「小技巧」使用Git从其他分支merge个别文件
小明发现在实际项目开发过程中,总会遇到各种各样的情况,比如一个大型的项目或版本迭代可能不是一次上线,可能会分好几次上线,这时候就会涉及创建多个分支,分别开发。
项目背景
产品经理:我们本次开发三个功能,列表页功能、详情页功能、系统消息功能,分两次上线,先上列表功能,再上详情页和系统消息。
小明:好的吧。
紧接着,小明就将本次需求分为2个分支,分别为a、b。
- a:开发列表页功能
- b:开发详情页功能、系统消息功能
原计划:产品经理说先上列表功能,那小明就先开发a分支,列表功能很快开发完成(厉害吧)。
计划有变:风云变幻,第二天小明按照计划开发b分支,开发到一半,产品经理突然说目前的系统消息功能(位于b分支)比较紧急,需要和列表功能(位于a分支)一起上线,当时小明就懵逼了。赶紧暂停开发详情页(位于b分支,虽然已经开发了一部分),转战系统消息功能的开发。当系统消息功能开发完成之后,就需要考虑将系统消息功能(位于b分支)和列表功能(位于a分支)放在一个分支上提测(开发一部分的详情页功能暂先不需要合并)的问题,这时候分支合并就要派上用场了。
分支合并
说起分支合并,大家第一个想到的命令肯定是git merge
,因为这是分支合并的常用命令。
使用git merge
合并分支会将两个分支的所有内容进行比较合并,因此我们如果想合并两个分支中的一部分,显然直接使用这个命令是行不通的。
so what happens next ? 嘿嘿,有两种方案可供我们选择:
强制合并
从其他分支merge
指定文件到当前分支,git checkout
是个合适的工具。
语法如下:
git checkout source_branch <path>...
我们使用git checkout 将b分支上的系统消息功能添加到a分支上
$ git branch * a b $ git checkout b message.html message.css message.js other.js $ git status # on branch a # changes to be committed: # (use "git reset head <file>..." to unstage) # # new file: message.css # new file: message.html # new file: message.js # modified: other.js #
合并完成
但是……
注意:在使用git checkout某文件到当前分支时,会将当前分支的对应文件强行覆盖
因此,合并a分支上没有存在的文件没问题,但是如果合并a分支上原先就存在的文件(比如两个分支上都对other.js进行过修改),位于分支a上的文件other.js就会被checkout(分支b)过来的other.js覆盖,导致分支a上之前开发的列表功能付之东流,这样做肯定是优雅的!
那如何避免同一个文件不强制覆盖,有没有更好的解决方案呢(调一下味口)?我们一起来看一下第二种方案。
智能合并
思路:曲线救国,我们通过git merge 强大的分支合并功能来完成此次无缝合并。
- 首先使用
git checkout
根据a分支创建一个a_temp分支(避免影响a分支)
$ git checkout -b a_temp switched to a new branch 'a_temp'
- 然后将b分支合并到a_temp分支,此时两个都经修改过的文件会跑出冲突,我们只需解决冲突即可。
$ git merge b updating 1f73596..04627b5 fast-forward message.css | 0 message.html | 0 message.js | 0 other.js | 1 + 4 files changed, 1 insertion(+) create mode 100644 message.css create mode 100644 message.html create mode 100644 message.js
- 再次切换到a分支,并使用git checkout 将a_temp分支上的系统消息功能相关文件或文件夹覆盖到a分支,此时可以大胆的覆盖!因为我们已经在第二步处理过冲突问题。
$ git checkout a switched to branch 'a' $ git checkout a_temp message.html message.css message.js other.js $ git status # on branch a # changes to be committed: # (use "git reset head <file>..." to unstage) # # new file: message.css # new file: message.html # new file: message.js # modified: other.js #
-
最后,有强迫症的患者可以卸磨杀驴,把刚刚根据分支a创建的a_temp删除。
$ git branch -d a_temp
ok,到此分支合并就完结了,现在我们就可以自信地召唤产品经理(我们公司产品兼测试)测试这两个功能。
扩展
另外给大家介绍一下git merge
使用的小技巧
举例:要把master
分支合并到dev
分支
git checkout dev // 切换到dev分支 git merge master --no-ff // 使用--no-ff
默认使用merge
命令是ff
,即 fast-forward
,这种方式从git 合并历史中是无法查看到是哪几个提交对象在一起实现了一个功能。
而--no-ff
标记会在分支合并的时候,创建一个新的提交对象,可以避免丢失master
分支的历史信息,并且把所有的功能叠加在一起提交上去。两者的区别如下图所示,大家可以自己体验一下两者的区别。
以上就是小明工作中使用git合并总结的经验,希望能帮助到大家,仅供参考,有错误请指出,谢谢!
欢迎关注微信公众号”程序员小明”,获取更多资源。