撤消尚未推送的 Git 合并

问题描述:

我不小心在本地主分支上运行了 git merge some_other_branch。我还没有将更改推送到原始主机。如何撤消合并?

合并后,git status 说:

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

我如何撤消所有这些提交?

解决方案1:

huntsbot.com精选全球7大洲远程工作机会,涵盖各领域,帮助想要远程工作的数字游民们能更精准、更高效的找到对方。

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

git reset --hard commit_sha

还有另一种方式:

git reset --hard HEAD~1

它会让你回到 1 次提交。

请注意,任何已修改和未提交/未存储的文件都将重置为未修改状态。要让他们保留更改,或者查看下面的 --merge 选项。

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

git reset --hard ORIG_HEAD

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

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

git reset --merge ORIG_HEAD

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

我认为这不会(总是?)工作——“合并之前的一次”将是从另一个分支合并的最新提交——它不会是当前分支上的最新提交.正确的? (这可能只是 git log 选择默认显示的结果 - 可能有不同的 git log 输出或 git reflog 可用于此)

我认为这可能取决于你是否压缩合并。

@JohnBachir 是对的。在 git log 输出中,您想要查看两个父提交。一个是您分支中的最新提交,一个是您合并到的分支中的最新提交。您想要 git reset --hard 到您合并到的分支上的父提交。

@JohnBachir:只要“合并”不是真正的快进,它就会导致日志顶部的新提交,并且这个提交有两个父母(或者如果你做章鱼,则超过2个合并)。如果你删除了这个合并提交,那么来自合并的所有旧提交也将消失。不过,为了安全起见,在重置后 git 会告诉你新的 head 在哪里:“HEAD 现在位于 88a04de ”。我总是看着那个,以确保我最终到达了我期望的位置。我的项目使用标准的分支命名方案来保持记忆。

我发现有用的是查看“git reflog”并查找我在 master 中所做的最后一次提交。然后执行git reset --hard

解决方案2:

HuntsBot周刊–不定时分享成功产品案例,学习他们如何成功建立自己的副业–huntsbot.com

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

git reset --hard origin/master

然后您的本地 master 分支应该看起来与 origin/master 相同。

@Carter 它实际上不是最好的答案。在某些提交合并之前,origin/master 可能在本地 master 之前,在这种情况下,这可能不会给出预期的结果

@dhruva-sagar 是的,但只要 git 没有说你落后,并且你不获取,你应该没问题。

谢谢!如果(且仅当)您有一个远程存储库,这是完美的。

不,这不是这个问题的完美选择,请参阅“假设”条款。 MBO 的回答实际上涵盖了这种情况,以及合并不是唯一本地提交的情况。

再一次,也许这个警告应该进入答案本身:Always avoid rewriting git history!

解决方案3:

huntsbot.com – 高效赚钱,自由工作

请参阅 chapter 4 in the Git book 和 the original post by Linus Torvalds。

要撤消已推送的合并:

git revert -m 1 commit_hash

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

@perfectist 同意 :) 有点希望有办法将此答案迁移到另一个问题——(也许有?)

有关还原的详细信息:link

为了确信这个恢复工作,你可以做 git diff hash1 hash2 其中 hash1 是提交的恢复,而 hash2 是你试图恢复到其状态的旧提交。没有输出==成功!通过多次执行此操作,我能够回滚多个提交,首先是还原最近的合并并向后工作。 git diff 向我展示了我最终达到了我想要的状态。

请注意,这不实际上解决了原始发帖人的问题。原始海报已经使用了git revert -m 1 。问题是这样做并没有消除他所做的意外合并(并且还没有推动)。涉及硬重置的其他答案更适合原始发布者的问题。

这是直接来自 Github 的一个很好的资源:How to undo (almost) anything with Git

解决方案4:

huntsbot.com精选全球7大洲远程工作机会,涵盖各领域,帮助想要远程工作的数字游民们能更精准、更高效的找到对方。

奇怪的是缺少最简单的命令。大多数答案都有效,但是撤消您刚刚所做的合并,这是一种简单而安全的方法:

git reset --merge ORIG_HEAD

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

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

如果您此后弄脏了工作树,git reset --merge ORIG_HEAD 会保留这些更改。

这是 only 正确答案(我并不是说这是最佳答案 - 请注意区别)。假设,在 master 上,我在 t1、t3 和 t5 做了 3 次提交。假设在 branch1 上,我在 t2、t4 和 t6 做了 3 条评论(假设 t1、t2、t3、t4、t5 和 t6 按时间顺序排列)。任何类似于 git reset --hard HEAD~5 的命令只会重置 HEAD(可能会删除 master 和 branch1 中的提交)。只有 --merge 选项会删除 merge。

