Git常用命令总结

来源:互联网 发布:minecraftpe凡家物语js 编辑:程序博客网 时间:2024/06/14 23:11

Git学习笔记

标签(空格分隔): git


声明:以下为本人在工作中用git进行代码管理的笔记,按命令进行总结,仅供参考。
文章链接:https://www.zybuluo.com/guhuizaifeiyang/note/605443


  • Git学习笔记
    • 在Linux上安装Git
      • 创建版本库
    • commit提交
      • git add
      • git commit
    • git status
    • git diff
    • 版本回退git checkoutgit reset
    • 文件追溯git blame
    • git log
    • 使用分支
    • 设置Git别名
    • Patch
    • 修改提交log信息
    • git stash
    • git tag
    • cherry-pick
    • git checkout
    • git revert
    • git clean
    • git rebase
    • repo forall

在Linux上安装Git

首先,输入git,看系统有没有安装Git。如果没有安装,输入sudo apt-get install git即可完成Git的安装。

创建版本库

  • 创建一个空目录:
$ mkdir learngit$ cd learngit$ pwd/Users/michael/learngit
  • 配置身份:
git config --global user.name=git config --global user.email=
  • 初始化Git仓库:
$ git initInitialized empty Git repository in /Users/michael/learngit/.git/

如果Git的版本是1.6.5以上,可以在git init命令的后面直接输入目录名称:

$ git init learngitgit config --global –editOpen the global configuration file in a text editor for manual editing.
  • 删除版本库
    在创建仓库的目录下找到隐藏的.git文件夹,删除该文件夹即可。

commit提交

git add

git add是进行git代码管理的第一步,是用来保存修改过的代码的。git常用的有三条git add命令,分别是git add . 、 git add -u 、git add -A

  • git add
    我通常是通过git add <path>的形式把我们添加到索引库中,可以是文件也可以是目录。
    .表示当前目录。
  • git add -u
    git add -u [<path>]: 把<path>中所有tracked文件中被修改过或已删除文件的信息添加到索引库。它不会处理untracted的文件。
    .表示当前目录。
  • git add -A
    git add -A []表示把中所有tracked文件中被修改过或已删除文件和所有untracted的文件信息添加到索引库。
    .表示当前目录。

总结:
1. git add -A 保存所有的修改
2. git add . 保存新的添加和修改,但是不包括删除
3. git add -u 保存修改和删除,但是不包括新建文件。

git commit

  • git commit -m <说明>
  • git commit --amend -m <说明>
    修改最后一次提交的信息

git status

查看仓库的状态

git diff

如果git status告诉你有文件被修改过,用git diff可以查看修改内容。

  • git diff
    比较工作区(working directory)和暂存区(stage)快照之间的差异,也就是修改之后还没有暂存起来的变化内容
  • git diff –cached或者git diff –staged
    比较已经暂存区(stage)的文件和上次提交(commited)时的快照之间的差异
  • git diff branch_name
    查看当前工作目录与另一个分支branch_name的区别
  • git diff commit_id
    比较工作区(working directory)commit_id之间的差异
  • git diff – file
    查看文件file修改的内容

版本回退(git checkout/git reset)

  • HEAD指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使用命令git reset –hard commit_id。其中HEAD、HEAD^、HEAD^^分别表示最新版本、上一个版本、上上个版本的commit_id。
  • 穿梭前,用git log可以查看提交历史,以便确定要回退到哪个版本。git log –stat可以查看提交详细历史。
  • 要重返未来,用git reflog查看命令历史,以便确定要回到未来的哪个版本。

    git版本回退
    总结:
    版本回退有以下几种方式:

  • git reset
    此为默认方式,回退commit和stage信息。即暂存区将回退,但工作不会回退.
  • git reset –soft
    回退了commit的信息,暂存区和工作区都不会回退。
  • git reset –hard
    彻底回退到某个版本,即暂存区和工作区都会回退.
  • git checkout
    丢弃工作区的修改,回退到暂存区。
  • git checkout commit_id
    丢弃工作区的修改,回退到commit_id。

    文件追溯(git blame)

    当针对某个文件执行git blame时,就会逐行显示文件,在文件的每一行的行首显示此行最早是在什么版本,由谁引入的。

    git log

  • git log
    Display the entire commit history using the default formatting.

  • git log -n <limit>
    Limit the number of commits by <limit>. For example, git log -n 3 will display only 3 commits.

  • git log --oneline
    Condense each commit to a single line.

  • git log --stat
    Along with the ordinary git log information, include which files were altered and the relative number of lines that were added or deleted from each of them.

  • git log -p
    Display the patch representing each commit. This shows the full diff of each commit, which is the most detailed view you can have of your project history.

  • git log --author='<pattern>'
    Search for commits by a particular author. The argument can be a plain string or a regular expression.

  • git log --grep='<pattern>'
    Search for commits with a commit message that matches , which can be a plain string or a regular expression.

  • git log <since>..<until>
    Show only commits that occur between (<since> and <until>]. Both arguments can be either a commit ID, a branch name, HEAD, or any other kind of revision reference.

  • git log <file>
    Only display commits that include the specified file.

  • git log --graph --decorate --oneline
    A few useful options to consider. The —graph flag that will draw a text based graph of the commits on the left hand side of the commit messages. —decorate adds the names of branches or tags of the commits that are shown. —oneline shows the commit information on a single line making it easier to browse through commits at-a-glance.

  • git log --pretty=format
    定制要显示的记录格式,这样的输出便于后期编程提取分析。

