git - 有没有一种快速的方法可以将长期提交到 master 分支的历史 rebase ?

标签 git rebase git-rebase

过去两周我一直在研究一个功能,并为它创建了一个单独的分支。问题是这项任务花了我很长时间,而且我没有定期将我的分支重新设置为 master。我最终得到了 100 多个提交,现在当我尝试使用 git rebase master 将分支重新设置为 master 时,它需要永远,因为我需要检查每个提交的冲突,修改它,git add然后 git rebase --continue .

有没有更简单的方法来做到这一点?

最佳答案

这部分取决于您如何完成 100 多次提交以及在此期间发生了什么。四种策略可能有用:
减少 rebase 的提交次数
如果你有 100 次提交的漂亮清晰的流,从不修改相同的代码两次,对不起,但你被卡住了。
然而,从两周内的 100 次提交来看,我猜你的提交历史看起来不像那样。也许您已经在提交历史记录中修改了函数 X 5 次,并且每一次提交都会导致冲突。如果只有一次提交修改了函数 X,那么您将有 20% 的工作要做。
所以这里的答案是在你 rebase 到 master 之前整理你的提交历史。这是“git rebase”的另一个用途。将其重新绑定(bind)到现有的基础上,但使用 git rebase -i以交互方式挤压在一起并重新排序提交。确保你有最少数量的提交,并且每个提交都做一些独立的事情。您也可以借此机会更改提交日志。关键备份分支 ( git branch ) 和 git diff在每次提交后检查你没有改变任何东西。
特别是,如果您有内部 merge 提交,将它们展平会很有帮助。
不可避免地,当我这样做时,我发现我做错了,或者本可以做得更好,即使它“只是”代码格式或提交消息。您可以借此机会修复这些问题。我猜你应该在完成后减少到 10 或 20 次提交 - 更易于管理。
分阶段 rebase
如果你已经这样做了,你可能不得不咬紧牙关。但是,如果同事在您工作时一直在进行重构,那么有时您最好的做法如下。想象一下这棵树看起来有点像这样:

    A --- B --- C --- D --- E --- F -- .... -- X --- Y --- Z (master)
     \
      \----- 1 --- 2 --- 3 --- 4 .... 97 --- 98 --- 99 --- 100 (you)
您最终想要做的是重新基于 Z。但是,这会给您带来很多冲突。让我们假设提交 D 和 E 是来自一位同事重构您的代码正在处理的内容的两个大型提交。有时,更容易:
  • Rebase 到 C(这应该没什么工作)
  • 深吸一口气,重新回到 E
  • Rebase 到 master(这应该没什么工作)

  • 避免“主”端的复杂性
    有时,在您尝试 merge 的树上,事情变得非常复杂。一个经典的例子是(使用上图),提交 G 恢复提交 C,然后提交 H 重做(或几乎重做)它,同时有 merge (特别是你可能已经 merge 的事情) .谢谢同事,这让 rebase 变得非常简单。其他导致困难的事情是复杂的 merge 提交和讨厌的重命名。每次提交都会无缘无故地一次又一次地给你同样的冲突。 git rebase啊!
    这里的一种技术是展平主树的副本,即分支 master(本地),然后将其 rebase 将整个内容压缩为从 A 到 Z 的单个提交。您也可以先展平您的内容(见上文)。然后 rebase 到扁平的母版上。现在您已经获得了“正确”的一组提交,您可以轻松地将其重新设置为 master(嗯,由于 master 可能会更改,因此可以将其重新设置为“Z”),因为代码完全相同。
    如果一切都失败了
    有时 git rebase似乎陷入了矛盾的神游状态,是时候爆发了git format-patchgit am全部或部分地重新应用它。如果有人重命名了文件(因为您可以在编辑器的补丁中修复文件名)或重命名公共(public)类/变量/任何东西(因为您可以在补丁中找到/替换),这非常有用。
    从你的错误中学习
    下一次,更频繁地 rebase 到 master。如果你边做边做,痛苦会小一些。
    另外,如果您有两个人在同一代码区域工作并且产生了一堆冲突,那么您的代码可能抽象得不够好,或者您是在彼此之上工作并且可以更好地划分您的工作?

    关于git - 有没有一种快速的方法可以将长期提交到 master 分支的历史 rebase ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32681850/

    相关文章:

    git - 如何为 gitk 添加更好的复制检测?

    Git 重置当前 rebase

    git - 在 rebase 之前挤压

    Git:如何通过访问控制保护 git-flow 中的 develop/master 分支(来自菜鸟)?

    git - 更改 GIT 端口

    git - 在 rebase -i 期间重写提交消息时如何使 git show diff?

    git - 'git merge' 和 'git rebase' 有什么区别?

    git - 无法完成 Git Rebase

    git - vim-plug PlugInstall 在尝试从 git pull 时抛出 PAT 身份验证错误?

    git rebase "--preserve-merges --onto"不保留 merge