【问题标题】:git commit --fixup hash does nothinggit commit --fixup hash 什么都不做
【发布时间】:2021-06-20 05:51:45
【问题描述】:

我有一个要修复的提交。我做错了什么?

git commit --fixup bdf55a7c12996e3af853c27ca4ff6c670e826c5e
On branch foo
nothing to commit, working tree clean
git --version
git version 2.31.0

【问题讨论】:

  • 输出是否正确?...您的树中是否没有待提交的更改要提交?执行“git status”并将结果添加到您的问题中。
  • 如果你已经提交你的新提交(没有更改仍然暂存),git commit --fixup 不会做任何事情。你想要git rebase -i
  • @Joshua,嗯?修复的整个想法是您正在更改内容而不是更改消息。因此,--fixup=that-other-commit 创建了一条虚拟消息,git rebase --autosquash 将其识别为“我现在正在创建的这个提交应该被视为对那个其他提交的修复,而不是一个带有自己消息的真正提交”。
  • @Joshua, ...所以,如果您已经提交了要作为修复程序应用的代码,那么再给它那个虚假消息已经太迟了;你可以直接去git rebase -i,在你的编辑器中手动将操作类型更改为fixup,然后将行移动到that-other-commit行的正下方(这是commit --fixup会做的两件事rebase --autosquash 自动代表您执行)。
  • 老实说,commit --fixup 标志不会做任何没有它就无法完成的事情。确保您了解fixup 标记在git rebase -i 中的工作原理,如果您对此感到满意,您可以做任何--fixup 在没有它时会为您做的事情。

标签: git git-commit


【解决方案1】:

随着 Git 2.32(2021 年第二季度),“git commit --fixup=<commit>(man) 发生了变化。

它是在保持原始日志消息不变的情况下调整对内容所做的更改,但现在它已经学习了“--fixup=(amend|reword):<commit>”,可用于调整消息和内容,并且只调整消息,分别。

参见commit 00ea64ecommit 8bedae4commit 3d1bda6commit 3270ae8commit 494d314commit 6e0e288(2021 年 3 月 15 日)Charvi Mendiratta (charvi-077)
(由Junio C Hamano -- gitster -- 合并commit 89519f6,2021 年 3 月 26 日)

commit:将修改子选项添加到 --fixup 以创建修改!提交

指导者:Christian Couder
指导者:Phillip Wood
帮助者:Junio C Hamano帮助者:Eric Sunshine
签字者:Charvi Mendiratta

git commit --fixup=amend:<commit>"(man) 将创建一个“amend!”提交。
生成的提交消息主题将为“amend! ...”,其中“...”是<commit> 的主题行,初始消息正文将是<commit> 的消息。

amend!”提交在使用--autosquash 重新设置时将修复内容并将<commit> 的提交消息替换为“修改!”提交的消息正文。

为了防止 rebase 创建带有空消息的提交,如果提交消息正文为空,我们拒绝创建“amend!”提交。

详细说明:

doc/git-commit:为fixup=[amend|reword] options 添加文档

指导者:Christian Couder
指导者:Phillip Wood
帮助者:Eric Sunshine
帮助:Junio C Hamano
签字人:Eric Sunshine
签字人:Charvi Mendiratta

git commit 现在包含在其man page 中:

[--dry-run] [(-c | -C | --squash) <commit> | --fixup [(amend|reword):]<commit>)]

git commit 现在包含在其man page 中:

--fixup=[(amend|reword):]<commit>

创建一个新的提交,在应用时“修复”<commit> git rebase --autosquash.

普通--fixup=<commit> 创建一个 “修理!”提交更改 <commit> 的内容但离开 它的日志消息保持不变。

--fixup=amend:<commit> 类似但 创建一个“amend!”提交,它也替换了日志消息 <commit> 带有“amend!”提交的日志消息。

--fixup=reword:<commit> 创建一个“amend!”提交 用自己的日志消息替换<commit> 的日志消息 但不改变<commit>的内容。

plain --fixup=<commit> 创建的提交有一个主题 由“fixup!”和来自<commit>的主题行组成, 并且被git rebase --autosquash特别认可。
-m 选项可用于补充创建的日志消息 提交,但额外的评论将被丢弃,一旦 “fixup!”提交被压缩成<commit> git rebase --autosquash.

--fixup=amend:<commit> 创建的提交是相似的,但它的 主题改为以“amend!”为前缀。
<commit> 的日志消息被复制到“amend!”提交的日志消息中,并在编辑器中打开,以便对其进行细化。
git rebase --autosquash 将“amend!”提交压缩到<commit> 时, <commit> 的日志消息被细化的日志消息替换 来自“amend!”提交。

amend!”提交的日志消息为空是错误的,除非--allow-empty-message 是 指定。

