在 Git 中重新进行恢复合并

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1078146/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 06:40:50  来源:igfitidea点击:

Re-doing a reverted merge in Git

gitgit-mergegit-revert

提问by Toms Mikoss

I have run into a bit of a problem here: I had a problem-specific branch 28sin Git, that I merged in the general developbranch. Turns out I had done it too fast, so I used git-revert to undo the merge. Now, however, the time has come to merge 28sinto develop, but git-merge command sees the original merge, and happily announces that all is well and branches have been already merged. What do I do now? Create a 'Revert "Revert "28s -> develop"" ' commit? Doesn't seem to be a good way to do it, but I can't imagine any other at the moment.

我在这里遇到了一些问题:我28s在 Git 中有一个特定于问题的分支,我将它合并到了通用develop分支中。事实证明我做得太快了,所以我使用 git-revert 来撤消合并。然而,现在是时候合并28s到 了develop,但是 git-merge 命令看到了原来的合并,并高兴地宣布一切顺利,分支已经合并。现在我该怎么做?创建一个'Revert“Revert”28s -> develop“”'提交?似乎不是一个好方法,但我目前无法想象其他任何方法。

What the tree structure looks like:

树结构是什么样的:

Git log output

Git日志输出

采纳答案by J-16 SDiZ

You have to "revert the revert". Depending on you how did the original revert, it may not be as easy as it sounds. Look at the official document on this topic.

您必须“还原还原”。根据您原始版本的还原方式,它可能不像听起来那么容易。查看有关此主题官方文档

---o---o---o---M---x---x---W---x---Y
              /
      ---A---B-------------------C---D

to allow:

允许:

---o---o---o---M---x---x-------x-------*
              /                       /
      ---A---B-------------------C---D

But does it all work? Sure it does. You can revert a merge, and from a purely technical angle, git did it very naturally and had no real troubles.
It just considered it a change from "state before merge" to "state after merge", and that was it.
Nothing complicated, nothing odd, nothing really dangerous. Git will do it without even thinking about it.

So from a technical angle, there's nothing wrong with reverting a merge, but from a workflow angle it's something that you generally should try to avoid.

If at all possible, for example, if you find a problem that got merged into the main tree, rather than revert the merge, try reallyhard to:

  • bisect the problem down into the branch you merged, and just fix it,
  • or try to revert the individual commit that caused it.

Yes, it's more complex, and no, it's not always going to work (sometimes the answer is: "oops, I really shouldn't have merged it, because it wasn't ready yet, and I really need to undo allof the merge"). So then you really should revert the merge, but when you want to re-do the merge, you now need to do it by reverting the revert.

但这一切都有效吗?当然可以。您可以恢复合并,从纯技术角度来看,git 非常自然地做到了,没有真正的麻烦。
它只是认为它是从“合并前的状态”到“合并后的状态”的变化,仅此而已。
没有什么复杂的,没有什么奇怪的,没有什么真正危险的。Git 会不假思索地去做。

因此,从技术角度来看,恢复合并没有错,但从工作流程角度来看,您通常应该尽量避免

如果可能的话,例如,如果发现得到了合并到主树,出了问题,而不是撤销的合并,尽量真的很难

  • 把问题分成你合并的分支,然后修复它,
  • 或者尝试恢复导致它的单个提交。

是的,它更复杂,不,它并不总是去上班(有时,答案是:“哎呀,我真不应该把它合并,因为当时还没有准备好,我真的需要撤消所有的合并”)。那么你真的应该还原合并,但是当你想要重新进行合并时,你现在需要通过还原还原来完成。

回答by Maksim Kotlyar

Let's assume you have such history

让我们假设你有这样的历史

---o---o---o---M---W---x-------x-------*
              /                      
      ---A---B

Where A, B failed commits and W - is revert of M

其中 A、B 提交失败,W - 恢复为 M

So before I start fixing found problems I do cherry-pick of W commit to my branch

所以在我开始修复发现的问题之前,我会挑选 W 提交到我的分支

git cherry-pick -x W

Then I revert W commit on my branch

然后我在我的分支上恢复 W 提交

git revert W 

After I can continue fixing.

之后我可以继续修复。

The final history could look like:

最终的历史可能如下所示:

