代码之家  ›  专栏  ›  技术社区  ›  elmarco

git:squash/fixup较早提交

git
  •  24
  • elmarco  · 技术社区  · 18 年前

    假设你有:

    A-B-C
    

    现在您的构建/测试失败了。修复程序应合并到一个。

    $ git commit -m "fixA"
    
    A-B-C-fixA
    
    $ git rebase -i A~1
    

    并在A中挤压fixA,导致:

    A'-B-C
    

    A-B-C + (index with fix for A)
    
    $ git commit -supperdupper A 
    

    结果:

    6 回复  |  直到 15 年前
        1
  •  20
  •   Jo Liss    11 年前

    如果您只是在寻找修复早期提交的简单解决方案,请阅读问题!这解释了一切。但既然Elmarco要求的是一种巧妙的方式,我们就这样做:

    --autosquash 选择 rebase ,这正是你想要的。还有 --fixup 和 --squash commit 让事情变得更容易。通过使用一些别名,您甚至可以将整个过程放到一个命令中。

    我建议升级到最新的Git,以获得最大的惊喜:

    git/Documentation/RelNotes $ grep -i -A1 autosquash\\\|fixup *
    1.7.0.txt: * "git rebase -i" learned new action "fixup" that squashes the change
    1.7.0.txt-   but does not affect existing log message.
    --
    1.7.0.txt: * "git rebase -i" also learned --autosquash option that is useful
    1.7.0.txt:   together with the new "fixup" action.
    1.7.0.txt-
    --
    1.7.3.txt: * "git rebase -i" peeks into rebase.autosquash configuration and acts as
    1.7.3.txt:   if you gave --autosquash from the command line.
    1.7.3.txt-
    --
    1.7.4.txt: * "git commit" learned --fixup and --squash options to help later invocation
    1.7.4.txt-   of the interactive rebase.
    --
    1.7.4.txt: * "git rebase --autosquash" can use SHA-1 object names to name which
    1.7.4.txt:   commit to fix up (e.g. "fixup! e83c5163").
    1.7.4.txt-
    
        2
  •  4
  •   bkeepers    13 年前

    我 created some aliases git commit --fixup 和 git commit --squash ~/.gitconfig :

    [alias]
      fixup = !sh -c 'REV=$(git rev-parse $1) && git commit --fixup $@ && git rebase -i --autosquash $REV^' -
      squash = !sh -c 'REV=$(git rev-parse $1) && git commit --squash $@ && git rebase -i --autosquash $REV^' -
    

    用法:

    $ git commit -am 'bad commit'
    $ git commit -am 'good commit'
    
    $ git add .          # Stage changes to correct the bad commit
    $ git fixup HEAD^    # HEAD^ can be replaced by the SHA of the bad commit
    

    错误的提交可以是多次提交。

        3
  •  4
  •   Mika Eloranta    12 年前

    我目前的git工作流程是这样的 --fixup / --squash 我写了一篇新的 git-fixup

    • git fixup 相同的文件
    • git fixup -a --修理 更改及其相应的“父级”提交
    • git fixup -r git rebase --autosquash 对于所有修复提交

    很多更改都是这样的,仅上述三个命令就足以完成任务,而不需要复制粘贴提交id或通过 git log --修理 目标。

    资料来源: https://github.com/ohmu/git-crust

        4
  •  2
  •   pje    13 年前

    如果要压缩最后两个提交,则必须调用

    git rebase --interactive <3rd last commit>
    

    然后,您需要选择最后一次提交并挤压第二次到最后一次提交。您无法挤压历史记录的最顶端提交。

        5
  •  0
  •   Martin OConnor    18 年前

    如果您与其他人共享正在进行更改的分支,则您所做的操作是危险的。 就你而言,你是 重写

    由于这个事实,Git开发人员故意不让这件事变得容易,因为您必须意识到这样做的后果。

        6
  •  0
  •   Oktalist    10 年前

    我认为问题的根源在于git(以及通常的版本控制)迫使您按照更改的顺序进行思考,但是一个更改集或特性分支或任何您称之为相关更改的内聚组的东西通常在逻辑上是不连续的。编写代码的顺序是偶然的,不一定与读取代码的顺序有关。

    我没有办法解决这个问题,但我已经写了一份 Perl script

    commit --fixup 和 rebase --autosquash 他们很棒,但做的还不够。当我有一系列的提交 A-B-C fixup!

    为了每一个大块头 git diff 脚本使用 git blame 查找最后触及相关行的提交,以及调用 git commit --fixup 修理! 提交,基本上执行与我以前手动执行的相同的操作。

    如果脚本无法将一个大块头解析为一个明确的提交,它会将其报告为一个失败的大块头,您将不得不使用手动方法来完成该任务。如果在两次单独的提交中更改了一行两次,脚本将该行上的更改解析为这些提交中的最新更改,这可能并不总是正确的解析。IMHO在“正常形式”功能分支中,您不应该在两次不同的提交中两次更改一行,每次提交都应该显示它所涉及的行的最终版本,以帮助审阅者。但是,它可能发生在错误修复分支中,以设计一个示例行 foo(bar()); 可通过提交(重命名)进行触摸 foo 到 fox bar 到 baz

    git 适当的我很想看到一个工具,它能够理解当一个交互的重基引入合并冲突时,应该如何解决合并冲突。