让我这样描述你的情况:你有合并result你想要——源树——但不是history你希望这会导致这个结果。
As VonC已将其放在其他地方 https://stackoverflow.com/a/5203843/1256452,而你自己也尝试过,git reset --soft
通常is答案。您进行软重置,然后进行新的提交。如果你能做一个merge在这一点上提交,它仍然是答案。
有三种简单的方法可以做到这一点,无需git rerere
。一种是作弊,其中一种方法是“有记录的作弊”,因此可能是正确的方法。 (我最喜欢的方法是中间一种,因为它又短又甜,但它显然是作弊,所以有一天它可能会停止工作。)
方法 1:笨重,但使用所有常规工具(没有作弊)
请注意,此处的命令序列假设您位于存储库的顶层(特别是git rm
and git checkout
以下步骤参考.
意为“一切”)。我也用$startpoint
对于您想要合并之后的提交,以及$other
引用另一个分支名称或提交 ID(您想要的那个)git merge
).
-
保存最终结果的ID(我们想要tree,但是标准工具可以最简单地引用提交,这也可以正常工作):
$ git tag temp-save-result
(或者使用剪切和粘贴或引用日志来保存它;为了简单起见,我在这里显示了一个标签)。
-
重置。这也可能是--hard
, 而不是--soft
:
$ git reset --hard $startpoint
-
运行合并,这将因冲突而失败。忽略冲突和删除整个索引和工作树。到目前为止,我们不希望有冲突的合并或任何临时结果,因为我们有proper其他地方的结果。
$ git merge $other
$ git rm -r .
(如果您有一些自定义合并工具留下了粪便,您可能也想将它们从工作树中清除,尽管它们不会影响任何重要的事情:它们只会弄乱您的工作树)。
-
提取步骤 1 中保存的工作树,并提交结果:
$ git checkout temp-save-result -- .
$ git commit
这次提交结束了合并,其tree来自您在步骤 1 中保存的树。您现在可以删除该标签:
$ git tag -d temp-save-result
方法二:作弊
When git commit
进行新的提交,如果满足以下条件,则进行合并提交.git/MERGE_HEAD
存在。这MERGE_HEAD
文件包含第二次提交的 ID,即other or remote or --theirs
正在被合并。
因此,我们只需像往常一样进行软重置,然后添加合并 ID,然后提交。 (注意:我最近没有尝试过这个,Git 可能也想要.git/MERGE_MSG
。做好需要调整作弊的准备,或者直接转向方法 3。)
$ git reset --soft $startpoint
$ git rev-parse $other > .git/MERGE_HEAD
$ git commit
第一个命令就是我们平常使用的git reset --soft
步骤,第二步对 Git 撒谎说我们正在解决冲突的合并(并且索引已全部解决,因此我们必须完成该步骤),并且git commit
现在提交合并。
方法 3:使用管道命令(“有记录的作弊”)
生成实际提交对象的命令 -git commit
毫无疑问,曾经只是一个在接近尾声时运行的 shell 脚本——是git commit-tree
。这个需要:
- 包含所需树的树对象
- 一条提交消息(它将从标准输入读取一条消息,但您可能应该使用
-m
or -F
)
- 新提交的父级 ID
它将新的提交对象写入存储库,并打印出该对象的哈希 ID。
We 已经有那个树!由于它是当前提交,因此它的 ID 是HEAD^{tree}
(using gitrevisions syntax https://www.kernel.org/pub/software/scm/git/docs/gitrevisions.html)。我们也有两个家长 ID。我们所需要的只是消息:
$ tmp=$(git commit-tree -p $startpoint -p $other -m 'merge msg' HEAD^{tree})
一旦我们有了提交 ID,我们只需要git reset --hard
我们当前的分支指向它:
$ git reset --hard $tmp
(当然,您可以使用以下命令将两者合并为一个大命令$(...)
代替$tmp
在第二个命令中,尽管这假设您git commit-tree
命令将起作用:为了个人舒适度,最好执行两个步骤。您可以省略$tmp
变量,以及相应的shell$(...)
语法,如果您更喜欢的话,可以通过剪切和粘贴哈希 ID 来实现。而且,您可以放入一条俗气的临时提交消息,然后使用git commit --amend
一旦你重置它:--amend
选项也适用于合并提交。)