--fixup=reword:<commit>--fixup=amend:<commit> --only 的简写。
它创建一个只有一条日志消息的“amend!”提交 (忽略索引中的任何更改)。
当被git rebase --autosquash 压扁时,它会替换<commit> 的日志消息,而不做任何其他更改。

fixup!”和“amend!”均未提交更改作者身份 <commit>git rebase --autosquash 申请时。

git rebase 现在包含在其man page 中:

当提交日志消息以“squash! ...”或“fixup! ...”开头时 或“amend! ...”,并且待办事项列表中已经有一个提交 匹配相同...,自动修改todo列表 rebase -i,以便标记为压缩的提交紧随其后 要修改的提交,并更改移动提交的操作 分别从picksquashfixupfixup -C

提交 如果提交主题匹配,则匹配 ...,或者如果 ... 引用 到提交的哈希。

作为后备,提交的部分匹配 主题工作也是如此。

推荐的创建修复/修改/壁球的方法 提交是通过使用--fixup--fixup=amend:--fixup=reword:--squash 分别是git commit 的选项。


在 Git 2.34(2021 年第四季度)中,“git commit(man)--fixup 现在再次与 --edit 一起使用,在 v2.32 中被破坏后。 p>

参见 Joel Klinghed (thejk)commit 8ef6aad(2021 年 8 月 14 日)。
(由 Junio C Hamano -- gitster -- 合并于 commit 6e21f71,2021 年 9 月 3 日)

commit: 与 --fixup 结合使用时恢复 --edit

签字人:Joel Klinghed

最近对--fixup 的更改,添加了修正子选项,导致--edit 标志被忽略,因为use_editor 始终设置为零。

在确定use_editor 的值时,通过在方法中稍后移动编辑标志条件来恢复优先级高于fixup_messageedit_flag