@Manu --merge 选项实际上并没有删除合并,您可以使用 --hard 它也可以正常工作。此处的线索是参考 ORIG_HEAD,它是在您合并到您所在的位置之前设置的。 :)

@yingted “如果您此后弄脏了工作树,则 git reset --merge ORIG_HEAD 保留这些更改是什么意思。”您的意思是合并后更改文件吗?无论如何,我做了合并,然后做了一些解决冲突。但是后来我想重置合并并按照此答案中的说明进行操作。一切都很好,它没有保留我在合并后所做的更改。我的本地仓库与我进行合并之前的位置相似。

git reset --hard ORIG_HEAD 命令对我来说非常有效——这可能是因为我在尝试撤消本地 git merge 后没有对存储库进行任何其他更改。该命令只是将存储库的状态重置为合并之前的状态。感谢您的精彩提示!

解决方案5:

huntsbot.com汇聚了国内外优秀的初创产品创意,可按收入、分类等筛选,希望这些产品与实践经验能给您带来灵感。

对于较新的 Git 版本,如果您尚未提交合并并且您有合并冲突,您可以简单地执行以下操作:

git merge --abort

从 man git merge:

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

他的合并已提交但未推送(见标题),他已经合并,您的命令仅在他仍在合并中间时才有效

解决方案6:

保持自己快人一步,享受全网独家提供的一站式外包任务、远程工作、创意产品订阅服务–huntsbot.com

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

git reset --hard HEAD^

甚至 HEAD^^ 来恢复该恢复提交。如果您不确定应该退后多少步,您可以随时提供完整的 SHA 参考。

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

最好的答案恕我直言,包含了 OP 自己的一个(假设只有 1 个步骤可以恢复,这在 Q 中似乎是这种情况),以及 randomguy3 的快捷方式一个(当“你的主分支没有任何本地更改时有效” ")

你们评论者,@Inger 和@Konstantin,为什么?您是在我的答案创建后来到这里的,而且更正确。仅仅向上走一步通常是错误的,你必须实际计算你需要走多远。 Git 已经为你设置了 ORIG_HEAD,为什么不使用它呢?

它也会重置本地更改吗? #请更新。

这对我来说非常有效,像这样重置头部比这里的一半答案更有意义。

HEAD^ 等于在 HEAD 之前提交? ^^ 是两次提交之前?猜测这不适用于快进合并?

解决方案7:

huntsbot.com精选全球7大洲远程工作机会,涵盖各领域,帮助想要远程工作的数字游民们能更精准、更高效的找到对方。

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

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

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

很好的答案,谢谢!需要撤消合并,但其他答案只是把它搞砸了,使用 reflog 获取 SHA 并将其传递给 git reset 工作。

这绝对节省了我的一天,以前从未使用过 git reflog,谢谢一百万

解决方案8:

huntsbot.com – 高效赚钱,自由工作

如果您正在合并,您可以随时中止它

git merge --abort

huntsbot.com – 高效赚钱,自由工作

谢谢兄弟,我正要做那些可怕的事情正确答案。幸运的是我向下滚动。我只想删除合并头

解决方案9:

huntsbot.com洞察每一个产品背后的需求与收益,从而捕获灵感

使用现代 Git,您可以:

git merge --abort

旧语法:

git reset --merge

老套:

git reset --hard

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

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

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

就我个人而言,我发现 git reset --merge 在日常工作中更加强大和有用,所以这是我一直使用的。

对我来说效果很好。其他所有帖子都说这太复杂了,但这完全符合预期。我想它只是因为存在冲突而起作用,这并不能完全回答最初的问题。

这个答案不关注 OP 的情况,并遗漏了重要的上下文。

谢谢! git apply --3way 失败后,git reset --merge 提供了帮助,而其他答案却没有。这似乎是因为没有 MERGE_HEAD。

解决方案10:

huntsbot.com全球7大洲远程工作机会,探索不一样的工作方式

如果分支被合并而不被推送,那么下面给出的 git reset 命令将用于撤消合并:

git reset --merge ORIG_HEAD

例子:

git reset --merge origin/master

示例:git reset --merge origin/master

解决方案11:

huntsbot.com洞察每一个产品背后的需求与收益,从而捕获灵感

好的,这里其他人给我的答案很接近,但它不起作用。这就是我所做的。

这样做…

git reset --hard HEAD^
git status

…给了我以下状态。

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

然后我不得不多次输入相同的 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.

此时,我看到状态消息发生了变化,因此我尝试执行 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

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

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

或者您可以使用 HEAD^^^^

甚至可能重置为 origin/master ;)

原文链接:https://www.huntsbot.com/qa/la75/undo-a-git-merge-that-hasnt-been-pushed-yet?lang=zh_CN

huntsbot.com精选全球7大洲远程工作机会,涵盖各领域,帮助想要远程工作的数字游民们能更精准、更高效的找到对方。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值