---o---o---o---M---W---x-------x-------*
              /                       /     
      ---A---B---W---W`----------C---D

When I send a PR it will clearly shows that PR is undo revert and adds some new commits.

当我发送 PR 时,它会清楚地显示 PR 是撤消还原并添加了一些新的提交。

回答by Sam Dufel

To revert the revert without screwing up your workflow too much:

要在不过多破坏工作流程的情况下还原还原:

  • Create a local trash copy of develop
  • Revert the revert commit on the local copy of develop
  • Merge that copy into your feature branch, and push your feature branch to your git server.
  • 创建一个开发的本地垃圾副本
  • 在开发的本地副本上还原还原提交
  • 将该副本合并到您的功能分支中,并将您的功能分支推送到您的 git 服务器。

Your feature branch should now be able to be merged as normal when you're ready for it. The only downside here is that you'll a have a few extra merge/revert commits in your history.

当您准备好时,您的功能分支现在应该能够正常合并。这里唯一的缺点是您的历史记录中会有一些额外的合并/恢复提交。

回答by Richard

To revert a revert in GIT:

要在 GIT 中还原还原:

git revert <commit-hash-of-previous-revert>

回答by knweiss

Instead of using git-revertyou could have used this command in the develbranch to throw away(undo) the wrong merge commit (instead of just reverting it).

而不是使用的git-revert,你可以在已经使用这个命令devel分支扔掉(撤消)错误的合并提交(而不仅仅是恢复它)。

git checkout devel
git reset --hard COMMIT_BEFORE_WRONG_MERGE

This will also adjust the contents of the working directory accordingly. Be careful:

这也将相应地调整工作目录的内容。小心

  • Save your changesin the develop branch (since the wrong merge) because they too will be erased by the git-reset. All commits after the one you specify as the git resetargument will be gone!
  • Also, don't do this if your changes were already pulled from other repositories because the reset will rewrite history.
  • 将您的更改保存在开发分支中(由于错误的合并),因为它们也会被git-reset. 在您指定为git reset参数之后的所有提交都将消失!
  • 此外,如果您的更改已经从其他存储库中提取,请不要这样做,因为重置将重写历史记录。

I recommend to study the git-resetman-page carefully before trying this.

我建议git-reset在尝试之前仔细研究手册页。

Now, after the reset you can re-apply your changes in develand then do

现在,重置后您可以重新应用您的更改devel,然后执行

git checkout devel
git merge 28s

This will be a real merge from 28sinto devellike the initial one (which is now erased from git's history).

这将是一个真正的融合28sdevel像最初的一个(现在是从Git的历史擦除)。

回答by Claire

I just found this post when facing the same problem. I find above wayyy to scary to do reset hards etc. I'll end up deleting something I don't want to, and won't be able to get it back.

当我遇到同样的问题时,我刚刚找到了这篇文章。我发现上面的方式很可怕,重置硬盘等。我最终会删除我不想删除的东西,并且无法取回它。

Instead I checked out the commit I wanted the branch to go back to e.g. git checkout 123466t7632723. Then converted to a branch git checkout my-new-branch. I then deleted the branch I didn't want any more. Of course this will only work if you are able to throw away the branch you messed up.

相反,我检查了我希望分支返回到 eg 的提交git checkout 123466t7632723。然后转换为分支git checkout my-new-branch。然后我删除了我不再想要的分支。当然,这只有在你能够扔掉你搞砸的分支时才有效。

回答by Venkataraman R

I would suggest you to follow below steps to revert a revert, say SHA1.

我建议您按照以下步骤还原还原,例如 SHA1。

git checkout develop #go to develop branch
git pull             #get the latest from remote/develop branch
git branch users/yourname/revertOfSHA1 #having HEAD referring to develop
git checkout users/yourname/revertOfSHA1 #checkout the newly created branch
git log --oneline --graph --decorate #find the SHA of the revert in the history, say SHA1
git revert SHA1
git push --set-upstream origin users/yourname/revertOfSHA1 #push the changes to remote

Now create PR for the branch users/yourname/revertOfSHA1

现在为分支创建 PR users/yourname/revertOfSHA1

回答by Misha Mostov

  1. create new branch at commit prior to the original merge - call it it 'develop-base'
  2. perform interactive rebase of 'develop' on top of 'develop-base' (even though it's already on top). During interactive rebase, you'll have the opportunity to remove both the merge commit, and the commit that reversed the merge, i.e. remove both events from git history
  1. 在原始合并之前提交时创建新分支 - 将其称为“develop-base”
  2. 在'develop-base'之上执行'develop'的交互式rebase(即使它已经在上面)。在交互式 rebase 期间,您将有机会删除合并提交和反转合并的提交,即从 git 历史记录中删除这两个事件

At this point you'll have a clean 'develop' branch to which you can merge your feature brach as you regularly do.

此时,您将拥有一个干净的“开发”分支,您可以像往常一样将功能分支合并到该分支。