下表列出了常用的格式占位符写法及其代表的意义。

选项 说明 %H 提交对象(commit)的完整哈希字串 %h 提交对象的简短哈希字串 %T 树对象(tree)的完整哈希字串 %t 树对象的简短哈希字串 %P 父对象(parent)的完整哈希字串 %p 父对象的简短哈希字串 %an 作者(author)的名字 %ae 作者的电子邮件地址 %ad 作者修订日期(可以用 -date= 选项定制格式) %ar 作者修订日期,按多久以前的方式显示 %cn 提交者(committer)的名字 %ce 提交者的电子邮件地址 %cd 提交日期 %cr 提交日期,按多久以前的方式显示 %s 提交说明

使用分支

  • 查看分支:git branch
  • 查看远程分支:git branch -r
  • 查看所有分支:git branch -a
  • 创建分支:git branch name
  • 切换分支:git checkout name
  • 创建+切换分支:git checkout -b name
  • 从远程分支创建分支:git checkout –b name origin/name
  • 重命名分支:git branch -m
  • 删除分支:git branch -d name
  • 合并某分支到当前分支:git merge name
  • 合并时发生冲突,不使用fast-forward模式:git merge –no-ff –m ‘commit message’ name。合并分支支时,加上–no-ff参数就可以用用普通模式合并,合并后的历史有分支支能看出来曾经做过合并,而而fast forward合并就看不出来曾经做过合并。

设置Git别名

将commit用ci代替:
$ sudo git config –system alias.ci commit
可在/etc/gitconfig文件中查看

Patch

可以根据一个diff文件进行版本更新。
三种种简单的patch方案:
一、 用git diff生成的标准patch。
git diff master>patch
git apply patch
二、 git format-patch生成的git专用patch。
1 使用git format-patch生成所需要的patch:

  • 当前分支所有超前master的提交:
    git format-patch -M master
  • 某次提交以后的所有patch:
    git format-patch 4e16
    4e16指的是commit名,不包括4e16。
  • 从根到指定提交的所有patch:
    git format-patch –root 4e16
    包括4e16
  • 某两次提交之间的所有patch:
    git format-patch 365a..4e16
    (365a和4e16 ]分别对应两次提交的名称
  • 某次提交(含)之前的几次提交:
    git format-patch –n commit_id
    -n指patch数,commit_id
    单次提交即为:git format-patch -1 commit_id

git format-patch生成的补丁文件默认从1开始顺序编号,并使用对应提交信息中的第一行作为文件名。如果使用了– numbered-files选项,则文件名只有编号,不包含提交信息;如果指定了–stdout选项,可指定输出位置,如当所有patch输出到一个文件;可指定-o <dir>指定patch的存放目录;

2 应用patch:
先检查patch文件:git apply –stat newpatch.patch
检查能否应用成功:git apply –check newpatch.patch
打补丁:git am newpatch.patch

3 解决冲突:

  • 强制打补丁
    git apply --reject PATCH

  • 手动解决代码冲突(检视生成的 .rej 文件,与冲突文件比较,修改冲突内容,或者使用git mergetool进行修改,并最终把文件加入到index中)

$ git add FIXED_FILES$ git add 其他 apply 进来的文件$ git am --resolved

三、 Linux patch
单个文件
diff –uN from-file to-file >to-file.patch
patch –p1 < to-file.patch

多个文件
diff –uNr from-docu to-docu >to-docu.patch
patch –p1 < to-docu.patch

-u 显示有差异行的前后几行(上下文), 默认是前后各3行。
-r 递归地对比一个目录和它的所有子目录(即整个目录树)。
-N 如果某个文件缺少了, 就当作是空文件来对比
-p1 忽略补丁中的路径的第一级目录
Example:
to-docu.patch:

diff -uNr old/Camera2/src/com/android/camera/app/AppController.java new/Camera2/src/com/android/camera/app/AppController.java--- old/Camera2/src/com/android/camera/app/AppController.java   2016-10-12 17:23:22.000000000 +0800+++ new/Camera2/src/com/android/camera/app/AppController.java   2016-10-10 16:07:24.000000000 +0800@@ -425,7 +425,9 @@      * Finishes the activity since the intent got canceled.      */     public void finishActivityWithIntentCanceled();-    +     public ShutterButton.OnShutterButtonListener getPhotoShutterListener();     public ShutterButton.OnShutterButtonListener getVideoShutterListener();++    public int getCameraId(); }

步骤:
1、进入到Camera2目录
2、命令:patch -p2 < to-docu.patch
因为patch中diff的对比路径为old/Camera2/和new/Camera2/,而当前目录为/Camera2/,所以用-p2忽略补丁中的路径的前两级目录,

修改提交log信息

git commit --amend -m <message>可以修改最后一次提交的信息。

对于历史提交,必须使用rebase。
git rebase –i HEAD~3
表示要修改当前版本的倒数第三次状态。执行这个命令后,会显示:
pick:*
pick:*
pick:*
如果你要修改哪个,就将那行的pick改成edit,然后保存退出。然后再使用:
git commit –amend来对commit进行修改。
修改完成之后,使用git rebase –continue。

git stash

当在一个分支的开发工作未完成,却又要切换到另外一个分支进行开发的时候,除了commit原分支的代码改动的方法外,我觉得git stash是一个更加便捷的选择。
步骤如下:
一、添加改动到stash。在原分支 git stash save -a “messeag”,执行完该命令后,工作区会恢复到最近一次提交,所以一定要将当前更改提交或者保存到stash。
二、恢复改动。如果你要恢复的是最近的一次改动,git stash pop即可,我用这个用的最多。如果有多次stash操作,那就通过git stash list查看stash列表,从中选择你想要pop的stash,运行命令git stash pop stash@{id}或者 git stash apply stash@{id}即可。
三、删除stash。git stash drop stash@{id} 如果不加stash编号,默认的就是删除最新的,也就是编号为0的那个,加编号就是删除指定编号的stash。git stash clear 是清除所有stash,整个世界一下子清净了!
四、git stash pop与 git stash apply stash@{id}的区别。
git stash pop stash@{id}命令会在执行后将对应的stash id 从stash list里删除,而 git stash apply stash@{id} 命令则会继续保存stash id。

git tag

  • 创建tag
    git tag v1.0 [commit_id]
  • 查看tag
    git tag
  • 查看标签信息
    git show v0.9
  • 创建带有说明的标签
    git tag -a v0.1 -m “version 0.1 released” 3628164
  • 删除标签
    git tag -d v0.1
  • 推送某个标签到远程
    git push origin v1.0
  • 一次性推送全部尚未推送到远程的本地标签
    git push origin –tags
  • 如果标签已经推送到远程,要删除远程标签
    git tag -d v0.9
    git push origin :refs/tags/v0.9

cherry-pick

如果某个特性分支上有多个commits,但你只想引入其中之一就可以使用这种方法。

git cherry-pick <commit id>git cherry-pick -x <commit id>:保留原提交者信息。git cherry-pick <start-commit-id>..<end-commit-id>:表示把<start-commit-id><end-commit-id>之间(左开右闭,不包含start-commit-id)的提交cherry-pick到当前分支;git cherry-pick -n <commit id>:This flag applies the changes necessary to cherry-pick each named commit to your working tree and the index, without making any commit. 

git checkout

The git checkout command serves three distinct functions: checking out files, checking out commits, and checking out branches.

  • git checkout master
    Return to the master branch.
  • git checkout <commit> <file>
    Check out a previous version of a file. This turns the that resides in the working directory into an exact copy of the one from and adds it to the staging area.
  • git checkout <commit>
    Update all files in the working directory to match the specified commit. You can use either a commit hash or a tag as the <commit>argument. This will put you in a detached HEAD state.
  • git checkout - -ours // 抛弃remote的版本,保留本地的

  • git checkout - -theirs // 抛弃本地的版本,完全采用remote的

git revert

git revert 是撤销某次操作,此次操作之前的commit都会被保留,并且生成一个新的commit。

git clean

* git clean -nPerform a “dry run” of git clean. This will show you which files are going to be removed without actually doing it.* git clean -fRemove untracked files from the current directory. This will not remove untracked folders or files specified by .gitignore.* git clean -f <path>Remove untracked files, but limit the operation to the specified path.* git clean -dfRemove untracked files and untracked directories from the current directory.* git clean -xfRemove untracked files from the current directory as well as any files that Git usually ignores.

