如何使用更改的提交消息准确地重播 git 分支历史记录?

How to exactly replay a git branch history with changed commit messages?

我有一个分支,我想在其中更改一堆提交消息。我不在乎改写历史。该分支有很多变化,因此将其重新设置在 master 之上是不切实际的(许多提交有很多冲突,需要数周才能解决)。

我想要的是(假设到目前为止的历史是一致的,并且合并是从 master 那里使用的)基本上是挑选在分支上完全按顺序完成的所有提交和合并,偶尔修改提交消息.基本上从头开始重新创建它并强制推送。

我认为 git rebase --interactive --preserve-merges (first commit)^ 会做到这一点;但是,完成后,在重做合并时仍然会遇到冲突。这是为什么?合并是在完全相同的分支状态下完成的,并且来自完全相同的提交(曾经是 master 的 HEAD),并且合并提交包括冲突解决,那么为什么会发生冲突?我错过了什么吗?

交互式变基仍然必须执行 合并。它不能只采用原始合并的树,因为(据它所知)您正在进行其他更改以更改合并结果。

因为你不是实际改变树,只有消息,git附带的命令可以做你想做的事1git filter-branch.

您想要的过滤器是 "message filter" (--msg-filter)。棘手的部分是提出一个只影响您想要影响的提交的过滤器。没有单一的方法可以做到这一点,但一个选择是编写一个 shell 脚本来检查 $GIT_COMMIT 与一组 "new" 消息,例如:

#! /bin/sh
new_msg_dir=/absolute/path  # we don't know $cwd during a msg-filter
if [ -f "$new_msg_dir/$GIT_COMMIT" ]; then
    cat "$new_msg_dir/$GIT_COMMIT"
else
    cat
fi

当且仅当有替换消息时,它会自动将标准输入内容(原始消息)替换为文件内容(来自提交 ID 命名的文件)。

显然这都是未经测试的。


1嗯,差不多就是你想要的了。加上比您想要的更多的东西,这让编写脚本以完全按照您的意愿行事变得非常有趣2

2或其他词。