[英]Git revert in master reverting commits when merged into feature branch
I have been developing a major, long-term feature on a separate branch, big-feature
.我一直在一个单独的分支big-feature
上开发一个主要的、长期的特性。 During its development, I have also been making smaller unrelated updates on master
(well, technically I have been making the smaller updates on their own branches from master
and then merging them into master
.)在其开发过程中,我也一直在对master
进行较小的无关更新(从技术上讲,我一直在从master
对他们自己的分支进行较小的更新,然后将它们合并到master
。)
Each time I complete some changes to master
, I have been in the habit of also merging master
into big-feature
so that the feature branch doesn't stray too far from master
and the merge will be hopefully easier when the big feature is complete.每次完成对master
的一些更改时,我一直习惯于将master
合并到big-feature
中,这样功能分支不会偏离master
太远,并且希望在 big feature 完成后合并会更容易。
However, after some recent work, I accidentally merged big-feature
into master
.但是,在最近的一些工作之后,我不小心将big-feature
合并到了master
中。 I attempted to rectify this with revert
, and indeed the previous code state seems to have been restored.我试图用revert
来纠正这个问题,实际上之前的代码 state 似乎已经恢复了。 However, I still see the full history of commits from big-feature
listed in the commit history of master
, plus a merge
and revert
at the top.但是,我仍然看到master
的提交历史中列出的big-feature
提交的完整历史,以及顶部的merge
和revert
。
The problem is, when I now make a small change on master
and attempt to merge master
into big-feature
, all of big-feature
's code reverts to that of master
.问题是,当我现在对master
进行小改动并尝试将master
合并到big-feature
时,所有big-feature
的代码都会恢复为master
的代码。 I can only guess that the revert
from master
is being merged into big-feature
and removing all the commits in big-feature
.我只能猜测master
的revert
被合并到big-feature
并删除了big-feature
中的所有提交。
Hopefully this is semi-coherent.希望这是半连贯的。
Questions:问题:
master
into big-feature
a bad idea?我定期将master
合并到big-feature
中的策略是一个坏主意吗? PS I also tried a hard reset
of master
to the commit before the erroneous merge, but this didn't remove all of the commits from big-feature
, which surprised me? PS我还尝试在错误合并之前将master
hard reset
为提交,但这并没有从big-feature
中删除所有提交,这让我感到惊讶吗?
I accidentally merged big-feature into master.我不小心将 big-feature 合并到 master 中。 I attempted to rectify this with revert我试图用 revert 来纠正这个问题
That's not how to undo a merge.这不是撤消合并的方法。
A revert is a whole new commit, which is artificially created in such a way as to add to the future history the negation of some commit that came before it.恢复是一个全新的提交,它是人为创建的,以便在未来的历史中添加对之前的某个提交的否定。
The way to undo the merge is to be on the branch you were on when you did the merge and simply reset --hard
back one commit, namely to the commit just before the merge commit.撤消合并的方法是在您进行合并时所在的分支上,然后简单地reset --hard
一次提交,即在合并提交之前的提交。 It has no name so you have to use HEAD~1
notation or use the SHA of that commit.它没有名称,因此您必须使用HEAD~1
表示法或使用该提交的 SHA。 The merge commit is thrown away, and presto, we are right back where we were before the merge.合并提交被丢弃,并且很快,我们就回到了合并之前的位置。
(You say you tried that, but you don't give the actual command that you gave, so there is no reason to think you gave the command correctly.) (你说你试过了,但你没有给出你给出的实际命令,所以没有理由认为你给出了正确的命令。)
In this example, I have created commits A, B, and C on master
and commit Z on feature
, and I have merged feature
into master
— you can tell that because (1) I am on master
, and (2) the merge commit is part of master
, not part of feature
:在这个例子中,我在master
上创建了提交 A、B 和 C 并在feature
上提交了 Z,我已经将feature
合并到master
中——你可以看出这是因为(1)我在master
上,以及(2)合并提交是master
的一部分,而不是feature
的一部分:
* a65559d (HEAD -> master) merge commit
|\
| * c6c9d90 (feature) Z
* | caa732e C
* | 11bbc44 B
|/
* 92e934a A
Note the SHA numbers.请注意 SHA 编号。 Let's say we regret this move.假设我们对这一举动感到遗憾。 So our goal is to delete a65559d
in such a way as to put master
back at caa732e
, where it was before we merged feature
.因此,我们的目标是删除a65559d
,以便将master
放回caa732e
,即我们合并feature
之前的位置。 We are currently on master
, so all we have to do is say:我们目前在master
上,所以我们要做的就是说:
git reset --hard caa732e
Result:结果:
* c6c9d90 (feature) Z
| * caa732e (HEAD -> master) C
| * 11bbc44 B
|/
* 92e934a A
Exactly what we wanted.正是我们想要的。
NOTE: This answer is only applicable if you are able to overwrite history.注意:仅当您能够覆盖历史记录时,此答案才适用。 You should only do it if you haven't pushed you changes to remote or if you know for a FACT that this won't affect other developers (eg there are none or you can communicate to everyone working on the project what you are about to do)只有在您没有将更改推送到远程或者您知道这不会影响其他开发人员的情况下才应该这样做(例如,没有或您可以与项目中的每个人交流您将要做什么做)
how do I fix this?我该如何解决?
I'm assuming that what happened when you merged big-feature
to master was a fast-forward merge .我假设当您将big-feature
合并到 master 时发生的事情是快进合并。
In that case, using git reset
to reset to some specific commit may not work as our commits from master
and big-feature
may have become mixed.在这种情况下,使用git reset
重置为某些特定提交可能不起作用,因为我们来自master
和big-feature
的提交可能已经混合。 Instead we can use git reflog
to find the state master
was in before we've made the merge and then reset master
to that state.相反,我们可以使用git reflog
来查找 state 在我们进行合并之前所在的master
节点,然后将master
节点重置为该 state。
git reflog master # Show the history of updates to the tip of master.
# Find the line that says "master{n}: merge big-feature: Fast-forward"
# and note the reference number n
git switch master # checkout master if necessary
git reset --keep master@{n+1} # Now reset master to the reference just before merge
Is my strategy of periodically merging master into big-feature a bad idea?我定期将大师合并到大功能中的策略是一个坏主意吗?
If, again, you can overwrite history I would recommend periodically rebasing your feature
branch on master
instead.如果再次,您可以覆盖历史记录,我建议您定期将您的feature
分支重新设置在master
上。 This gives you an advantage of having a clean history on your feature
branch, which makes interacting with the branch easier, including in cases like this.这为您提供了一个优势,即在您的feature
分支上拥有干净的历史记录,这使得与分支的交互更容易,包括在这种情况下。
I suspect that the problem here is that when you now merge master
into big-feature
, Git is pulling along that merge revert commit, which is then functionally undoing a bunch of your work which happened in big-feature
.我怀疑这里的问题是,当您现在将master
合并到big-feature
时,Git 正在拉动该合并还原提交,然后在功能上撤消了您在big-feature
中发生的一堆工作。 While there might be a more graceful way to handle this, an easy solution would be to just cherry pick the commits from master
which you want to also include in big-feature
:虽然可能有一种更优雅的方式来处理这个问题,但一个简单的解决方案是从master
中挑选您希望也包含在big-feature
中的提交:
# from big-feature
git cherry-pick ABCD
The above assumes that ABCD
is the SHA-1 hash of the commit in master
which has the minor fix which you want to bring into big-feature
.以上假设ABCD
是master
中提交的 SHA-1 hash,它具有您想要引入big-feature
的次要修复。
Using this approach is more work, because you need to figure out exactly which commit(s) need to come in, but it avoids the merge brute force approach which is no longer working for you.使用这种方法需要更多的工作,因为您需要准确地确定需要输入哪些提交,但它避免了不再适合您的合并蛮力方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.