git rebase

git rebase,顾名思义,就是重新定义(re)起点(base)的作用,即重新定义分支的版本库状态。要搞清楚这个东西,要先看看版本库状态切换的两种情况:
1. 我们知道,在某个分支上,我们可以通过git reset,实现将当前分支切换到本分支以前的任何一个版本状态,即所谓的“回溯”。即实现了本分支的“后悔药”。也即版本控制系统的初衷。
2. 还有另一种情况,当我们的项目有多个分支的时候。我们除了在本地开发的时候可能会“回溯”外,也常常会将和自己并行开发的别人的分支修改添加到自 己本地来。这种情况下很常见。作为项目管理员,肯定会不断的合并各个子项目的补丁,并将最新版本推送到公共版本库,而作为开发人员之一,提交自己的补丁之 后,往往需要将自己的工作更新到最新的版本库,也就是说把别的分支的工作包含进来。

举个例子来说吧!假设我们的项目初期只有一个master分支,然后分支上作过两次提交。这个时候系统只有一个master分支,他的分支历史如下:
此处输入图片的描述

这个时候,我们可以通过git reset将master分支(工作目录、工作缓存或者是版本库)切换到master1或者master0版本,这就是前面所说的第一种情况。

假设我们这里把master分支通过git reset回溯到了master1状态。那么这个时候系统仍然只有一个master分支,分支的历史如下:
此处输入图片的描述

然后,我们在这里以master1为起点,创建了另一个分支test。那么对于test分支来说,他的第一个版本test0就和master1是同一个版本,此时项目的分支历史如下:
此处输入图片的描述

  1. 这个时候,通过第一种git reset的方式,可以将master分支的当前状态(master3)回溯到master分支的master0、master1、master2状态。 也可以将test分支当前状态(test2)回溯到test分支的test0、test1状态,以及test分支的父分支master的master0、 master1状态。
  2. 那么。如果我要让test分支从test0到test2之间所有的改变都添加到master分支来,使得master分支包含test分支的所有修改。这个时候就要用到git rebase了。

首先,我们切换到master分支,然后运行下面的命令,即可实现我们的要求:

git rebase test

这个时候,git做了些什么呢?
1. 先将test分支的代码checkout出来,作为工作目录
2. 然后将master分支从test分支创建起的所有改变的补丁,依次打上。如果打补丁的过程没问题,rebase就搞定了
3. 如果打补丁的时候出现了问题,就会提示你处理冲突, 在解决完冲突后,用”git-add”命令去更新这些内容的索引(index), 然后,你无需执行 git-commit。处理好了,可以运行git rebase –continue继续直到完成
4. 如果你不想处理,你还是有两个选择,一个是放弃rebase过程(运行git rebase –abort),另一个是直接用test分支的取代当前分支的(git rebase –skip)。

此处输入图片的描述

当我们使用Git log来参看commit时,其commit的顺序也有所不同。
假设C3提交于9:00AM,C5提交于10:00AM,C4提交于11:00AM,C6提交于12:00AM,
对于使用git merge来合并所看到的commit的顺序(从新到旧)是:C7 ,C6,C4,C5,C3,C2,C1
对于使用git rebase来合并所看到的commit的顺序(从新到旧)是:C7 ,C6‘,C5’,C4,C3,C2,C1
因为C6’提交只是C6提交的克隆,C5’提交只是C5提交的克隆,
从用户的角度看使用git rebase来合并后所看到的commit的顺序(从新到旧)是:C7 ,C6,C5,C4,C3,C2,C1
另外,我们在使用git pull命令的时候,可以使用–rebase参数,即git pull –rebase,这里表示把你的本地当前分支里的每个提交(commit)取消掉,并且把它们临时 保存为补丁(patch)(这些补丁放到”.git/rebase”目录中),然后把本地当前分支更新 为最新的”origin”分支,最后把保存的这些补丁应用到本地当前分支上。

repo forall

  • repo forall -c
    这个命令会遍历所有的git仓库,并在每个仓库执行-c所指定的命令(这个被执行的命令就不限于仅仅是git命令了,而是任何被系统支持的命令,比如:ls 、 pwd 、cp 等等的 )
  • repo forall -p -c git branch
    //该命令会遍历所有仓库并打印每个仓库的分支情况,由于有了-p参数,这样便会打印出每个仓库的路径!!!

  • repo sync同步所有仓库后,怎么查看更新了哪些仓库?
    repo forall -p -c git log –since=”2016-3-15” –before=”2016-3-16”

  • git show
    查看修改纪录

  • git show commitId 查看某次修改纪录
  • git show commitId1 commitId2 查看[Id1 Id2]的修改纪录
0 0