➜ erp git:(master) ✗ git branch
* master
git branch
列出本地仓库所有的分支,并在当前分支(也就是HEAD指针指向的分支)前面打*号。当前我的本地仓库只有一个master主分支。
之前讲过git checkout
可以使暂存区的内容覆盖工作目录,使工作目录的更改discard掉。git checkout
还有一个用途是切换branch。
创建新的名为dev
的branch:
➜ erp git:(master) ✗ git branch dev
➜ erp git:(master) ✗ git branch
dev
* master
切换到新创建的dev
branch上:
➜ erp git:(master) git checkout dev
Switched to branch 'dev'
➜ erp git:(dev) git branch
* dev
master
以上两个步骤可以合并为下面一个命令,表示创建并切换:
➜ erp git:(dev) git checkout -b test
Switched to a new branch 'test'
➜ erp git:(test) git branch
dev
master
* test
可以看到已经切换到dev branch,HEAD指针指向dev branch。
什么时候要使用branch呢,比如已经发布了稳定的release版本,那么可以从这个稳定的版本上创建一个dev分支出来,后续的开发就可以在这个dev分支上进行,不会影响已发布版本的正常使用,dev上的功能开发到一定阶段,可以基于dev创建一个test的分支,测试人员在test分支上测试已完成的功能,开发人员继续在dev分支上开发。
删除刚刚创建的test分支:
➜ erp git:(test) git branch -d test
error: Cannot delete the branch 'test' which you are currently on.
因为当前分支是test,所以无法删除,只能先切换到其他分支才能把test分支删除掉:
➜ erp git:(test) git checkout dev
Switched to branch 'dev'
➜ erp git:(dev) git branch -d test
Deleted branch test (was e998425).
➜ erp git:(dev) git branch
* dev
master
dev分支是基于master创建的,之后dev分支又进行了2次提交,commit id分别是2c451和d9472,而master分支没有变动,还是停留在6d782的提交,这时若要合并两分支,这种情况是最简单的,直接将master指针指向d9472,令master分支和dev分支指向相同,即可完成两分支合并。
➜ erp git:(master) git merge dev
Updating d095d23..4387e6e
Fast-forward
global.properties | 1 +
1 file changed, 1 insertion(+)
create mode 100644 global.properties
git merge dev
表示将dev分支并入当前分支,当前分支是master,合并时出现了fast-forward的提示,由于当前master分支是dev分支的直接上游,git只需把master分支的指针直接右移,也就是说,如果顺着一个分支走下去可以到达另外一个分支的话,那么git在合并两者时只需简单地把指针右移,因为这种情况没有任何的冲突,因此称为Fast-forward快进。
执行➜ erp git:(master) git log --pretty=oneline
:
4387e6ea61a983938e6486979f9861f33352c5cc commit global properties file on dev branch
执行➜ erp git:(master) git reflog
:
4387e6e HEAD@{0}: merge dev: Fast-forward
d095d23 HEAD@{1}: checkout: moving from dev to master
4387e6e HEAD@{2}: commit: commit global properties file on dev branch
d095d23 HEAD@{3}: checkout: moving from master to dev
可以看出,在整个Fast-forward合并过程中,只有一次commit提交的操作,merge完成之后的图示如下:
------------我是萌萌哒的分割线------------
在上面这种情况下,两个分支都有各自的推进,没有哪个分支是另一分支的直接祖先,这种情况就不能简单地指针右移,在合并时,git会自动识别出最佳的同源合并点,分支交叉点即为同源合并点。图中绿框代表的6d782即为同源合并点,粉框代表的75c41和d9472分别是master和dev的分支末端,git会为上述三者进行合并处理。
➜ erp git:(master) git merge dev
Auto-merging global.properties
CONFLICT (content): Merge conflict in global.properties
Automatic merge failed; fix conflicts and then commit the result.
执行git merge dev
之后,显示自动merge失败,有冲突出现,需要我们手动解决。我打开冲突的global.properties文件:
<<<<<<< HEAD
global config on master
=======
global config on dev
>>>>>>> dev
=======
是分隔符,介于<<<<<<< HEAD
和分隔符之间的内容是在master分支提交的内容,介于分隔符和>>>>>>> dev
之间的内容是在dev分支提交的内容,我在同一地方同时做了修改,git无法确定我最终需要的内容是什么,因此无法为我自动合并,我手动改为如下内容:
global config on master and dev
提交手动修改后的global.properties文件:
➜ erp git:(master) ✗ git add global.properties
➜ erp git:(master) ✗ git commit -m "merge global properties file on master and dev"
[master c55ac10] merge global properties file on master and dev
到此,冲突解决完毕,合并完毕。
我们看一下这种情况下的日志记录:
执行➜ erp git:(master) git log --pretty=oneline
:
c55ac10ec007dfb60ca8f52a9e6ce43ac6562cc6 merge global properties file on master and dev
1e61561eb2f329e31758a1cfef058d62af0a7048 modify global properties on master
966cab3d19ac361c7924394f879a981e3e5b8483 modify global properties file on dev
执行➜ erp git:(master) git reflog
:
c55ac10 HEAD@{0}: commit (merge): merge global properties file on master and dev
1e61561 HEAD@{1}: commit: modify global properties on master
4387e6e HEAD@{2}: checkout: moving from dev to master
966cab3 HEAD@{3}: commit: modify global properties file on dev
4387e6e HEAD@{4}: checkout: moving from master to dev
除了分别在两个分支上修改global.properties文件的两次commit操作,合并的时候也进行了一次commit操作,merge完成之后的图示如下:
使用git log --graph --pretty=oneline --abbrev-commit
来查看提交的图示信息,注意只显示提交操作,--abbrev-commit
显示缩略的commit id,只有7位,如果不用--abbrev-commit
的话,就会显示40位长度的commit id。
➜ erp git:(master) git log --graph --pretty=oneline --abbrev-commit
* c55ac10 merge global properties file on master and dev
|\
| * 966cab3 modify global properties file on dev
* | 1e61561 modify global properties on master
|/
* 4387e6e commit global properties file on dev branch
这样看得更直观。