【问题标题】:Git: Temporary merges in a parallel fix work flowGit:并行修复工作流程中的临时合并
【发布时间】:2020-09-08 18:26:06
【问题描述】:

我处于这种情况,我们有 masterfix-afix-b 分支。

| A fix-a wip (HEAD of fix-a)
|/
| 
| B fix-b wip good enough (HEAD of fix-b)
|/  
M  (HEAD of master)
|

假设我正在处理fix-a,而其他人正在处理fix-bfix-afix-b 不相互依赖,完成后可以按任意顺序合并到 master。但是,修复 issue-b 后,使用 issue-a 会更方便。现在 issue-b 对我来说已经足够修复了,还没有完成,所以没有合并到 master 中。所以基本上我想将fix-b 合并到fix-a,但是当将fix-a 合并到master 时,不包括fix-b 的变化——考虑到fix-b 将继续分歧,我不希望半生不熟在我的分支中修复。

所以我将fix-b 合并到fix-a 并继续破解。

| E  a fixed! (HEAD of fix-a)
| |
| D  merge fix-b in to fix-a
| |\
| | A  fix-a wip
| |/
|/| C  fix-b still wip (HEAD of fix-b)
| |/
| B  fix-b wip good enough
|/  
M  (HEAD of master)
|

现在我想将更改 AE 合并到 master 中。所以我结帐E,执行git rebase -i 并删除B。然后合并到master

问题是,有没有更优雅的方法来做到这一点?想象AB 是一长串提交。 git rebase -i 是一种乏味的工作。我想说,在合并提交D 关注父A

【问题讨论】:

    标签: git merge rebase


    【解决方案1】:

    现在我想将更改 A 和 E 合并到 master 中

    只是合并。我不明白变基舞是为了什么。 E 有父 D,D 有父 A,所以 A 所做的更改仍在 E 中,在合并之后,A 仍将作为合并提交的祖先之一在 master 的历史中存在。没有更多的欲望了。

    您的犹豫可能是由于错误地认为 A 和 E 是变更集。他们不是。提交是当时所有文件的快照。合并提交 D 包括执行任何 A 所做的文件,提交 E 也包括它们。 (除非在准备 E 的过程中您删除了这些文件或采取了撤消 A 所做的任何事情的方式,但您当然没有 - 您的整个目标是使用 A 贡献的内容,而不是反驳它。)

    也可能是您最初的愿望根本不是合并,而是将A“借”到您的分支中。在那种情况下,你应该只是挑选它。然后,您可以对下一次提交进行本地交互式 rebase 以将其压缩到 A 中。这样看起来就好像您独立地提出了 A 中的功能。我不赞成这样做,因为您现在在谎报这些功能的来源,但在我看来,这比试图回溯合并提交要干净得多。

    【讨论】:

    • rebase in 丢弃来自 B 的更改。就好像 D 从未发生过一样。它只是为了我的方便。与修复 a 无关。
    • 这就是为什么我建议你应该从樱桃挑选 A 开始。你用合并提交完成了完全成熟的合并,现在你后悔了。
    • hmm.. 我如何丢弃樱桃采摘带来的(借来的)变化?改变难道不是我自己做出的改变吗?至少在合并(或基于 rebase)的情况下,我可以稍后退出提交。
    • 我认为您不了解我的情况。在D之前有A和B。我想要A。我只是暂时想要B,然后扔掉B。
    • 但是你需要 B 的状态来做你的好事。您不想反转 B。这会对您费心编写的代码造成不良影响。
    【解决方案2】:

    我每隔一段时间就会做这样的游戏......它是可以管理的,但是当你想要移动东西时它需要更多的努力......并且合并不是一个好主意(在与另一个功能合作时从一个功能中获取更改)。

    假设你分别开发fea-Afea-B。然后你想在fea-A 之上获得fea-B,只是因为它很有趣:

    git checkout fea-B
    git rebase fea-A # assuming fea-A was started _after_ fea-B was started
    

    然后,fea-A 得到了更多的工作(没有变基)...你如何让 fea-B 进行这些更改:

    git checkout fea-B
    git rebase fea-A # no problem.
    

    一个棘手的部分(不是唯一的部分)是如果fea-A 离开其当前基数(在变基上)。然后fea-B 有点悬而未决。你可以试试

    git checkout fea-B
    git rebase fea-A
    

    这是一个不行。您正在重新调整 fea-B 的修订版...加上原来的 fea-A 修订版。这是一个问题吗?嗯,是的......因为fea-A 在重新设置基础时可能已经被大量修改......甚至使用完全不同的内容从头开始重建。您想要重新设置您为fea-A 提供的内容。所以你应该试试这个:

    git checkout fea-B
    git rebase --onto fea-A fea-B~3 fea-B # assuming fea-B is only 3 revisions
    

    最后但并非最不重要的一点是,您想让它们再次分开如何:

    git checkout fea-B
    git rebase --onto main fea-A fea-B
    

    这将再次在main 之上获得fea-B,而没有所有fea-A 的东西。

    并保持分支笔直而不合并。搬运东西会更简单。

    【讨论】:

    • 我从未听说过 rebase --onto 标志,我会调查一下。谢谢你。我有点喜欢使用合并而不是变基来保留历史的想法。我从来没有这样做过,但我想有一天想要检查 SOME_MERGE_COMMIT^2 以查看当时的更改。
    • 太棒了!不要误会我的意思。我不反对合并……什么时候 PR 会合并到 main 分支中……但是在开发功能时等等?我认为它们应该是直线。处理它们更简单。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-04
    • 1970-01-01
    • 1970-01-01
    • 2010-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多