首页 > 解决方案 > 在 Git 中,如何在分支上进行新提交,其树等于另一个提交的树

问题描述

我有一个情况

...--x--y--z   master

...--a--b--c  someOtherBranch

我想在主分支上进行新的提交,它只是将文件树更改为看起来像 someOtherBranch 的树。即,我想进入一个状态

...--x--y--z--c1 master

...--a--b--c  someOtherBranch

其中 commitc1有一个文件树,看起来就像c. (这大概意味着它是完全相同的文件树对象。)

我怎样才能做到这一点?

我知道这会在 z 和 c1 之间造成潜在的大且不受欢迎的不连续性。

标签: git

解决方案


完全不清楚为什么要这样做(通常的原因包含在 中git merge -s ours,它会进行合并提交而不是单父提交),但是很容易做到,使用git merge --squash -s ours后跟git commit使用git commit-tree. 编辑-s ours来自 master 会保留错误的树(z而不是c)。可以使用它,但前提您想要合并提交。请参阅下面的部分。

(下面的所有命令都假设您master现在处于打开状态。)

要使用git commit-tree,您必须提供一些额外的参数,这需要更多设置:

hash=$(git commit-tree -p HEAD -F /tmp/commit-msg someOtherBranch^{tree})

例如,将提交消息存储在文件中/tmp/commit-msg。生成的哈希 ID 是一个新的提交对象,它还没有在任何分支上,但现在很容易“快进合并”到:

git merge --ff-only $hash

git reset到:

git reset --hard $hash

正如John Szakmeister 所评论的,您还可以使用git checkout将另一个提交的索引和工作树覆盖到您当前的索引中。git rm如果你有一个名为的文件README并且它们没有 a README,只有 a ,你应该首先做所有事情README.md

或者您可以使用它git read-tree来执行此操作,我认为这更简单:

git read-tree -m -u someOtherBranch; git commit

(不需要^{tree}这里,因为它git read-tree会自行解决对树的提交)。

如果你真的想要合并

在设置真正的合并后,也可以使用读取树(或删除并签出)技巧,使用git merge -s ours. 那是:

git merge -s ours someOtherBranch
git read-tree -m -u someOtherBranch
git commit

将为将保留的合并做准备z,然后用 from 替换索引和工作树,然后进行树匹配c的新提交,而不是:c1cz

...--x--y--z--c1   <-- master
             /
...--a--b---c   <-- someOtherBranch

推荐阅读