分支在实际中的作用:假设你准备开发一个新功能,但是需要两周才能完成,第一周你写了50%的代码,如果立刻提交,由于代码还没写完,不完整的代码库会导致别人不能干活了。如果等代码全部写完再一次提交,又存在丢失每天进度的巨大风险。
现在有了分支,就不用担心了。你创建了一个属于你自己的分支,别人看不到,还继续在原来的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上,这样,既安全,又不影响别人工作。
一、创建与合并分支
第一步,创建dev
分支,然后切换到dev
分支:
➜ test-marketing-testcase git:(master) git checkout -b dev Switched to a new branch 'dev'
git checkout
命令加上-b
参数表示创建并切换,相当于以下两条命令:
$ git branch dev $ git checkout dev Switched to branch 'dev'
第二步,用git branch
命令查看当前分支:
➜ test-marketing-testcase git:(dev) git branch * dev master
git branch
命令会列出所有分支,当前分支前面会标一个*
号。
然后,我们就可以在dev
分支上正常提交,比如对readme.txt做个修改,加上一行:
Creating a new branch is quick.
第三步,然后提交:
➜ test-marketing-testcase git:(dev) ✗ git add readme.txt ➜ test-marketing-testcase git:(dev) ✗ git commit -m "branch test" [dev 1282e04] branch test 1 file changed, 1 insertion(+)
第四步,现在,dev
分支的工作完成,我们就可以切换回master
分支:
➜ test-marketing-testcase git:(dev) git checkout master Switched to branch 'master' Your branch is up-to-date with 'origin/master'.
切换回master
分支后,再查看一个readme.txt文件,刚才添加的内容不见了!因为那个提交是在dev
分支上,而master
分支此刻的提交点并没有变。
第五步,我们把dev
分支git merge
命令用于合并指定分支到当前分支。合并后,再查看readme.txt的内容,就可以看到,和dev
分支的最新提交是完全一样的。的工作成果合并到master
分支上:
➜ test-marketing-testcase git:(master) git merge dev Updating 00a130d..1282e04 Fast-forward readme.txt | 1 + 1 file changed, 1 insertion(+)
git merge
命令用于合并指定分支到当前分支。合并后,再查看readme.txt的内容,就可以看到,和dev
分支的最新提交是完全一样的。
注意到上面的Fast-forward
信息,Git告诉我们,这次合并是“快进模式”,也就是直接把master
指向dev
的当前提交,所以合并速度非常快。
当然,也不是每次合并都能Fast-forward
,我们后面会讲其他方式的合并。
第六步,合并完成后,就可以放心地删除dev
分支了:
➜ test-marketing-testcase git:(master) git branch -d dev
Deleted branch dev (was 1282e04).
删除后,查看branch
,就只剩下master
分支了:
➜ test-marketing-testcase git:(master) git branch
* master
因为创建、合并和删除分支非常快,所以Git鼓励使用分支完成某个任务,合并后再删掉分支,这和直接在master
分支上工作效果是一样的,但过程更安全。
小结
Git鼓励大量使用分支:
查看分支:git branch
创建分支:git branch <name>
切换分支:git checkout <name>
创建+切换分支:git checkout -b <name>
合并某分支到当前分支:git merge <name>
删除分支:git branch -d <name>
二、合并冲突
合并分支往往也不是顺利的,有时候会发生冲突。
第一步,准备新的feature1
分支,继续新分支开发:
➜ test-marketing-testcase git:(master) git checkout -b feature1 Switched to a new branch 'feature1'
第二步,修改readme.txt
最后一行,改为:
Creating a new branch is quick AND simple.
第三步,在feature1分支上提交:
➜ test-marketing-testcase git:(feature1) ✗ git add readme.txt ➜ test-marketing-testcase git:(feature1) ✗ git commit -m "AND simple" [feature1 7da2f6e] AND simple 1 file changed, 1 insertion(+), 1 deletion(-)
第四步,切换到master分支:
➜ test-marketing-testcase git:(feature1) git checkout master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
在master
分支上把readme.txt
文件的最后一行改为:
Creating a new branch is quick &&& simple.
第五步,提交:
➜ test-marketing-testcase git:(master) ✗ git add readme.txt ➜ test-marketing-testcase git:(master) ✗ git commit -m "&&& simple" [master 5bfff4d] &&& simple 1 file changed, 1 insertion(+), 1 deletion(-)
第六步,现在,master
分支和feature1
分支各自都分别有新的提交,这种情况下,Git无法执行“快速合并”,只能试图把各自的修改合并起来,但这种合并就可能会有冲突,我们试试看:
➜ test-marketing-testcase git:(master) git merge feature1 Auto-merging readme.txt CONFLICT (content): Merge conflict in readme.txt Automatic merge failed; fix conflicts and then commit the result.
果然冲突了!Git告诉我们,readme.txt
文件存在冲突,必须手动解决冲突后再提交。git status
也可以告诉我们冲突的文件:
➜ test-marketing-testcase git:(master) ✗ git status On branch master Your branch is ahead of 'origin/master' by 1 commit. (use "git push" to publish your local commits) You have unmerged paths. (fix conflicts and run "git commit") Unmerged paths: (use "git add <file>..." to mark resolution) both modified: readme.txt no changes added to commit (use "git add" and/or "git commit -a")
我们可以直接查看readme.txt的内容:
➜ test-marketing-testcase git:(master) ✗ cat readme.txt Git is a distributed version control system. Git is free software distributed under the GPL. Git has a mutable index called stage. Git tracks changes of files. <<<<<<< HEAD Creating a new branch is quick &&& simple. ======= Creating a new branch is quick AND simple . >>>>>>> feature1
Git用<<<<<<<
,=======
,>>>>>>>
标记出不同分支的内容。
第七步,我们修改readme.txt文件如下后保存:
Creating a new branch is quick and simple.
第八步,再提交:
➜ test-marketing-testcase git:(master) ✗ git add readme.txt ➜ test-marketing-testcase git:(master) ✗ git commit -m "conflict fixed" [master d688c0e] conflict fixed
用带参数的git log
也可以看到分支的合并情况:
➜ test-marketing-testcase git:(master) git log --graph --pretty=oneline --abbrev-commit
| | * 0993855 add simple * | 52c868b &&& simple |/ * 929ac6f test * 1ce101b &&& simple * 016886b AND simple * 5bfff4d &&& simple * 7da2f6e AND simple
最后,删除feature1分支:
➜ test-marketing-testcase git:(master) git branch -d feature1
Deleted branch feature1 (was 0993855).
小结
当Git无法自动合并分支时,就必须首先解决冲突。解决冲突后,再提交,合并完成。
解决冲突就是把Git合并失败的文件手动编辑为我们希望的内容,再提交。
用git log --graph
命令可以看到分支合并图。