首页 文章

撤消尚未推送的Git合并

提问于
浏览
3251

在我的主分支中,我在本地做了 git merge some-other-branch ,但从未将更改推送到origin master . 我没有't mean to merge, so I'想要撤消它 . 合并后执行 git status 时,我收到此消息:

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

根据一些instructions I found,我试着跑步

git revert HEAD -m 1

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

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

我不希望我的分支机构通过任意数量的提交领先 . 我该如何回到这一点?

26 回答

  • 330

    您可以使用 git reflog 查找之前的结帐 . 有时这是一个你想要回归的好状态 .

    具体而言,

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

    如果你还没提交,你只能使用

    $ git checkout -f
    

    它将撤消合并(以及您所做的一切) .

  • 11

    只是为了看一个额外的选项,我一直主要遵循这里描述的分支模型:http://nvie.com/posts/a-successful-git-branching-model/并且因此通常与 --no-ff (没有快进)合并 .

    我只是读了这个页面,因为我不小心合并了一个测试分支,而不是我的发布分支与master进行部署(网站,主人是什么是现场) . 测试分支有两个其他分支合并到它,总共约六个提交 .

    所以为了恢复整个提交,我只需要一个 git reset --hard HEAD^ 并且它恢复了整个合并 . 由于合并没有快速转发,因此合并是一个块,后退一步是"branch not merged" .

  • 0

    您可以使用git-reset命令 .

    git-reset - 将当前HEAD重置为指定状态 . git reset [--mixed | --soft | - 硬| --merge] [-q] [] git reset [-q] [] [ - ] ... git reset --patch [] [ - ] [...]

    GIT-Reset

  • 13

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

    git reset --hard commit_sha
    

    还有另一种方式:

    git reset --hard HEAD~1
    

    它会让你回来1提交 .

    Be aware that any modified and uncommitted/unstashed files will be reset to their unmodified state . 要保持它们隐藏更改或查看下面的 --merge 选项 .


    正如@Velmont在他的回答中所建议的那样,在这个直接案例中使用:

    git reset --hard ORIG_HEAD
    

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


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

    git reset --merge ORIG_HEAD
    

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

  • 0

    我能够使用一个不涉及查找提交ID的单个命令来解决此问题 .

    git reset --hard remotes/origin/HEAD
    

    接受的答案对我没有用,但是这个命令达到了我想要的结果 .

  • 1

    如果您注意到在合并后需要立即恢复,并且在合并尝试后没有做任何其他操作,则可以发出以下命令: git reset --hard HEAD@{1} .

    基本上,如果合并后没有提交任何其他内容,则合并 sha 将指向 HEAD@{0} ,因此 HEAD@{1} 将是合并之前的前一个点 .

  • 80

    最简单的答案是odinho给出的 - Velmont

    先做 git reset --merge ORIG_HEAD

    对于那些希望在推送更改后重置的人,请执行此操作(因为这是任何git重置合并问题的第一篇文章)

    git push origin HEAD --force

    这将以一种方式重置,以便在拉后不会再次获得合并的更改 .

  • 3585

    奇怪的是,最简单的命令丢失了 . 大多数答案都有效,但撤消了你刚才做的合并, this is the easy and safe way

    git reset --merge ORIG_HEAD
    

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

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

  • 4

    Strategy: 从一切都很好的地方创建一个新的分支 .

    Rationale: 恢复合并很难 . 解决方案太多,取决于许多因素,例如您是否已提交或推送合并,或者自合并以来是否有新的提交 . 此外,您仍然需要对git有一个相对深入的了解,以使这些解决方案适应您的情况 . 如果你盲目地遵循一些指令,你最终会得到"empty merge",其中没有任何东西将被合并,进一步的合并尝试将使Git告诉你"Already up to date" .

    Solution:

    假设您要将 dev 合并到 feature-1 中 .

    • 找到要接收合并的修订:
    git log --oneline feature-1
    a1b2c3d4 Merge branch 'dev' into 'feature-1' <-- the merge you want to undo
    e5f6g7h8 Fix NPE in the Zero Point Module <-- the one before the merge, you probably want this one
    
    • 检查出来(回到过去):
    git checkout e5f6g7h8
    
    • 从那里创建一个新的分支并检查出来:
    git checkout -b feature-1
    

    现在您可以重新启动合并:

    • 合并: git merge dev

    • 修复合并冲突 .

    • 承诺: git commit

    • 如果对结果满意,请删除旧分支: git branch --delete feature-1

  • 7

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

    git merge --abort
    

    man git merge

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

  • 0

    如果您的合并和相应的提交尚未推送,您可以随时切换到另一个分支,删除原始分支并重新创建它 .

    例如,我意外地将开发分支合并到主分支中,并想要撤消它 . 使用以下步骤:

    git checkout develop
    git branch -D master
    git branch -t master origin/master
    

    瞧! Master与原点处于同一阶段,您的错误合并状态将被删除 .

  • 10

    如果您提交了合并:

    git reset HEAD~1
    # Make sure what you are reverting is in fact the merge files
    git add .
    git reset --hard
    
  • 1

    得到这个问题也希望恢复匹配原点(即,NO提交原点之前) . 进一步研究,发现有一个 reset 命令正是如此:

    git reset --hard @{u}

    注意: @{u}origin/master 的简写 . (当然,您需要该远程存储库才能实现此功能 . )

  • 1321

    我认为你可以做 git rebase -i [hash] [branch_name] ,其中 [hash] 是你想要倒回的标识哈希加一个(或者你想要去的多次提交)然后删除编辑器中你不想要的提交行再也没有 . 保存文件 . 出口 . 祈祷 . 它应该是重绕的 . 你可能不得不做 git reset --hard ,但在这一点上它应该是好的 . 如果你不想要,你也可以使用它来从堆栈中提取特定的提交 .

  • 21
    • 首先,确保你已经兑现了一切 .

    • 然后将存储库重置为先前的工作状态:

    $ git reset f836e4c1fa51524658b9f026eb5efa24afaf3a36
    

    或使用 --hardthis will remove all local, not committed changes! ):

    $ git reset f836e4c1fa51524658b9f026eb5efa24afaf3a36 --hard
    

    在错误合并提交之前使用那里的哈希 .

    • 通过以下方式检查您要在上一个正确版本的顶部重新提交的提交:
    $ git log 4c3e23f529b581c3cbe95350e84e66e3cb05704f
    
    commit 4c3e23f529b581c3cbe95350e84e66e3cb05704f
    
    ...
    
    commit 16b373a96b0a353f7454b141f7aa6f548c979d0a
    
    ...
    
    • 通过以下方式在您的存储库的正确版本顶部应用您的权限提交:

    • 使用cherry-pick(某些现有提交引入的更改)

    git cherry-pick ec59ab844cf504e462f011c8cc7e5667ebb2e9c7
    
    • 或者通过以下方式挑选提交范围:

    • 首先在合并之前检查正确的更改:

    git diff 5216b24822ea1c48069f648449997879bb49c070..4c3e23f529b581c3cbe95350e84e66e3cb05704f
    
    • 首先在合并之前检查正确的更改:
    git cherry-pick 5216b24822ea1c48069f648449997879bb49c070..4c3e23f529b581c3cbe95350e84e66e3cb05704f
    

    这是您提交的正确提交的范围(不包括错误提交的合并) .

  • 1102

    您只能使用两个命令来恢复合并或通过特定提交重新启动:

    • git reset --hard commitHash (您应该使用要重新启动的提交,例如44a587491e32eafa1638aca7738)

    • git push origin HEAD --force (将新的本地主分支发送到origin / master)

    祝你好运,继续吧!

  • 880

    最简单的机会,比这里说的任何事情简单得多:

    删除本地分支(本地分支,而不是远程分支)并再次将其拉出 . 这样您就可以撤消主分支上的更改,任何人都会受到您不想推送的更改的影响 . 重新开始吧 .

  • 113

    假设您的本地主人不在原点/主人之前,您应该能够做到

    git reset --hard origin/master
    

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

  • 47

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

    这样做......

    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
    
  • 36

    在这种情况下,您需要使用 git reset --hard <branch_name> 重置分支 . 如果要在重置之前保存更改,请确保创建新分支和 git checkout <branch_name> .

    您也可以使用 git reset --hard <commit_id> 将状态重置为特定提交 .

    如果已推送更改,则可以使用 git revert <branch_name> . 请务必查看如何在其他场景中使用git revert and git checkout .

  • 5

    使用现代Git,您可以:

    git merge --abort
    

    较旧的语法:

    git reset --merge
    

    老套:

    git reset --hard
    

    但实际上,值得注意的是 git merge --abort 仅相当于 git reset --merge ,因为 MERGE_HEAD 存在 . 这可以在Git help for merge命令中读取 .

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

    合并失败后,如果没有 MERGE_HEAD ,则可以使用 git reset --merge 撤消失败的合并,但不一定使用 git merge --abortso they are not only old and new syntax for the same thing 撤消 .

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

  • 4

    如果你想要一个命令行解决方案,我建议你去MBO的答案 .

    如果你是新手,你可能会喜欢图形方法:

    • 启动 gitk (从命令行开始,或者右键单击文件浏览器,如果有的话)

    • 您可以轻松地发现合并提交 - 顶部的第一个节点有两个父节点

    • 点击链接到第一个/左边的父级(合并前当前分支上的一个,通常是红色的)

    • 在选定的提交上,右键单击"Reset branch to here",在那里选择硬重置

  • 1

    chapter 4 in the Git bookthe original post by Linus Torvalds .

    撤消一个合并 that was already pushed

    git revert -m 1 commit_hash
    

    如果你再次提交分支,请确保恢复恢复,如Linus所说 .

  • 10

    您应该重置为上一次提交 . 这应该工作:

    git reset --hard HEAD^
    

    甚至 HEAD^^ 还原那个还原提交 . 如果您不确定应该采取多少步骤,则始终可以提供完整的SHA参考 .

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

  • 6

    最近,我一直在使用 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 强制这个分支在合并之前进行跟踪,并随身携带 .

相关问题