Git 修改旧承诺

Git 修改旧承诺,git,Git,我的提交历史记录如下: * 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”(因为修复程序与之相关),因为它是。我已经完成了

我的提交历史记录如下:

* 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”(因为修复程序与之相关),因为它是。我已经完成了以下步骤:

  • 打字

    $ git rebase -i bffd858
    
  • git向我展示(nano)

  • 我已将“拾取”替换为“编辑”

  • 吉特对我说:

    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
    
  • 我已应用我的错误修复并键入

    $ git commit -a --amend
    
  • 打字

    git rebase --continue
    
  • 然后我在“8cd26ba”(lastcommit)中找到了我的bug修复


  • 我做错了什么

    您的错误是,在执行重基时,您希望提供要修改的最早提交的父级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.
    #
    
    然后保存并关闭文件

    通常,应用错误修复和更正历史记录的最简单方法是:

  • 提交修复程序时,请使用git commit--fixup=bffd858
  • 使用
    git-rebase--interactive--autosquash bffd858~1
    重新设置基址
  • 将文件保存到打开的位置,然后等待重新基线完成
  • 您最初的提交将被修复


    在您的例子中,您只对一个提交执行了一次重基,然后对其进行了修改。“重设基础”部分,只是将历史倒回到您提交修复后的某一点(即,什么也没做)。

    我会这样做:

    编写一个适当的“修复提交”

    那么要么——让它保持原样。有时候已经足够好了。如果全部出版,这真的是你唯一的好选择


    或者。执行
    git-rebase-i^
    -比要修复的版本早一个。然后编辑文件:将“修复提交”向上移动,使其正好位于要修复的文件之后。然后,将“pick”替换为“squash”以对提交和编辑提交消息应用修复,或将“fixup”替换为应用修复并保持消息不变。

    您完全得到了您的要求。您编辑了“历史服务器端”提交,而在文本中,您说您之前打算提交一个

    如果您从较早的一次提交开始重新设置基础,并编辑实际想要的提交,那么流程本身就可以工作

    但更方便的方法是,只需将您的修复放在最上面,用“Fixup!”提交即可,并最终从下面开始交互式重基。自动挤压是默认设置,它会自动创建todo列表,将修复移动到适当的位置,并将其标记为修复。(类似于壁球!)。当然,您可以手动编辑todo


    那就执行吧。这种方法更容易复制,如果某些内容没有达到预期效果,编辑中完成的工作很容易丢失。

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

    我愚蠢地做了这么长时间,因为在工作中没有人告诉我,也找不到讨论这个问题的工作流基础。我曾经做过
    git-rebase-I HEAD~#
    将旧的提交移动到HEAD,可能会在移动过程中修复冲突,执行提交修正,然后再次重定基址以将提交移回其历史上的原始位置,可能会再次修复冲突。虽然有效,但答案是错误的。真是一场噩梦。我很惊讶没有讨论这个,它太基本了。如果有,我就错过了

    答案很简单:

  • 使用要应用于旧提交的更改进行新提交
  • git-rebase-i HEAD~10
    或者无论你需要走多远,通常都可以。如果您碰巧知道提交SHA,请使用上面@aragaer的答案
  • 将“提交”移动到要挤压它的旧提交的正下方
  • 然后应用
    squash
    fix
    您的新提交

  • 完成。

    我将最后一段移到顶部,因为它清楚地回答了OP的问题。好建议!请注意,
    ^[n]
    ~[n]
    如果
    n
    >1Thanks,Sylvain Defresne,征求意见,语法结构是不同的!真正让我困惑的是,在最初的问答中,“~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.
    #