在中止交互式变基后如何恢复上一个待办事项?

13
假设我正在进行一个互动变基,该分支包含大约20个提交。在TODO文件中,我压缩、重新命名和重新排序提交。总的来说,这需要做很多工作才能设置好这个变基。
在变基过程的一半以上,我出了点问题。我通过执行"git rebase --abort"取消了变基。我再次开始变基以重新开始,因为在变基过程中我弄错了一个提交(也许我解决了一个冲突,但直到后来才意识到)。
现在我必须重新编辑TODO。Git不会记住我上次配置的TODO文件吗?它不能记住我重新命名的提交信息吗?
也许一个更简单的问题是,有没有一种方法可以仅仅将交互式变基倒回几步,然后从那个点重新开始?

你是否曾经考虑向git项目提出/报告这个问题?我经常遇到你在这里解释的非平凡提交的确切问题(通常是交换两个不应该交换的提交),似乎仍然没有办法恢复之前中止的rebase。 - Masklinn
3个回答

4
对于每次成功的变基步骤,都会创建一个新的提交,并在引用记录中记录下来。 因此,您可以利用这一点,在上一次成功点重新开始一个新的变基过程。
例如:
git rebase --abort # Oops! I notice I messed up during rebase
git reflog         # find the last "good" rebase hash created

git rebase -i --onto <last-good-hash> \
<branchname>~<number of commits that were not replayed>

这是一种比较繁琐的方法,但考虑到长时间或困难的变基,这可能是值得的。这实质上是在你中止的地方重新创建TODO。

直接在新分支上挑选一个范围,而不进行交互式变基,这样不是更好吗? - mlt
@mlt 如果要将分支变基到另一个分支,那么这是一种选择,但如果变基是为了清理提交历史记录,那么我认为我会使用这种方法。另外一件事是,即使您创建了一个新分支,在 cherry-pick 过程中仍然可能遇到冲突。我可能误解了您的评论。 - Jeff Ward
你可以使用 rebase --onto 将步骤 3-5 结合起来。使用 reflog 找到最后一个“好”的 rebase 哈希值。然后:git rebase -i --onto <last-good-hash> <branchname>~<number of commits that were not replayed>。这本质上重新创建了你中止的 TODO。例如:git rebase -i --onto 1234567 myBranch~5。将我分支上的最后 5 次提交重放到 1234567 上,这是我离开的假设点。 - joshtkling
另外,您仍然需要再次编辑todo文件。这样可以避免重新执行已经变基的提交,但我不熟悉从先前的todo文件恢复git的方法。 - joshtkling

4
老实说,经过这么长时间的寻找,我仍然没有找到一个好的内置解决方案。实际上,我今天使用的技术非常简单。
在设置想要的rebase之后,在保存和关闭文件之前,将整个内容复制并粘贴到另一个临时记事本窗口中。
如果您需要完全放弃rebase以便稍后再次尝试,只需从临时窗口中复制并粘贴内容即可。对我有效!

更新:抱歉,我刚刚注意到文件是文本编辑器的备份,它不是100%相同,它是版本1-最终之前保存的。然而,清理后的.backup似乎可用。 - quetzalcoatl

1
对于如此复杂和漫长的变基操作,你可以尝试使用git-imerge,它可以处理Git的增量合并和变基
这样,任何时候“出错”意味着您可以停止、修复和恢复变基会话。请注意,中止变基将有效地删除包含.git/rebase-merge文件夹的文件夹
  • 当前应用的提交哈希

    cat .git/rebase-merge/stopped-sha
    

    如果您想检查原始提交的更改,例如如下方式:

    git show `cat .git/rebase-merge/stopped-sha`
    
  • 当前提交的消息

    cat .git/rebase-merge/message
    

    以防您忘记了更改的目的。

  • 剩余的变基任务列表

    cat .git/rebase-merge/git-rebase-todo
    

    所有将在当前提交之后应用的提交(及其“策略”,例如pick、squash等)

  • 您(整个)变基所应用的目标提交/分支的哈希

    cat .git/rebase-merge/onto
    

    方便查看该分支文件的状态。


2
根据我收到的反馈,似乎为git-rebase实现一个好功能。原生支持“记住”上次rebase操作会很不错。 - void.pointer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接