撤消尚未推送的 Git 合并

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2389361/
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 07:58:45  来源:igfitidea点击:

Undo a Git merge that hasn't been pushed yet

gitundogit-merge

提问by Matt Huggins

Within my master branch, I did a git merge some-other-branchlocally, but never pushed the changes to origin master. I didn't mean to merge, so I'd like to undo it. When doing a git statusafter my merge, I was getting this message:

在我的 master 分支中,我在git merge some-other-branch本地做了一个,但从未将更改推送到 origin master。我不是想合并,所以我想撤消它。git status在我合并后做 a 时,我收到了这条消息:

# On branch master
# Your branch is ahead of 'origin/master' by 4 commits.

Based upon some instructions I found, I tried running

根据我发现的一些说明,我尝试运行

git revert HEAD -m 1

but now I'm getting this message with git status:

但现在我收到这条消息git status

# On branch master
# Your branch is ahead of 'origin/master' by 5 commits.

I don't want my branch to be ahead by any number of commits. How do I get back to that point?

我不希望我的分支领先于任何数量的提交。我如何回到那个点?

回答by Marcin Gil

With git reflogcheck which commit is one prior the merge (git reflogwill be a better option than git log). Then you can reset it using:

git reflog合并之前检查哪个提交是一个提交(git reflog将是比 更好的选择git log)。然后您可以使用以下方法重置它:

git reset --hard commit_sha

There's also another way:

还有一种方法:

git reset --hard HEAD~1

It will get you back 1 commit.

它会让你回到 1 次提交。

Be aware that any modified and uncommitted/unstashed files will be reset to their unmodified state. To keep them either stash changes away or see --mergeoption below.

请注意,任何已修改和未提交/未隐藏的文件都将重置为其未修改状态。为了让他们隐藏更改或查看--merge下面的选项。



As @Velmont suggested below in his answer, in this direct case using:

正如@Velmont 在他的回答中建议的那样,在这种直接情况下使用:

git reset --hard ORIG_HEAD

might yield better results, as it should preserve your changes. ORIG_HEADwill point to a commit directly before merge has occurred, so you don't have to hunt for it yourself.

可能会产生更好的结果,因为它应该保留您的更改。ORIG_HEAD将在合并发生之前直接指向提交,因此您不必自己寻找它。



A further tip is to use the --mergeswitch instead of --hardsince it doesn't reset files unnecessarily:

另一个提示是使用--mergeswitch 而不是--hard因为它不会不必要地重置文件:

git reset --merge ORIG_HEAD

--merge

Resets the index and updates the files in the working tree that are different between <commit> and HEAD, but keeps those which are different between the index and working tree (i.e. which have changes which have not been added).

- 合并

重置索引并更新工作树中 <commit> 和 HEAD 之间不同的文件,但保留索引和工作树之间不同的文件(即具有尚未添加的更改)。

回答by randomguy3

Assuming your local master was not ahead of origin/master, you should be able to do

假设你的本地主人没有领先于原点/主人,你应该能够做到

git reset --hard origin/master

Then your local masterbranch should look identical to origin/master.

那么您的本地master分支应该看起来与origin/master.

回答by Yuri Geinish

See chapter 4 in the Git bookand the original post by Linus Torvalds.

第4章在Git的书,并在原来的职位由Linus Torvalds

To undo a merge that was already pushed:

要撤消已经推送的合并:

git revert -m 1 commit_hash

Be sure to revert the revert if you're committing the branch again, like Linus said.

如果您再次提交分支,请确保恢复还原,就像 Linus 所说的那样。

回答by odinho - Velmont

It is strange that the simplest command was missing. Most answers work, but undoing the merge you just did, this is the easy and safe way:

奇怪的是,最简单的命令丢失了。大多数答案都有效,但要撤消刚刚执行的合并,这是简单而安全的方法

git reset --merge ORIG_HEAD

The ref ORIG_HEADwill point to the original commit from before the merge.

refORIG_HEAD将指向合并之前的原始提交。

(The --mergeoption has nothing to do with the merge. It's just like git reset --hard ORIG_HEAD, but safer since it doesn't touch uncommitted changes.)

(该--merge选项与合并无关。它就像git reset --hard ORIG_HEAD,但更安全,因为它不涉及未提交的更改。)

回答by Travis Reeder

With newer Git versions, if you have not committed the merge yet and you have a merge conflict, you can simply do:

使用较新的 Git 版本,如果您还没有提交合并并且有合并冲突,您可以简单地执行以下操作:

git merge --abort

From man git merge:

来自man git merge

[This] can only be run after the merge has resulted in conflicts. git merge --abortwill abort the merge process and try to reconstruct the pre-merge state.

[this] 只能在合并导致冲突后运行。git merge --abort将中止合并过程并尝试重建合并前的状态。

回答by MBO

You should reset to the previous commit. This should work:

您应该重置为之前的提交。这应该有效:

git reset --hard HEAD^

Or even HEAD^^to revert that revert commit. You can always give a full SHA reference if you're not sure how many steps back you should take.

