【问题标题】:Amending old commit修改旧提交
【发布时间】:2013-06-24 16:44:07
【问题描述】:

我的提交历史如下:

* 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”时,我发现了模态机制中的一个错误并想要修复它。我试图修改'bffd858'(因为修复与它有关),因为它described here。我做了以下步骤:

  1. 输入

    $ git rebase -i bffd858
    
  2. git 向我展示(在 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. 我已将“pick”替换为“edit”

  4. git 说我:

    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. 我已经应用了我的错误修复并输入了

    $ git commit -a --amend
    
  6. 打字

    git rebase --continue
    
  7. 然后我在“8cd26ba”中找到了我的错误修复(last 提交)!

我做错了什么?

【问题讨论】:

  • 感谢 Sylvain Defresne 的建议!真正让我感到困惑的是,原来的问答“~1”部分被遗漏了。魔鬼在细节!

标签: git


【解决方案1】:

您的错误是,当您进行变基时,您想提供要修改的最早提交的父级的 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. 保存打开的文件,然后等待变基完成。

然后您的原始提交将被修复。

在您的情况下,您只使用了一次提交进行了 rebase,然后您对其进行了修改。 rebase 部分,只是在您提交修复后将历史倒退到点(即什么也没做)。

【讨论】:

  • 我会将最后一段移到顶部,因为它清楚地回答了 OP 的问题。好建议!
  • 请注意,<rev>^[n]<rev>~[n] 语法结构在 n > 1 时不同
【解决方案2】:

我会这样做:

写一个正确的“修复提交”。

然后 - 保持原样。它有时已经足够好了。如果全部发布,它确实是您唯一的好选择。

或者。执行git rebase -i <commit to fix>^ - 比您要修复的那个早一个。然后编辑文件:将“修复提交”向上移动,使其正好在您要修复的那个之后。然后将“pick”替换为“squash”以将修复应用于该提交并编辑提交消息,或者将“fixup”替换为应用修复并保留消息原样。

【讨论】:

    【解决方案3】:

    你得到的正是你所要求的。您编辑了“历史服务器端”提交,而在文本中您说您之前打算提交!

    如果您从较早的一个提交开始 rebase 并编辑实际预期的一个,则该过程本身会起作用。

    但更方便的方法是在顶部进行修复,并使用 'Fixup! ',并最终从下开始交互式变基。由于 auto-squash 是默认设置,它会自动将待办事项列表移动到适当的位置并将它们标记为已修复。 (类似于壁球!)。当然,您可以手动编辑待办事项。

    然后执行。如果某些事情没有达到预期,这种方式更容易重现,在编辑中完成的工作很容易丢失。

    【讨论】:

      【解决方案4】:

      @aragaer 回答了这个问题,但我想为外行澄清一下。

      我愚蠢地坚持了这么久,因为没有人在工作中告诉我,也找不到讨论这个的工作流程基础知识。我曾经使用git rebase -i HEAD~# 将旧提交移动到 HEAD,可能会在此过程中修复冲突,执行提交修改,然后再次变基以将提交移回其历史记录中的原始位置,从而可能再次修复冲突。有效,但答案错误。什么样的恶梦。我很惊讶http://git-scm.com 没有讨论这个,它太基础了。如果是这样,我错过了。

      答案很简单:

      1. 使用您想要应用于旧提交的更改进行新提交。
      2. git rebase -i HEAD~10 或无论您需要走多远,这通常都可以。如果您碰巧知道提交 SHA,请使用上面的@aragaer 答案。
      3. 将您的提交移动到您想要压缩它的旧提交的下方。
      4. 然后应用 squashfix 您的新提交。

      完成。

      【讨论】:

        猜你喜欢
        • 2012-02-08
        • 1970-01-01
        • 2020-12-18
        • 1970-01-01
        • 2014-07-12
        • 2021-12-31
        • 1970-01-01
        • 1970-01-01
        • 2017-05-05
        相关资源
        最近更新 更多