【讨论】:

    【解决方案2】:

    你在a comment中提到:

    我没有意识到它不是用于提交消息的。

    目前没有git commit 选项 的意思。1 相反,您需要运行git rebase -i(无论如何您通常都会这样做)然后将该特定提交的 pick 行更改为 reword 行。

    我还是不明白如何正确使用修复工具...

    这里要理解的是git commit --fixupgit commit --squash是比较晚的发明。 首先git rebase --interactive。 (还有更多的背景知识需要理解,但我们假设您通过重复摘樱桃完全了解git rebase 的作用以及它是如何做到的。如果您不了解,那是一个单独的问题——已经在 StackOverflow 上询问并回答了,所以请搜索那些问答。)

    现在,由于 rebase 本质上是一系列精选操作,我们观察到机械的、自动的、按原样复制每个提交的 rebase 有点无聊。我们添加了一些刺激!!! (在此处插入大片的电影爆炸声和巨大的噪音) 通过将一系列精选内容变成一个命令块:

    pick a123456   subject line from that commit
    pick b789abc   another commit subject line
    pick cef0123   ... etc ...
    pick d456789   and so on
    

    然后,在制作完这份“说明书”之后,我们为您——用户——提供编辑这份说明书的机会。

    例如,您可以更改pick 行的顺序。这意味着,它们不是按照原始顺序完成,而是按照您选择的新顺序完成。所以你可以重新调整提交的order。如果你有一个提交错误,并使用后来的提交以某种方式修复它,你可以将错误和修复提交放在一起!

    到目前为止,这并没有太多帮助。你改变:

    pick a123456   subject line from that commit
    pick b789abc   another commit subject line
    pick cef0123   ... etc ...
    pick d456789   and so on
    pick eabcdef   whoops
    

    进入:

    pick a123456   subject line from that commit
    pick b789abc   another commit subject line
    pick eabcdef   whoops
    pick cef0123   ... etc ...
    pick d456789   and so on
    

    “哎呀”提交修复了您在提交b789abc 中所犯的错误。好的,所以如果您运行 这些 指令,重新定位的结果是错误提交和修复提交现在 相邻,而不是由(的副本)分隔提交cef0123,后跟d456789

    但现在我们添加了更多选项。例如,我们不仅添加了pick,还添加了选项squash。这告诉 Git,它应该将 两个 提交转换为 单个组合提交,而不是仅仅挑选提交 eabcdef(修复早期提交的那个)。它还应该从两个提交中获取提交日志消息,并将它们放入一个临时文件中并将该临时文件用作提交消息... 给你有机会编辑该文件!

    因此,现在您可以将两个提交消息编辑为单个提交消息,用于将有缺陷的提交与其修复提交一起压缩而产生的组合提交!这是这里最初的想法。


    1正在努力为此添加一个新的提交选项。


    让我们暂停一下,盘点一下

    因此,通过只知道两个选项(picksquash)的交互式变基,我们获得了以下能力:

    • 我们可以重新排序提交,将密切相关的提交放在一起。
    • 我们可以合并提交。当我们这样做时,我们会被扔到我们的编辑器中,为组合提交组成正确的提交消息。

    既然我们可以做这么多,让我们考虑一下我们可能希望能够做的其他事情:

    • 如果某些提交消息中有错字,能够修复它会很好。

      所以,在我们现有的两个选项(picksquash)上添加一个 reword 选项。这将挑选提交,但也会让我们进入我们的编辑器,让我们首先更改提交消息

    • 如果提交中有问题,但我们有修复它并且我们不需要修复它的提交消息,如果能够进行修复就好了在提交失败后立即提交。我们已经可以通过移动它并使用squash 来做到这一点。但这会将我们带入我们的编辑器。最好只保留来自被破坏的提交的提交message,同时压缩两个提交。

      所以,在我们现有的选项中,让我们添加一个fixup 选项。这将进行压缩,就像 squash 所做的那样,但不会将我们放入我们的编辑器中。它将完全丢弃修复提交的消息,在修复压缩的同时保留来自稍微损坏的提交的消息。

    这些为我们提供了一些交互式 rebase 可以执行的命令。在我们停止并声明我们的交互式 rebase 功能很漂亮并且应该成为 Git 的一部分并将其放入 Git 之前,我们得到了更多(例如 edit,它选择提交但随后停止,就好像存在冲突一样)发布。然后它在 Git 中存在了几年。

    现在几年过去了,我们说:嘿,如果我们可以在我们提交时让git commit 注释 提交,那就太好了,说这是一个壁球或修复提交,git rebase --interactive 应该自动变成squashrebase这就是你遇到的情况。你在电影中迟到了,并不知道所有这些背景,但现在你已经阅读了一些剧透来解释电影的第一部分以及我们是如何到达这里的。

    这解释了为什么会出现错误:--fixup 提交应该是修复已提交文件中的错误。这不是为了修复提交消息git commit 目前还没有办法做到这一点。相反,您必须自己运行git rebase -i,并将pick 行更改为reword 行。

    【讨论】:

    • 您关于 fixup 实际作用的部分最终回答了我的问题。
    【解决方案3】:

    您似乎认为git commit --fixup 更改了现有提交。它没有。 git commit --fixupgit commit --squash 是历史重写的一部分,但它们只是解决方案的一部分。

    git commit --fixup 不会更改您指向的提交。它在当前分支的头部创建一个新的提交,主题是从给定的提交中构造的,前面带有单词fixup! 。提交是包含当前更改的常规提交,因此请使用 git addgit commit -a --fixup 添加和提交更改。

    然后运行git rebase --interactive --autosquash — 这是执行修复/压缩的主要命令。该命令对提交进行重新排序,并为您提供修复/壁球的提交列表。验证列表并退出编辑器。 git rebase 将运行修复或压缩提交。

    了解如何将所有内容组合到一个巧妙的别名中:https://blog.filippo.io/git-fixup-amending-an-older-commit/

    [alias]
            fixup = "!f() { TARGET=$(git rev-parse "$1"); git commit --fixup=$TARGET ${@:2} && EDITOR=true git rebase -i --autostash --autosquash $TARGET^; }; f"
    

    使用它:

    git fixup bdf55a7c12996e3af853c27ca4ff6c670e826c5e
    

    【讨论】:

    • 我一定不明白,如果我给 git commit --fixup 一个哈希值,它不应该使用该哈希值来变基并进行新的提交吗?或者至少创建一个具有相同内容和 fixme 的新提交!提交消息?
    • @Joshua,你给它的散列是rebase --autosquash 将放置你现在正在创建的新提交的散列(这个概念只有在你有分阶段的,未提交的更改)直接在上面。因此,如果您之前提交了“bugfix foo”并发现了一个错字,您可以git add 修复该错字,然后git commit --fixup=bugfix-foo-hashgit rebase -i --autosquash 知道它应该将您的错字修复视为对 bugfix-foo 的修正-hash 提交。
    • @Joshua Nop,当您给git commit --fixup 一个哈希值时,该哈希值用于从给定提交的消息主题构造一个新的提交消息主题。仅此而已。
    • @CharlesDuffy 那么如何创建新的提交以便我可以编辑消息?
    • @Joshua,...如果它会以自己的信息存在于历史中(不仅仅是暂时的/直到你变基),这不是一个修复。修复的全部意义是它们将被压缩到现有提交中而被破坏,同时保持现有提交的消息不变(这是修复和常规壁球之间的区别;与常规squash 用户有机会合并两个提交消息,而通过修复,通过压缩其他更改来“修复”提交保留其原始消息)。
    猜你喜欢
    • 2011-04-04
    • 2017-02-07
    • 1970-01-01
    • 2019-08-16
    • 2012-11-07
    • 1970-01-01
    • 2020-02-14
    • 1970-01-01
    • 2019-02-18
    相关资源
    最近更新 更多