或者甚至HEAD^^还原那个还原提交。如果您不确定应该后退多少步,您始终可以提供完整的 SHA 参考。

In case when you have problems and your master branch didn't have any local changes, you can reset to origin/master.

如果您遇到问题并且您的 master 分支没有任何本地更改,您可以重置为origin/master.

回答by Parris

Lately, I've been using git reflogto help with this. This mostly only works if the merge JUST happened, and it was on your machine.

最近,我一直在用它git reflog来帮助解决这个问题。这主要仅在合并刚刚发生时才有效,并且它在您的机器上。

git reflogmight return something like:

git reflog可能会返回类似的东西:

fbb0c0f HEAD@{0}: commit (merge): Merge branch 'master' into my-branch
43b6032 HEAD@{1}: checkout: moving from master to my-branch
e3753a7 HEAD@{2}: rebase finished: returning to refs/heads/master
e3753a7 HEAD@{3}: pull --rebase: checkout e3753a71d92b032034dcb299d2df2edc09b5830e
b41ea52 HEAD@{4}: reset: moving to HEAD^
8400a0f HEAD@{5}: rebase: aborting

The first line indicates that a merge occurred. The 2nd line is the time before my merge. I simply git reset --hard 43b6032to force this branch to track from before the merge, and carry-on.

第一行表示发生了合并。第二行是我合并之前的时间。我只是git reset --hard 43b6032强制这个分支从合并之前开始跟踪,然后继续。

回答by Martin G

With modern Git, you can:

使用现代 Git,您可以:

git merge --abort

Older syntax:

旧语法:

git reset --merge

Old-school:

老套:

git reset --hard

But actually, it is worth noticing that git merge --abortis only equivalent to git reset --mergegiven that MERGE_HEADis present. This can be read in the Git help for merge command.

但实际上,值得注意的git merge --abort是,仅相当于给git reset --mergeMERGE_HEAD存在。这可以在合并命令的 Git 帮助中阅读。

git merge --abort is equivalent to git reset --merge when MERGE_HEAD is present.

After a failed merge, when there is no MERGE_HEAD, the failed merge can be undone with git reset --merge, but not necessarily with git merge --abort, so they are not only old and new syntax for the same thing.

合并失败后,如果没有MERGE_HEAD,失败的合并可以用 撤消git reset --merge,但不一定用git merge --abort因此它们不仅是同一事物的新旧语法

Personally I find git reset --mergemuch more powerful and useful in everyday work, so that's the one I always use.

就我个人而言,我发现git reset --merge它在日常工作中更强大、更有用,所以我总是使用它。

回答by Matt Huggins

Okay, the answers other people here gave me were close, but it didn't work. Here's what I did.

好吧,这里的其他人给我的答案很接近,但没有用。这就是我所做的。

Doing this...

这样做...

git reset --hard HEAD^
git status

...gave me the following status.

...给了我以下状态。

# On branch master
# Your branch and 'origin/master' have diverged,
# and have 3 and 3 different commit(s) each, respectively.

I then had to type in the same git resetcommand several more times. Each time I did that, the message changed by one as you can see below.

然后我不得不git reset多次输入相同的命令。每次我这样做时,消息都会改变一个,如下所示。

> git reset --hard HEAD^
HEAD is now at [...truncated...]
> git status
# On branch master
# Your branch and 'origin/master' have diverged,
# and have 3 and 3 different commit(s) each, respectively.
> git reset --hard HEAD^
HEAD is now at [...truncated...]
> git status
# On branch master
# Your branch and 'origin/master' have diverged,
# and have 2 and 3 different commit(s) each, respectively.
> git reset --hard HEAD^
HEAD is now at [...truncated...]
> git status
# On branch master
# Your branch and 'origin/master' have diverged,
# and have 1 and 3 different commit(s) each, respectively.
> git reset --hard HEAD^
HEAD is now at [...truncated...]
> git status
# On branch master
# Your branch is behind 'origin/master' by 3 commits, and can be fast-forwarded.

At this point, I saw the status message changed, so I tried doing a git pull, and that seemed to work:

此时,我看到状态消息发生了变化,因此我尝试执行一个git pull,这似乎有效:

> git pull
Updating 2df6af4..12bbd2f
Fast forward
 app/views/truncated |    9 ++++++---
 app/views/truncated |   13 +++++++++++++
 app/views/truncated |    2 +-
 3 files changed, 20 insertions(+), 4 deletions(-)
> git status
# On branch master

So long story short, my commands came down to this:

长话短说,我的命令归结为:

git reset --hard HEAD^
git reset --hard HEAD^
git reset --hard HEAD^
git reset --hard HEAD^
git pull

回答by stephjang

You could use git reflogto find the previous checkout. Sometimes that's a good state you want to return back to.

您可以使用git reflog查找以前的结帐。有时那是您想要回到的好状态。

Concretely,

具体来说,

$ git reflog
$ git reset --hard HEAD@{0}