关于git的使用上深究的话是有很多疑惑点的,所以写篇文章记录下。
概述
如下图,是常用的git工作策略,网上基本都在说这一套的了。
主要的概念就是,有feature的时候就在develop上拉一条独立branch出来做,一条branch对应一个feature,做完以后在merge/rebase进去develop,要发布版本的时候在从develop里面抽出来到release branches ( 这部分有的团队不一样,他们会先把develop稳定的版本抽到master然后发布的时候是从master中拉取 )。
整体概念是很简单的,也有很多辅助工具去帮忙实现这个策略。但是带新人的时候他们总会遇到类似的问题,主要是GIT用得不熟悉。
开始实践
正常flow
1) master新增一个初始文件1.txt,然后push到remote
2) 成功push以后,新增branch -> develop
git checkout -b develop
当前的分支状态就是一个小点点,为了看得更清楚些,会在develop进行一次推进:增加一个2.txt文件,并在1.txt文件中增加一行内容。
3) 新增feature
现在要开发一个新的需求,我们先基于develop拉一条branch
git checkout -b feature/1
然后在1.txt 随便加点东西,目前 1.txt的内容如下:
master - Hello World
develop - My Baby
feature/1 - Test
commit
4) 新增第二条feature
为了模仿协同开发,我们基于develop分支重新拉一份源码,然后新增第二条branch: feature/2。同样修改一下 1.txt :
master - Hello World
develop - My Baby
feature/2 - Test2
因为两条feature都是基于develop,并且都没有push,所以feature2看不到feature1的内容
5) feature1,2都完成开发,各自commit和push以后
可以看到现在开始出现了分叉,这个时候我们需要在develop branch整理一个版本发布到测试服务器上测试了,分别把两条branch rebase到develop上。
5.1) 先rebase feature/1
疑惑点:谁rebase谁?
这个是带新人的时候常被问到的问题,我们的原则是用分支较后的rebase到较前的分支上,可以看到我们的develop是在feature/1后面的,所以是在develop的分支上然后对feature/2进行rebase。
develop成功走到feature/1的节点上了,没有冲突,然后要rebase feature/2 ,同样是在develop上去rebase feature/2。可以预料的是,因为两个feature都改了同一个文件,所以必然会有冲突要处理。
master - Hello World
develop - My Baby
<<<<<<< HEAD
feature/2 - Test2
=======
feature/1 - Test
>>>>>>> feature/1 done
把1.txt修改成如下:
master - Hello World
develop - My Baby
feature/2 - Test2
feature/1 - Test
然后add一下1.txt,用git status查看一下当前状态:
mac002:gittest sevens$ git status
rebase in progress; onto 87e2b10
You are currently rebasing branch 'develop' on '87e2b10'.
(all conflicts fixed: run "git rebase --continue")
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: 1.txt
文件修改好了,再用下面命令继续rebase:
mac002:gittest chensh$ git rebase --continue
Applying: feature/1 done
成功合并两条feature分支
如上图,蓝色是我们的develop分支,可以看到feature/1和feature/2的代码都已经成功合并到develop分支上,然后push到remote就可以了。
疑问点:为什么图上feature/1的分支感觉没有合到develop上?
其实这就是rebase和merge的分别,我们可以回到feature/1,来对develop进行一次merge看看效果:
同样会有冲突要处理,解决完冲突以后,commit一下,得到如下分支图:
合并之后feature/1是在develop的之前。
所以我们可以看到rebase和merge的区别,rebase是把分支的内容合并到目标分支上,而本身的分支是不会合并到目标分支上的,因此rebase了以后,我们是可以直接把分支delete掉的。而merge就是把整个分支合并到目标分支身上。
6) 发布测试版本
这个时候,为了更清晰,我们可以在当前节点上增加一个tag来纪录当前的版本:
就可以提取出来上测试服了
7) 发布生产版本
回到我们的gitflow图上,我们要需要一条branch 叫release,由于是第一个版本,所以直接基于当前develop节点新增分支就行。