问题描述:
我不小心在本地主分支上运行了 git merge some_other_branch。我还没有将更改推送到原始主机。如何撤消合并?
合并后,git status 说:
# On branch master
# Your branch is ahead of 'origin/master' by 5 commits.
我如何撤消所有这些提交?
解决方案1:
huntsbot.com精选全球7大洲远程工作机会,涵盖各领域,帮助想要远程工作的数字游民们能更精准、更高效的找到对方。文章来源地址https://www.toymoban.com/news/detail-708951.html
使用 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
文章来源:https://www.toymoban.com/news/detail-708951.html
huntsbot.com精选全球7大洲远程工作机会,涵盖各领域,帮助想要远程工作的数字游民们能更精准、更高效的找到对方。
到了这里,关于撤消尚未推送的 Git 合并的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!