【问题标题】:Split commit into existing commits将提交拆分为现有提交
【发布时间】:2020-08-13 10:56:11
【问题描述】:

我有一个包含多个提交的分支:

A --- B --- C --- D
                  ^
                 HEAD

我已经完成了这个分支的工作并准备了拉取请求。但我对现在的历史并不满意:

  • C 正在修改很多文件,这些文件本来可以更好地提交到 A 和 B
  • D 正在修复一些独立的问题,应保持原样

我正在寻找一种在不破坏 D 的情况下将 C 拆分为 A 和 B 的干净方法。

【问题讨论】:

标签: git git-rebase git-rewrite-history


【解决方案1】:

你需要变基两次:

  • 首先,使用git rebase -i HEAD^4 运行交互式变基
  • 在编辑器窗口中,找到要拆分的提交并将第一个单词pick替换为eedit的缩写)
  • 保存并退出编辑器,rebase 将在您设置为编辑的提交后获取您
  • 使用git reset HEAD~ 重置提交
  • 现在您的更改未暂存,您可以根据需要提交它们
  • 使用 git add -p 在文件中仅添加一些更改很有用
  • 创建两个提交,一个在 A 中合并,另一个在 B 中合并
  • git rebase --continue

现在,您已将提交一分为二,历史记录应如下所示:

A --- B --- Ca --- Cb --- D
                          ^
                        HEAD

您现在可以启动第二个 rebase 以将 Ca 合并到 ACbB

  • git rebase -i HEAD^4
  • 在编辑器中,将提交Ca的行移到提交A的行下方,并将pick更改为ssquash的缩写)。
  • Cb 的行移到提交B 的行下,并将其设置为压缩到B
  • git rebase --continue

【讨论】:

    【解决方案2】:

    我将在 C 上创建一个 temp 分支,我将使用它,假设 main 在 D 上(未指定,但是):

    git branch -b temp C
    # let's go back to A, keeping _all_ of C's content so you can decide what to keep:
    git reset --soft A
    # now get the files the way you would like to get it for A (you can compare with A and B, just so that you _really_ get what you want.
    # when you are done
    git commit -m "new A"
    # temp is on the new A
    
    # let's go back to C
    git checkout C
    # let's put it on top of temp
    git reset --soft temp
    # Get the files you want the to be on B (compare with HEAD~1 and B.. and C)
    # when you are done
    git commit -m "new B"
    # let's put temp where we are
    git branch -f temp
    
    # finally, let's move whatever is left over from C that is not part of B
    git checkout C
    git reset --soft temp
    git commit -m "New C"
    git branch -f temp
    # at this moment C and temp are exactly the same
    
    git checkout temp
    git cherry-pick D
    # temp is like the branch you want
    

    ...就是这样。

    如果实际上 C 是您希望 B 成为的样子,对 A 进行一些更改,然后按照“新 A”的配方,然后

    git checkout C
    git reset --soft temp
    git commit -m "New B"
    git branch -f temp
    git checkout temp
    git cherry-pick D
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-23
      • 1970-01-01
      • 1970-01-01
      • 2011-01-08
      相关资源
      最近更新 更多