版本库中的分支,就像科幻小说中的平行宇宙,再加上时光穿梭机一般的版本前进、回退功能,程序员在版本库上就像上帝一样的存在:想去哪儿就去哪儿(不同版本的切换),想在哪个宇宙发呆就在哪个宇宙(分支切换)发呆。
起初,程序员创造版本库。
分支是空虚混沌。版本黑暗。程序员的HEAD指在master上。
程序员说,要有分支,就有了分支。
程序员看分支是好的,就把分支合并了 。
分支在实际中有什么用呢?假设你准备开发一个新功能,但是需要两周才能完成,第一周你写了50%的代码,如果立刻提交,由于代码还没写完,不完整的代码库会导致别人不能干活了。如果等代码全部写完再一次提交,又存在丢失每天进度的巨大风险。
现在有了分支,就不用怕了。你创建了一个属于你自己的分支,别人看不到,还继续在原来的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上,这样,既安全,又不影响别人工作。
妈妈再也不用担心我的代码丢失了。--Git版本管理系统
当我们在版本库中工作时,每次提交,Git都把它们串成一条时间线,这条时间线就是一个分支。默认情况下,只有一条时间线,在Git里,这个分支叫主分支,即master
分支。HEAD
严格来说不是指向提交,而是指向master
,master
才是指向提交的,所以,HEAD
指向的就是当前分支。
每次提交,master分支都会向前移动一步,这样,随着版本不断提交,master分支的线也越来越长。
当我们创建新的分支,例如dev
时,Git新建了一个指针叫dev
,指向master
相同的提交,再把HEAD
指向dev
,就表示当前分支在dev
上。
从现在开始,对工作区的修改和提交就是针对dev
分支了,比如新提交一次后,dev
指针往前移动一步,而master
指针不变。
假如我们在dev
上的工作完成了,就可以把dev
合并到master
上。Git怎么合并呢?最简单的方法,就是直接把master
指向dev
的当前提交,就完成了合并。
合并完分支后,根据需要可以删除dev
分支。删除dev
分支就是把dev
指针给删掉,删掉后,我们就剩下了一条master
分支。
创建分支
执行git checkout -b dev
命令,创建dev分支。
在dev分支上进行修改提交。
由于git版本库在本地,再加上其优秀的设计(指针),创建分支和切换分支非常快速,所以你一定会爱上“创建分支、在上面开发、合并分支、删除分支”这种开发方式的。与SVN相比较,Git实在是方便太多,而且,并不会和服务器进行交互。
合并分支
随着日常工作的推进,我们在不同的分支上进行工作,当一个阶段的工作完成后,就需要把工作成果合并到指定的分支(很有可能是master)上。
首先,我们把dev
分支上的修改合并到master
,再把fix_bug1762
分支合并到master
,以接收两个开发人员的工作。
在当前分支(如master)上执行git merge dev
,把dev分支合并到master,注意提示信息中说有冲突。
解决冲突后提交,合并dev分支工作内容就完成了。
同样,再次执行git merge fix_bug1762
命令,把分支fix_bug1762合并到master上。
同样提示信息标识HelloGit.java文件在合并过程中出现了冲突,需要人工介入。
解决冲突后再次提交,合并fix_bug1762分支的工作也完成了。这样,master上就接收了dev和fix_bug1762两个分支的修改。
当然,我们通过版本库管理的、需要解决冲突的,都是文本文件。如果你不嫌麻烦,使用vi、记事本等工具都可以解决冲突。但是,在日常开发过程中,总有合适的合并、解决冲突的工具供你使用,例如Eclipse中的EGit。
删除分支
是时候和分支说再见了。
当我们合并完分支的修改后,根据需要,就可以删除分支了。
请注意branch和tag的区分,tag是阶段性的工作,需要保留的,如v5.25.RELEASE。而branch通常都是临时性的工作,完成修改、合并后,一般需要丢弃。
执行git branch -d dev
命令,删除dev分支。
执行git branch -d fix_bug1762
命令,删除fix_bug1762分支。
这些操作,都是在本地库上进行的。根据需要,你可随时推送到远端库,把你的工作成果分享给小伙伴们。