0.引言
本文参考最后的几篇文章,将git的分支管理整理如下。学习git的分支管理将可以版本进行灵活有效的控制。
1.如何建立与合并分支
1.1分支的新建与合并指令
新建分支 newBranch,并进入新分支:
$ git checkout -b newBranch
相当于:
$ git branch newBranch
$ git checkout newBranch
合并分支 mergeBranch,例如要把mergeBranch,合并入master:
$ git checkout master $ git merge mergeBranch
合并后,master和mergeBranch都指向同一个版本,可以删除掉mergeBranch了:
$ git branch -d mergeBranch
1.2 分支创建与合并的实例
Task:
- 开发某项目。
- 为实现某个新的需求,创建一个分支iss53。
- 在这个分支上开展工作。
假设临时有个很严重的其他问题需要紧急修补,按照下面的方式处理:
- 返回master分支。
- 为这次紧急修补建立一个新分支hotfix,并在其中修复问题。
- 通过测试后,回到服务器所在的master分支,将修补分支合并进来,然后再推送到服务器上。
- 删除hotfix
- 切换到之前实现新需求的分支iss53,继续工作。
工作完成以后,将分支iss53合并入master
如果iss53与hotfix工作没有冲突,则合并成功,如果有冲突则需要再进行处理判断后,再合并。
Do:
1、假设当前,master更新为C2版本:
2、为实现某功能创建iss53分支,创建index.html,并上传
这个时候,状态是这样的:
3、紧急任务来了,要先返回master分支
4、现在接到进行紧急修改的要求,然后创建hotfix
5、进行了相应的开发,包括修改index.html(注意,在iss53中也进行了修改)
然后git push origin hotfix。
Git 会把工作目录的内容恢复为检出某分支时它所指向的那个提交对象的快照。它会自动添加、删除和修改文件以确保目录的内容和你当时提交时完全一样。
于是当前的状态是:
6、当分支hotfix的内容测试通过确认后,就可以合并到master中,并删除hotfix
如果顺着一个分支走下去可以到达另一个分支的话,那么 Git 在合并两者时,只会简单地把指针右移,因为这种单线的历史分支不存在任何需要解决的分歧,所以这种合并过程可以称为快进(Fast forward)。
现在最新的修改已经合并到master分支了。可以发布啦。
接下来删除hotfix
7、现在我们回到iss35继续工作
我们继续推进iss35:
8、现在接下来要合并master和iss53
合并后,删除iss53分支,即可。
请注意,这次合并操作的底层实现,并不同于之前 hotfix
的并入方式。因为这次你的开发历史是从更早的地方开始分叉的。由于当前 master
分支所指向的提交对象(C4)并不是 iss53
分支的直接祖先,Git 不得不进行一些额外处理。就此例而言,Git 会用两个分支的末端(C4 和 C5)以及它们的共同祖先(C2)进行一次简单的三方合并计算。
这次,Git 没有简单地把分支指针右移,而是对三方合并后的结果重新做一个新的快照,并自动创建一个指向它的提交对象(C6)(见图 3-17)。这个提交对象比较特殊,它有两个祖先(C4 和 C5)。
值得一提的是 Git 可以自己裁决哪个共同祖先才是最佳合并基础;这和 CVS 或 Subversion(1.5 以后的版本)不同,它们需要开发者手工指定合并基础。所以此特性让 Git 的合并操作比其他系统都要简单不少。
9、但是如果在不同的分支中都修改了同一个文件的同一部分,Git 就无法干净地把两者合到一起(译注:逻辑上说,这种问题只能由人来裁决。)。如果你在解决问题 #53 的过程中修改了 hotfix
中修改的部分,则会出现:
我们先看一下状态:
接下来我们可以打开 index.html
git 已经自动对其做了区分,HEAD表示master分支的内容,=====下面的是iss53分支做的修改
你可以对其再做调整和修改。
再用git add index.html,git commit表示他们已经解决冲突。
然后再融合和删除iss53分支。完成工作。
也可以使用mergetool:
2. Git分支在实际项目中的灵活运用
这是Git版本控制的分支管理总体图:
其中最重要的是主分支:
- master:用来版本发布,主要反映当前线上运行的代码。
- develop:作为开发分支,用来存放最新开发的代码,有时候会叫它“集成分支”。
develop分支用来存放开发完成的代码,当develop分支上的代码测试没有问题后,merge到master分支上,并发布。
辅助分支:
- feature branches
feature分支也可以叫做主题分支。例如在新版中要开发的新功能,可以用feature来存放。名字可以另外取,例如要增加insert和search功能,可以增加insertFeature和searcheFeature的分支,开发好后,再分别merge到develop分支中。
从 develop 分支建一个 feature 分支,并切换到 feature 分支
$ git checkout -b myfeature develop Switched to a new branch "myfeature"
合并feature 分支到 develop
$ git checkout develop Switched to branch 'develop' $ git merge --no-ff myfeature Updating ea1b82a..05e9557 (Summary of changes) $ git branch -d myfeature Deleted branch myfeature (was 05e9557). $ git push origin develop
其中--no-ff 的参数,ff表示fastforward,--no--ff,就表示会对历史的分支做一个新的提交对象。加参数和不加参数的区别如下:(可以使用 sourceTree 或者命令git log --graph
查看)
- release branches
这个分支可以是来自develop;必须合并到develop和master。release分支可以理解为更多的是作为版本控制、缺陷镜像修复和最后发布前的复查工作。
创建一个realase分支
$ git checkout -b release-1.2 develop Switched to a new branch "release-1.2" $ ./bump-version.sh 1.2 Files modified successfully, version bumped to 1.2. $ git commit -a -m "Bumped version number to 1.2" [release-1.2 74d9424] Bumped version number to 1.2 1 files changed, 1 insertions(+), 1 deletions(-)
这里的bump-version.sh ,只是一个虚拟的脚本,是要求读者自己去编写这样的脚本,实现相应的地方都统一更改版本号。
完成release分支:
$ git checkout master Switched to branch 'master' $ git merge --no-ff release-1.2 Merge made by recursive. (Summary of changes) $ git tag -a 1.2
融合到develop分支
$ git checkout develop Switched to branch 'develop' $ git merge --no-ff release-1.2 Merge made by recursive. (Summary of changes)
删除release分支
$ git branch -d release-1.2 Deleted branch release-1.2 (was ff452fe).
- hotfix branches
这个是一个需要紧急修复bug的分支。当线上产品有bug,我们可以开一个hotfix分支,修复完bug后,再merge,删除。
它来自master,融合向develop和master。
关系如下:
具体代码如下:
创建hotfix分支:
$ git checkout -b hotfix-1.2.1 master Switched to a new branch "hotfix-1.2.1" $ ./bump-version.sh 1.2.1 Files modified successfully, version bumped to 1.2.1. $ git commit -a -m "Bumped version number to 1.2.1" [hotfix-1.2.1 41e61bb] Bumped version number to 1.2.1 1 files changed, 1 insertions(+), 1 deletions(-)
$ git commit -m "Fixed severe production problem" [hotfix-1.2.1 abbe5d6] Fixed severe production problem 5 files changed, 32 insertions(+), 17 deletions(-)
完成了hotfix分支:
$ git checkout master Switched to branch 'master' $ git merge --no-ff hotfix-1.2.1 Merge made by recursive. (Summary of changes) $ git tag -a 1.2.1
合并到develop分支
$ git checkout develop Switched to branch 'develop' $ git merge --no-ff hotfix-1.2.1 Merge made by recursive. (Summary of changes)
最后删除hotfix分支
$ git branch -d hotfix-1.2.1 Deleted branch hotfix-1.2.1 (was abbe5d6).
参考:
【1】 http://nvie.com/posts/a-successful-git-branching-model/
【2】http://blog.jobbole.com/109466/
【3】https://git-scm.com/book/zh/v1/Git-%E5%88%86%E6%94%AF-%E5%88%86%E6%94%AF%E7%9A%84%E6%96%B0%E5%BB%BA%E4%B8%8E%E5%90%88%E5%B9%B6