将分支的祖先提交合并回到HEAD

时间:2020-01-19 00:02:30

标签: git

我有这样的提交历史。我计划应用该解决方案的实际仓库更大。尽管如此,它看起来像这样:

enter image description here

简单来说,我想做的就是将experiment合并到master分支中。这个想法是做一个reset而不丢失我在master分支中的提交。我没有使用revert,因为在实际回购中,masterexperiment之间的提交量比上面的图片还要多。完成merge之后,我只想仅查看experiment中的更改:因此,工作目录在执行以下命令后看起来像:{{1中的git checkout master; git reset --hard experiment }}分支。

由于master分支已经存在于experiment分支的历史中,因此我在运行以下命令时收到通知master

"Already up to date."

我尝试了git checkout master git merge experiment -X theirs --squash 选项,但是只要它能满足我的需要,我就可以接受其他方法。我感谢所有答案。

根据Kaz的答案更新#1:

Kaz的回答很好,但似乎缺少了关键的内容。下图显示了我使用他/她建议的答案后的历史演变:

enter image description here

如您所见,最后的merge不会更改commit而是会创建一个分离的提交。

解决方案是将其转换为分支,然后将该分支合并回master,如下所示:

enter image description here

2 个答案:

答案 0 :(得分:3)

如果您要对母版进行第5版修订,其内容与第二版完全相同,这是可行的方法:

envp

答案 1 :(得分:2)

一个非常简单的方法就可以使分支看起来像是自己的某些旧版本:

在这里,我们假设我们从master开始;如果不是,那么首先需要git checkout master

git tag starting-point                 # save our current location
git reset --hard old-commit-on-master  # hard-reset master to old commit
git reset --soft master starting-point # soft-reset master back to start
git tag -d starting-point              # optional: tidy up

现在您的工作树+索引看起来像old-commit-on-master,但是您在master上。使master看起来像old-commit-on-master的所有更改都已分阶段进行-您可以使用git diff --cached进行检查。剩下要做的就是:

git commit

而且,也许您可​​能希望清除starting-point标签:

git tag -d starting-point

之所以可行,是因为第一个git reset --hard使工作树看起来像old-commit-on-master,而我们停留在master上是因为我们实际上已经将master移到了该提交。然后,第二个git reset因为指定了--soft,所以在将master引用移回原处的同时保留了树。因此,就Git而言,历史没有改变。非常简单,可以从git reset手册页中了解。

但这不是合并;它只有一个父对象:上一个master提交。我会在提交评论中提到,这是old-commit-on-master之后到直接父级的所有内容的还原。

注意:我没有在需要添加或删除文件的情况下对此进行过测试。希望他们能正确上演。

请注意,如果您使用git reset而不是git reset --soft,则会得到默认的--mixed,结果会有所不同。更改不会被暂存,但会显示为与master HEAD的未暂存差异。我怀疑如果没有手动git add干预,可能无法处理文件添加。