• 使用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分支上

    1. $ git branch
    2. * A
    3. B
    4. $ git checkout B message.html message.css message.js other.js
    5. $ git status
    6. # On branch A
    7. # Changes to be committed:
    8. # (use "git reset HEAD ..." to unstage)
    9. #
    10. # new file: message.css
    11. # new file: message.html
    12. # new file: message.js
    13. # modified: other.js
    14. #

    合并完成

    但是……

    注意:在使用git checkout某文件到当前分支时,会将当前分支的对应文件强行覆盖

    因此,合并A分支上没有存在的文件没问题,但是如果合并A分支上原先就存在的文件(比如两个分支上都对other.js进行过修改),位于分支A上的文件other.js就会被checkout(分支B)过来的other.js覆盖,导致分支A上之前开发的列表功能付之东流,这样做肯定是优雅的!

    那如何避免同一个文件不强制覆盖,有没有更好的解决方案呢(调一下味口)?我们一起来看一下第二种方案。

    智能合并

    思路:曲线救国,我们通过git merge 强大的分支合并功能来完成此次无缝合并。

    1. 首先使用git checkout根据A分支创建一个A_temp分支(避免影响A分支)
    1. $ git checkout -b A_temp
    2. Switched to a new branch 'A_temp'
    1. 然后将B分支合并到A_temp分支,此时两个都经修改过的文件会跑出冲突,我们只需解决冲突即可。
    1. $ git merge B
    2. Updating 1f73596..04627b5
    3. Fast-forward
    4. message.css | 0
    5. message.html | 0
    6. message.js | 0
    7. other.js | 1 +
    8. 4 files changed, 1 insertion(+)
    9. create mode 100644 message.css
    10. create mode 100644 message.html
    11. create mode 100644 message.js
    1. 再次切换到A分支,并使用git checkout 将A_temp分支上的系统消息功能相关文件或文件夹覆盖到A分支,此时可以大胆的覆盖!因为我们已经在第二步处理过冲突问题。
    1. $ git checkout A
    2. Switched to branch 'A'
    3. $ git checkout A_temp message.html message.css message.js other.js
    4. $ git status
    5. # On branch A
    6. # Changes to be committed:
    7. # (use "git reset HEAD ..." to unstage)
    8. #
    9. # new file: message.css
    10. # new file: message.html
    11. # new file: message.js
    12. # modified: other.js
    13. #
    1. 最后,有强迫症的患者可以卸磨杀驴,把刚刚根据分支A创建的A_temp删除。 $ git branch -d A_temp

    OK,到此分支合并就完结了,现在我们就可以自信地召唤产品经理(我们公司产品兼测试)测试这两个功能。

    扩展

    另外给大家介绍一下git merge 使用的小技巧

    举例:要把master分支合并到dev分支

    1. git checkout dev // 切换到dev分支
    2. git merge master --no-ff // 使用--no-ff

    默认使用merge命令是ff,即 fast-forward,这种方式从Git 合并历史中是无法查看到是哪几个提交对象在一起实现了一个功能。

    --no-ff 标记会在分支合并的时候,创建一个新的提交对象,可以避免丢失master分支的历史信息,并且把所有的功能叠加在一起提交上去。两者的区别如下图所示,大家可以自己体验一下两者的区别。

    两者的区别

    以上就是小明工作中使用git合并总结的经验,希望能帮助到大家,仅供参考,有错误请指出,谢谢!

  • 相关阅读:
    Django路由层之有名分组和无名分组、反向解析、路由分发、伪静态的概念、名称空间、虚拟环境、Django1和Django2的区别
    如何计算3种卷积之后的尺寸(普通卷积,转置卷积,空洞卷积)
    两种高效的事件处理模式——Reactor和Proactor
    护眼灯亮度多少合适?2023最专业的护眼灯品牌推荐
    Chrome网页的标题编码错误,正文正常
    NextJS工程部署到阿里云linux Ecs
    风控模型中特征重要度的两种筛选方法
    业务架构·应用架构·数据架构实战~业务驱动的应用架构设计
    从头开始进行CUDA编程:Numba并行编程的基本概念
    Python 实现个人博客系统(附零基础python学习资料)
  • 原文地址:https://blog.csdn.net/sinat_30603081/article/details/136313882