git - merge 意外分割的提交

标签 git rebase squash

我的历史看起来像这样(按数字/字母排序):

c1a - c1b - c2a - c2b - c4 - c5 - c6 - c8 (master)
                   |               \     
                   |                c9 (branch2)
                    \
                      c3 - c10 (branch3)
                       \
                        c7 - c11 (branch4)

我想压缩提交 c2a en c2b,但我找不到独立于分支的方法来做到这一点,所以我不得不 rebase 4 次,而不是我期望的结果(星号代表由于 rebase 而产生的副本) :

c1a - c1b - c2ab - c4 - c5 - c6 - c8 (master)
      ||\     
      || c2ab* - c4* - c5* - c6* - c9 (branch2)
      |\ 
      | c2ab** - c3 - c10 (branch3)
      \
       c2ab*** - c3* - c7 - c11(branch4)

代替

c1a - c1b - c2ab - c4 - c5 - c6 - c8 (master)
              |               \     
              |                c9 (branch2)
               \
                c3 - c10 (branch3)
                 \
                  c7 - c11 (branch4)

对历史记录的所有修改都是本地和远程的

我的问题是:

  • 如何修复我的历史记录,以便将所有副本 merge 为一次提交?
  • 如何将 c1a 和 c1b 压缩为一次提交,而不重现问题?

最佳答案

1) 对于分支 2、3 和 4,您需要运行 git rebase 至少 3 次

2)你不能。如果更改提交,则必须重写每个后代提交以及与这些提交关联的所有引用(通过 rebase )。没有办法解决这个问题。

您的中间图表表明您最初的 rebase 尝试出现了问题,因此这一次您最终的 rebase 操作将是通常情况下的两倍。

一般来说,如果您有一个已发布的历史记录,其中有那么多基于它的提交和引用,我不建议您对其进行修改。

从您的原始图表开始 - 您有 3 个 SHA 充当您的分支的 anchor 。 C2B 通向 Master 和 Branch3,C3 通向 Branch 4,C6 通向 Branch2。一旦为 C2B 重写 SHA,所有其他 SHA 也将发生变化,这使得整个过程非常复杂,并且在不直接跟踪中间 SHA 的情况下很难实现自动化。以下内容应该适用于这种特定情况。

请注意,这需要您对各个分支上的提交有具体的了解。你可以尝试在没有提交限制器的情况下进行 rebase ,但我偶尔会遇到这样做的糟糕经历(Git rebase 超过了应有的程度,我最终不得不使用 ctrl-c 退出它,然后中止并重试)

git checkout master 
git rebase -i HEAD~5
# edit rebase todo list to combine c2a/c2b
# once rebase has finished, master is OK.  Use git log to get the SHA that represents C2AB
git checkout branch2
git rebase --onto master~1 HEAD~1 # this will relocate the one unique commit on branch2 and hang it off of C6'
git checkout branch3
git rebase --onto C2AB_SHA HEAD~2 # this will take the two commits on branch3 and put them onto C2AB
git checkout branch4
git rebase --onto branch3~1 HEAD~2 # this will take the two commits on branch4 and put them on C3'  

通常,当您执行此类操作时,您会将其他分支重新设置为新分支尖端,而不是尝试保留原始父系。它使事情变得更加容易。

您的恢复过程实际上是相同的,但 --onto 和限制说明符略有不同。

关于git - merge 意外分割的提交,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26150118/

相关文章:

git - 从 GitHub 克隆时更改文件夹名称?

Git 重置当前 rebase

git - Git/Git 扩展中的 "squash"和 "fixup"有什么区别?

git - 将我所有的提交压缩为 GitHub pull 请求

git - 如何将所有 git 提交 merge 为一个?

linux - Git 大文件存储/如何在 AWS EC2 Linux 上安装 git lfs 2/"No package git-lfs available."

java - 如何在标准 openjdk docker 镜像上安装 Git?

git rebase -i with squash 无法分离 HEAD

version-control - 在使用clear工具进行rebase之前我应该​​检查我的更改吗

git pull *after* git rebase?