重写历史以收敛两个孤儿树

时间:2015-03-03 20:54:34

标签: git

我有一个如下所示的存储库:

enter image description here

这些是同一存储库中的两个孤立树。

提交 B 是通过修改提交 A 创建的(但这不是由git记录的)

提交 C 的更改是手动(逐个文件编辑)合并到左侧树中创建提交 D (再次,不是由git记录)。

现在我想要合并 E F

如何重写历史记录(或任何其他方法),以便这种合并以及树之间的任何后续合并都是自动的?

1 个答案:

答案 0 :(得分:1)

你可以使用“移植物”临时重新连接祖先,并git filter-branch将其锁定。这里,

echo `git rev-parse $B $A` >> .git/info/grafts        # $B etc are shas or however
echo `git rev-parse $D $B $C` >> .git/info/grafts     # you want to refer to the commits

告诉这个特殊的回购表现就像A被列为B的第一个父母一样,并且好像D有父母的B和C.然后你可以进行合并,git会找到正确的合并库。此时只删除grafts文件是一个选项,因为可能没有多少回头并重写先前的提交祖先,因为你有一个正确的合并基础,以便将来的工作,但如果重写是一个选项,你git filter-branch -- --all将应用您列出的所有移植物。

在临时仓库中执行此操作,以便您可以进行实验:

git clone -s . $TMPDIR/foo
cd !$
mkdir .git/info

# do the echoes above here, then
git log --graph --decorate --oneline --all
# will show you that this repo sees the grafted ancestry links.

git filter-branch -- --all

它将弹出消息,显示哪些引用被移动到重写的历史记录,哪些不是。

退出程序如果出现任何问题,请回到原始仓库并擦除克隆。任何事情都是正确的,强制将重写推回到你的主仓库(如果在那里检查了重写的分支,你必须首先从你的HEAD中分离出来,cd -; git checkout @^0; cd -; git push etc; cd -; git checkout @{-1})。