我知道两种在 git 中更改提交消息的方法。
第一个是
git amend
,仅适用于最新的提交。因为我希望能够直接更改旧的提交消息,所以这不是我想要的。
第二个是交互式变基,例如,如本answer中所述,它也可以更改旧提交的提交消息。程序是使用
git rebase -i HEAD~n
对于我的具体情况,我必须手动计算
n
有多大,然后滚动浏览所有这些提交的列表,并将一个提交从 pick
更改为 reword
,最后键入新的提交消息并强制推。
老实说,虽然这可行,但这样做非常复杂和乏味。所以我的问题是,是否有一种更易于使用的选项(可能以别名的形式),可以一步自动执行此过程?
理想情况下,我想要这样的命令:
git reword <hash> -m "New commit message"
然后用力推动即可。这可能吗?
编辑:我想摆脱交互性,因为我想以编程方式自动化程序中的一些 git 命令。在此过程中必须手动与 git 交互,这违背了这种自动化的目的。
您可以在目标提交之前直接引用修订版本,而不是从 HEAD 手动倒数提交。奔跑吧
$ git rebase -i <rev>^
其中
<rev>
是您要重写的提交。
从那里,您仍然需要手动完成变基(将目标行更改为
reword
并运行git rebase --continue
)。您可以通过巧妙的 shell 脚本和GIT_SEQUENCE_EDITOR
的某种组合进一步自动化该过程,但我不确定我是否会建议这样做。 Rebase 是 git 中一项极具侵入性的操作。拥有即将在屏幕上短暂重写 Flash 的历史记录,并有机会中止 是一件好事,并且可能会为您节省很多眼泪和 git reflog
几个小时。
我喜欢明确我所采取的步骤,尤其是对于“破坏性”操作,例如变基。考虑到这一点,通过利用
GIT_SEQUENCE_EDITOR
变量,你所追求的绝对是可能的。它定义了用于编辑交互式变基的“待办事项列表”的“编辑器”。编辑器不必是交互式编辑器,可以是修改文本文件的任何可执行文件,sed
就是一个例子:GIT_SEQUENCE_EDITOR='sed -i "1s/^pick/reword/"' git rebase -i commit-you-want-to-amend^
当变基直到您要修改的提交的父级时,该提交将是列表中的第一个,您可以使用简单的 sed 脚本轻松地将
pick
切换到
reword
。整个事情可以轻松转换为别名:
git config --global alias.reword '!f() {
GIT_SEQUENCE_EDITOR="sed -i 1s/^pick/reword/" git rebase -i "$1^";
}; f'
然后
git reword commit-you-want-to-amend
。
上面仍然需要你手动输入commit message。如果您也想避免这种情况,使用GIT_EDITOR
进行巧妙的破解可以帮助您:
git config --global alias.reword '!f() {
GIT_SEQUENCE_EDITOR="sed -i 1s/^pick/reword/" GIT_EDITOR="printf \"%s\n\" \"$2\" >" git rebase -i "$1^";
}; f'
注意
>
值中的标准输出重定向
GIT_EDITOR
。然后拨打 git reword commit-you-want-to-amend 'your new commit message'
。
第二个选项可以使用来保留原始提交,但使用 Git 的replace refs 来显示不同的提交。
git commit --fixup=reword:commit
:
--fixup=[(amend|reword):]<commit>
创建一个新的提交,在应用
<commit>
时“修复”
。 […]git rebase --autosquash
创建了一个 “修正!”提交,将--fixup=reword:<commit>
的日志消息替换为其 自己的日志消息,但不更改<commit>
的内容。[…]<commit>
--fixup=reword:<commit>
是
的简写。它创建了一个“修正!”仅使用日志消息提交(忽略索引中暂存的任何更改)。当被--fixup=amend:<commit> --only
压扁时,它会替换git rebase --autosquash
的日志消息 无需进行任何其他更改。 因此,您将运行以下命令:<commit>
git commit --fixup=reword:commit-to-amend
git rebase -i --autosquash commit-to-amend^
但这不允许通过 CLI 参数指定提交消息,因此我们需要通过制作 autosqash 所需的正确提交消息来模仿 Git 的行为:
git config alias.reword2 '!f() {
git commit --allow-empty --only -m "amend! $1
$2" &&
GIT_SEQUENCE_EDITOR=: git rebase -i --autosquash "$1^";
}; f'
然后用
git reword commit-to-amend 'your new message'
执行。