强制提交在提交时有额外的 parents

Force a commit to have additional parents upon commit

这与我的另一个问题有关:Can't make a replacement ref "permanent"。需要明确的是,无论出于何种原因,git replace --graftgit filter-branch 结合使用都不起作用。

我需要合并三个分支,但 octopus 合并失败(文件太不相似)所以我全部手动完成(git show branch:file > file 然后启动 meld)。然而,历史很重要,所以我需要记录 branch 是 parent。尽管我按照 man 文件和 Stackexchange 上其他地方的指示进行了操作,但我无法使替换 refs permentant (filter-branch) 我寻求替代方案。

从我现有的问题可以看出,我的第一个想法是使用替换,但这并没有按预期工作(它们不是 "cemented")。同样 git graft 似乎不被建议。此外,如链接问题中所述,章鱼合并失败。浏览 git commit --help(手册页)一无所获。

请注意,我不是在询问向旧提交添加额外的 parent。我在尚未推送的分支的顶端,没有提交将此作为 parent.

通过在较低的层次上看这个(DO 提交究竟是如何发生的)我看到了一个可爱的网页:https://jwiegley.github.io/git-from-the-bottom-up/1-Repository/4-how-trees-are-made.html

所以答案是手工完成。

git add file
git write-tree
echo "commit message" | git commit-tree -p branch_A -p branch_B -p branch_C $hash-from-previous-step
git update-ref refs/heads/branch_A $hash-from-previous-step #note I'm on branch_A

瞧!然后我可以编写一个简单的 shell 命令,它将提交消息和其他两个分支作为输入(使用 HEAD 作为第一个父级)。

见鬼,我把它写成一行。

git add file && git update-ref refs/heads/branch_A $(echo "commit message" | git commit-tree -p branch_A -p branch_B -p branch_C $(git write-tree))
git replace --graft @ branch_A branch_B branch_C
git filter-branch

我在 scratch repo 中做任何大手术并推回我想要的结果,这样如果出现任何问题恢复就像走开一样简单:

git clone -sb somebranch . `mktemp -d`; cd $_
major surgery here
git push origin whatever
cd -

但是对于这种微不足道的事情,只要使用

就可以更容易地在本地进行并清除过滤器分支的引用备份
git filter-branch -f --setup exit

可能值得注意的是,所有这些归结为执行 中的操作并从签出的提交中获取提交消息。