修改旧的提交记录

7
我将提交历史记录如下:

我有以下提交历史记录:

* 8cd26ba 2013-06-26 | history server-side (HEAD, noXHR)
* bffd858 2013-06-25 | popups and modals
* d95c5f4 2013-06-21 | Map update for new interaction
...

当我已经提交了'8cd26ba'时,发现模态机制存在一个bug并希望进行修复。我尝试修改'bffd858'(因为修复与此有关),如这里所述。我执行了以下步骤:

  1. typed

    $ git rebase -i bffd858
    
  2. git shows me (in nano)

    pick 6fa566b history server-side
    # Rebase bffd858..6fa566b onto bffd858
    #
    # Commands:
    #  p, pick = use commit
    #  r, reword = use commit, but edit the commit message
    #  e, edit = use commit, but stop for amending
    #  s, squash = use commit, but meld into previous commit
    #  f, fixup = like "squash", but discard this commit's log message
    #  x, exec = run command (the rest of the line) using shell
    #
    # If you remove a line here THAT COMMIT WILL BE LOST.
    # However, if you remove everything, the rebase will be aborted.
    #
    
  3. I've replaced 'pick' with 'edit'

  4. git said me:

    Stopped at 8cd26ba... history server-side
    You can amend the commit now, with
    
        git commit --amend
    
    Once you are satisfied with your changes, run
    
        git rebase --continue
    
  5. I've apply my bug-fix and typed

    $ git commit -a --amend
    
  6. typed

    git rebase --continue
    
  7. And then I've found my bug-fix in '8cd26ba' (last commit)!

我哪里做错了?

感谢Sylvain Defresne的建议!真正让我困惑的是,在原始的问答中,'~1'部分被省略了。魔鬼就在细节中! - Roman Bekkiev
4个回答

13
您的错误在于,在执行变基操作时,您想要提供最早要修改的提交的父级ID。在您的情况下,您想要修改bffd858,其父级是d95c5f4,也被称为bffd858^bffd858~1(我更喜欢最后一种语法,因为它可以适用于将^解释为特殊字符的Shell)。
您应该使用以下命令:
$ git rebase --interactive bffd858~1

并更改了文件内容,以便它读取:

pick bffd858 popups and modals
fixup 6fa566b history server-side
# Rebase bffd858..6fa566b onto bffd858
#
# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#  f, fixup = like "squash", but discard this commit's log message
#  x, exec = run command (the rest of the line) using shell
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#

然后保存并关闭文件。

通常修复漏洞和更正历史记录的最简单方法是:

  1. 提交您的修复时使用 git commit --fixup=bffd858,
  2. 使用 git rebase --interactive --autosquash bffd858~1 进行变基,
  3. 打开文件并保存,等待变基完成。

这将利用您的修改对原始提交进行修补。

在您的情况下,您只对单个提交进行了变基,然后进行了修改。变基部分仅将历史记录倒回到提交修复后的点(即未执行任何操作)。


我会把最后一段移到顶部,因为它清楚地回答了提问者的问题。好建议! - John Szakmeister
请注意,如果 n > 1,则 <rev>^[n]<rev>~[n] 语法结构不同。 - kostix

1
我会这样做:
写一个合适的“修复提交”。
然后,或者 - 将其保持不变。这有时候已经足够好了。如果所有内容都已发布,那么这确实是您唯一的选择。
或者。执行git rebase -i <commit to fix>^ - 早于要修复的提交的前一个提交。然后编辑文件:将您的“修复提交”向上移动,使其恰好在您要修复的提交之后。然后要么将“pick”替换为“squash”,以将修复应用于该提交并编辑提交消息,要么将“fixup”应用于修复并保留消息不变。

0

@aragaer已经回答了这个问题,但我想为普通人澄清一下。

我曾经愚蠢地长时间地做以下操作,因为没有人在工作中告诉我,也找不到讨论此事的工作流程基础知识。我曾经使用git rebase -i HEAD~#将旧提交移动到HEAD,可能会在此过程中解决冲突,执行提交修正,然后再次进行变基以将提交移回其原始历史位置,可能再次解决冲突。虽然可以工作,但是这是错误的答案。真是一场噩梦。我很惊讶http://git-scm.com没有讨论这个问题,因为它是如此基础。如果有的话,我错过了它。

答案很简单:

  1. 创建一个新的提交,其中包含您要应用于旧提交的更改。
  2. 执行git rebase -i HEAD~10或者您需要回溯多远就回溯多远,这通常没问题。如果您恰好知道提交SHA,请使用上面@aragaer的答案。
  3. 将您的提交移动到要与之合并的旧提交的正下方。
  4. 然后,应用squashfix您的新提交。

完成。


0

您得到了您所要求的内容。您在文本中说您打算更改之前的提交,“历史记录服务器端”,但您实际上编辑了这一提交!

如果您从一个提交之前开始重新定义基础并编辑实际要更改的提交,该过程本身将会起作用。

但更方便的方法是在顶部修复并使用“Fixup!”提交修复,并最终从下面开始交互式重定义基础。使用自动压缩作为默认设置,它会自动将修复程序移动到正确位置并标记为修复程序(在压缩时也类似!)。当然,您也可以手动编辑待办事项清单。

然后只需执行即可。如果有些内容不符合预期,则此方法更容易重现,编辑的工作也容易丢失。


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