假设我有多个提交,如下所示:
---A---B---C---D
\
E---F---G
\
H
现在假设我修改了对 B 的更改,创建提交 B'
B'
/
---A---B---C---D
\
E---F---G
\
H
如何将 B 的每个后代重新设置为 B' 的基础?
B'---C'---D'
/ \
---A---B E'---F'---G'
\
H'
在我的工作流程中,通常有多个分支指向这些后代提交,理想情况下我不会为每个分支执行 git rebase 命令。
在我之前的公司中,我们使用 Mercurial,在修改提交后,您可以运行“hg evolve”,它会将该提交的所有后代重新设置为新的基础。
有没有办法在 git 中用一个命令来做到这一点?我一直在尝试编写一个脚本来根据提交图(从
git rev-list --children --all
解析)递归地挑选所有后代,但感觉必须有一种更简单的方法。
使用实验性功能
git replay
(从v2.44开始提供),您可以使用以下内容创建一个名为git-evolve
的bash脚本(已成功测试)(警告我不是shell专家,语法不漂亮):
#git replay --onto B' B..D B..G B..H | git update-ref --stdin
oldCommit=$1
newCommit=$2
if [ -n "$oldCommit" ] && [ -n "$newCommit" ] ; then
echo "original commit: $oldCommit / amended new commit: $newCommit"
else
echo "Input missing!! => original commit: $oldCommit / amended new commit: $newCommit"
exit 128
fi
replayCommand="git replay --onto $newCommit" #
branches=$(git branch --format="%(refname:short)" --contains $1)
echo "Will replay branches: $branches"
while IFS= read -r branch; do
# echo "branch: $branch"
replayCommand="$replayCommand $oldCommit..$branch"
# echo "cmd: $replayCommand"
done <<< "$branches"
echo "cmd: $replayCommand"
$replayCommand | git update-ref --stdin
并这样称呼它:
git-evolve B_HASH B'_HASH
这将变基/重播包含 B 提交的所有本地分支。
余数:
git replay
不管理冲突(也许应该改进脚本来管理冲突)