git - rebase 后如何更新提交消息中的 SHA1?

标签 git rebase

考虑这段历史:

E  BUG: fix regression in <sha-1 of C>
|
D  fixup! Do a thing
|
C  Add a feature
|
B  Do a thing
|
A  Initial commit

是否有 git rebase -i --autosquash 的变体可以调整 E 的提交消息以匹配以下内容?

E'  BUG: fix regression in <sha-1 of C'>
|
C'  Add a feature
|
BD' Do a thing
|
A   Initial commit

最佳答案

我真的想不出一种自动化的方法。在交互式 rebase 中,您可以将提交 E 标记为“reword”或“edit”,并自行更改 SHA。 (我认为“编辑”可能更容易,这样您就可以在启动提交消息编辑器之前使用 log 找到要填写的正确 SHA。)

更新

从评论中引入一些想法:如果您正在处理包含许多此类引用的大型历史记录的重写,因此使用手动消息编辑进行交互式 rebase 是不现实的,那么设想解决方案要困难得多。

虽然您的问题似乎集中在rebase上,但在评论中您提到您可能真的在考虑filter-branch。 (应该指出的是,这是一种非常不同的操作,因此用一个操作替换另一个操作几乎从来都不是一件容易的事......)

在任何情况下,最好的选择是在导致提交 SHA 值更改的同一操作中重写提交消息。 (如果您尝试“事后”执行此操作,那么重写提交 X 的消息将再次更改不仅 X,还有通过父指针到达 X 的任何提交;因此您必须在此时跟踪/处理多个 ID 映射。)

理论上,您想要的是一个 msg-filter,它对 SHA 值执行 sed 类型的搜索和替换;但问题是你在哪里获得“旧 sha 到新 sha”映射。

有一个 shell 函数 map,torek 指出它可以提供一些帮助,至少在过滤器脚本中是这样。 (我发现的文档仅确认它在执行 commit-filter 期间可用,但如果 torek 说其他过滤器可以看到它,那么我倾向于认为他是对的。问题是如果确实没有记录的话,这是否会在未来版本中发生变化。如果这让您担心,您可以将消息编辑硬塞到提交过滤器中,也许......)

因此,您可以编写一个脚本来查看旧的提交消息(如果您坚持使用 msg-filter,则在 STDIN 上收到)并在其中搜索可能的 SHA 值([0 中的 40 个字符的字符串] -9a-f])。找到可能的值时,它将调用 map,如果 map 返回看起来像单个 SHA 值的值,则编辑消息文本。然后在 STDOUT 上返回编辑后的文本。 (但是:我相信只有当您的提交消息中确实包含完整的 40 个字符的 SHA 时,这才有效。如果您缩写,那就是另一堆蠕虫......)

(请注意,map可以返回多个 SHA 值,但我发现的唯一情况是,如果您使用 commit 执行一些奇怪的操作-过滤器。)

关于git - rebase 后如何更新提交消息中的 SHA1?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44570856/

相关文章:

git rebase "--preserve-merges --onto"不保留 merge

Github + Jenkins >> 如何在代码库中触发 "Commit and Push"上的构建?

git 和 CR 与 LF(但不是 CRLF)

Git rebase : do I have to have a clean working directory first?

git - 将分离的 HEAD rebase 到 master 分支

git - 使用 autosquash 重新定位不能按预期工作

git - `go get` 和 `git clone` 之间的区别?

git - Visual Studio 2015 : Git Diff Tool Window is empty

git - 如何从不同分支上的本地提交复制文件?

git - 用 Git 重命名 : Using git mv vs deleting a file and adding another