使用 git rebase,有没有办法使用默认命令重写 git-rebase-todo 中的提交消息?

With git rebase, is there a way to reword commit messages in the git-rebase-todo using the default commands?

假设我运行git rebase -i HEAD~3

pick 6b24464 foo
pick a681432 Foo
pick 8ccba08 foo foo

# Rebase 960c384..8ccba08 onto 960c384
#
# 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

我想直接从这个文件改写提交消息,而不是一次编辑每条提交消息(按照 reword 的惯例),像这样:

reword 6b24464 foo bar
reword a681432 Foo Bar
reword 8ccba08 foo foo bar bar

# Rebase 960c384..8ccba08 onto 960c384
#
# 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

我曾希望仅使用 rewordedit 即可完成此操作,但我似乎无法弄清楚如何(如果可能的话)。我已经能够通过

获得相同的结果
x git cherry-pick 6b24464 && git commit -amend "foo bar"

但是,这比我希望的大型变基更耗时。有什么想法吗?

我不相信可以做到,因为当您执行 git rebase -i 时,您只会得到每个提交消息的第一行,而不是完整的提交消息。

作为惯例,提交消息的第一行应该只是一个摘要,并在接下来的几行中包含有关更改的更多详细信息。 Here's Linus Torvalds on how to write a proper commit message

Also, please write good git commit messages. A good commit message looks like this:

Header line: explain the commit in one line (use the imperative)

Body of commit message is a few lines of text, explaining things
in more detail, possibly giving some background about the issue
being fixed, etc etc.

The body of the commit message can be several paragraphs, and
please do proper word-wrap and keep columns shorter than about
74 characters or so. That way "git log" will show things
nicely even when it's indented.

Make sure you explain your solution and why you're doing what you're
doing, as opposed to describing what you're doing. Reviewers and your
future self can read the patch, but might not understand why a
particular solution was implemented.

Reported-by: whoever-reported-it
Signed-off-by: Your Name <youremail@yourhost.com>

where that header line really should be meaningful, and really should be just one line. That header line is what is shown by tools like gitk and shortlog, and should summarize the change in one readable line of text, independently of the longer explanation. Please use verbs in the imperative in the commit message, as in Fix bug that..., Add file/feature ..., or Make Subsurface...

因此,即使您可能每次提交只完成一行消息,但这并不是 git 所假设的,因此它不会让您通过“每行一行”来编辑提交消息提交视图。

不,您不能在变基 TODO 文件中改写消息。

这样做的原因:Git 正在从上到下应用变基。 TODO 文件只告诉 Git 以什么顺序执行 rebase 操作,以及它的操作是什么(压缩、改写、使用、修复等)。然后它依靠其他机制(如 commit)来处理其余部分。

如果您有很多次要改写,您会收到很多提示来编辑消息,这是您应该期待的;您正在创建一个带有新消息的新提交 [regardless],因此 Git 应该要求您在处理 rebase 操作的过程中输入它。

我强烈建议不要进行大型变基操作,因为它会导致这种平凡的事情,而且它有可能变得比它的价值更危险。

您或许可以使用 exec 选项来实现您想要的效果。

使用类似于 git commit --amend -m "this is the new message"

的执行命令

您可以直接使用它,或者如果您需要更复杂的功能,请将它放在名为 my_reword.

的外部脚本中
#!/bin/sh
git commit --amend -m ""

然后在 exec 行中任意添加

pick 6b24464 foo
pick a681432 Foo
x my_reword "this is a new message"
pick 8ccba08 foo foo

添加到我的 .gitconfig:

[alias]
    w = "!reword() { git commit --amend -m \"\"; }; reword"

然后,x git w "..."只是

据我所知,人们通常也将别名命名为ca...

一个改进的解决方案,支持更自然的语法。基于@AndrewC 的工作。

pick 7c88fde9
x reword Integrated database module
pick 23b35c34 fix this and that
x reword 'configuration reads ${HOME} now'

将此脚本保存为 "reword" 可执行文件,路径为:

#!/bin/sh
# In the git rebase todo list, directly reword commits. Save this script as "reword", executable, in the path.
# The message can be written literal or as one argument in double quotes. Use single quotes to not interpret ${HOME} `uname` etc.
git commit --amend -m "$*"