【问题标题】:How to change git commit message without changing commit hash如何在不更改提交哈希的情况下更改 git 提交消息
【发布时间】:2011-07-09 22:28:09
【问题描述】:

标题不准确,但我不能用一行更好地表达它。

  • 我实际上知道如何更改 git 提交消息,例如 here
  • 但我知道它也总是会更改 SHA-1,我想避免这种情况。

我只想看到git-log 中的不同消息。我认为可以使用git-notes 以某种方式完成,但我没有做到。


说明:

我需要它来修复提交消息中的错误。我总是在那里写包含我与客户沟通的文件的名称(它看起来就像T1234 Replace foo by bar)。沟通往往很长,所以我可以浪费很多时间,直到我发现我被提交消息中的错误文档名称误导了。

使用git-notes

看起来git-notes 实际上就像here 所说的那样工作。但是我总是使用

git log --oneline

所以我从来没有看到它。关于让 git 对用户撒谎的评论:恕我直言,只有在使用像 --replace-messages-by-notes 这样的特殊开关时才会发生这种情况是可以接受的,不是吗?因为我总是使用别名而不是直接使用git log,所以我不需要输入很多内容就可以得到我想要的。

您认为这是一个合理的功能要求还是会向我推荐其他工作流程?

【问题讨论】:

  • 这听起来就像git-notes 将成为解决方案,所以如果您澄清为什么git-notes 不适合您,也许会有所帮助。为什么要更改git-log 所说的内容(实际上是让git-log 对用户撒谎)?
  • 是的,git log 应该撒谎......但谎言实际上是正确的,因为输入的提交消息是例如引用错误的文件。当我盲目地遵循 git-commit 所说的内容时,我只会损失不可忽略的时间,直到我发现错误为止。
  • 您实际上并不想更改提交消息(正如其他人所说,它从根本上与 git 的工作方式相反)。但我认为这不是问题 - 听起来你真正的问题是“我如何让 git log 向我显示注释而不是提交消息,如果它们存在的话?”
  • 对...现在这对我来说实际上很明显,但不是我开始提问的时候。
  • 你可以使用git replace 来做你想做的事,但我会小心使用它来替换大量提交(由于文件数量非常多,它可能会导致性能问题在.git/refs/replace/ 中——至少在重新打包存储库之前)。

标签: git history


【解决方案1】:

从技术上讲,这似乎是不可能的(至少对我来说,虽然我不是 git pro)。

一个 git commit 存储一个树形哈希(想想:你当时的工作目录的状态)和额外的提交信息。当您更改提交消息时,树哈希不会更改,但是提交哈希会更改,因为它是根据提交对象计算的,没有办法绕过它。

详情请见Progit internals

【讨论】:

  • 你说得对,但我不需要更改存储的消息,我只需要更改显示的消息。跨度>
  • progit internals 链接好像失效了,但是你可以在archive.org找到它
【解决方案2】:

git notes 是在不更改 SHA1 的情况下获得不同 git 日志消息(不同于提交消息)的唯一方法,如 "Notes to Self" article(来自 original Aug. 2010 article)中所述。

不过有几点说明:

  • 注释按命名空间组织,默认为“commits”。
  • 注释不要修改提交消息,它们只会添加到它(这可能是git notes 不适合您的原因)。
  • 默认情况下不会推送注释,除非您明确指定它们的 refspec (refs/notes/*)

【讨论】:

  • “自我笔记”网站的 SSL 证书已过期 - 内容可以在 wayback machine 上(似乎重定向到 git-scm 博客)。 git-scm 博文本身已不存在。
  • @snakecharmerb 感谢您的反馈。我已经相应地编辑了答案,但也引用了原始文章(仍然可用):scottchacon.com/2010/08/25/notes.html
【解决方案3】:

正如许多人所指出的(例如在VonC's very useful answer 中),git notes 确实是您正在寻找的机制。把你的别名改成下面这样还不够吗?

git log --oneline --show-notes

大概只是偶尔您必须在提交中添加注释,并且注释会在该命令的输出中直观地突出显示。

如果你真的想在有注释的情况下替换每个提交的主题,你总是可以按照以下方式创建一个脚本:

for c in $(git rev-list HEAD)
do
    n=$(git notes show $c 2> /dev/null)
    m=$(git show --oneline $c|head -1)
    if [ -n "$n" ]
    then
       m=${m/ */ $n}
    fi
    echo $m
done

...但在我看来,这更难看。

【讨论】:

  • 您的简单解决方案可能就足够了。该脚本需要大量调整(颜色、有条件地使用寻呼机、仅在通过标签留下装饰时替换日志消息等),目前这对我来说工作量太大。非常感谢。
猜你喜欢
  • 2021-02-15
  • 2012-05-01
  • 1970-01-01
  • 2012-01-28
  • 2015-12-04
  • 2017-09-09
  • 2021-04-28
  • 2011-05-02
  • 2013-01-01
相关资源
最近更新 更多