在我的主分支中,我在本地做了一个git merge some-other-branch
,但从未将更改推送到origin master。我不是故意合并,所以我想撤消它。合并后做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.
我不希望我的分支通过任何数量的提交领先。我该如何回到那一点?
使用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
重置索引并更新工作树中<commit>和HEAD之间不同的文件,但保留索引和工作树之间不同的文件(即具有尚未添加的更改)。
您可以使用git reflog
查找之前的结帐。有时这是一个你想要回归的好状态。
具体而言,
$ git reflog
$ git reset --hard HEAD@{0}
如果你处于合并的中间,你可以随时中止它git merge --abort
如果你还没提交,你只能使用
$ git checkout -f
它将撤消合并(以及您所做的一切)。
得到这个问题也希望恢复匹配原点(即,NO提交原点之前)。进一步研究,发现有一个reset
命令正是如此:
git reset --hard @{u}
注意:@{u}
是origin/master
的简写。 (当然,您需要该远程存储库才能实现此功能。)
我能够使用一个不涉及查找提交ID的单个命令来解决此问题。
git reset --hard remotes/origin/HEAD
接受的答案对我没有用,但是这个命令达到了我想要的结果。
只是为了看一个额外的选项,我一直主要遵循这里描述的分支模型:http://nvie.com/posts/a-successful-git-branching-model/并且因此通常与--no-ff
(没有快进)合并。
我只是读了这个页面,因为我不小心合并了一个测试分支而不是我的发布分支与master进行部署(网站,主是什么是现场)。测试分支有两个其他分支合并到它,总共约六个提交。
所以为了恢复整个提交我只需要一个git reset --hard HEAD^
并且它恢复了整个合并。由于合并没有快速转发,合并是一个块,后退一步是“分支未合并”。
您只能使用两个命令来恢复合并或通过特定提交重新启动:
git reset --hard commitHash
(你应该使用你想要重启的提交,例如44a587491e32eafa1638aca7738)git push origin HEAD --force
(将新的本地主分支发送给origin / master)祝你好运,继续吧!
最简单的答案是odinho给出的一个 - Velmont
首先做git reset --merge ORIG_HEAD
对于那些希望在推送更改后重置的人,请执行此操作(因为这是任何git重置合并问题的第一篇文章)
git push origin HEAD --force
这将以一种方式重置,以便在拉后不会再次获得合并的更改。
如果您的合并和相应的提交尚未推送,您可以随时切换到另一个分支,删除原始分支并重新创建它。
例如,我意外地将一个开发分支合并到master中,并想要撤消它。使用以下步骤:
git checkout develop
git branch -D master
git branch -t master origin/master
瞧!师父与原点处于同一阶段,你的错误合并状态将被删除。
如果你想要一个命令行解决方案,我建议你选择MBO的答案。
如果你是新手,你可能会喜欢图形方法:
gitk
(从命令行开始,或者右键单击文件浏览器,如果有的话)假设您的本地主人不在原点/主人之前,您应该能够做到
git reset --hard origin/master
然后你当地的master
分支看起来应该与origin/master
相同。
策略:从一切都很好的地方创建一个新的分支。
理由:恢复合并很难。解决方案太多,取决于许多因素,例如您是否已提交或推送合并,或者自合并以来是否有新的提交。此外,您仍然需要对git有一个相对深入的了解,以使这些解决方案适应您的情况。如果你盲目地遵循一些指示,你最终会得到一个“空合并”,任何东西都不会合并,进一步的合并尝试将使Git告诉你“已经是最新的”。
解:
假设你想把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
我认为你可以做git rebase -i [hash] [branch_name]
,其中[hash]
是识别哈希,但是你想要倒回加一个(或者你想要去的多次提交)然后删除编辑器中你不想要的提交行更多。保存文件。出口。祈祷。它应该是重绕的。你可能不得不做一个git reset --hard
,但在这一点上应该很好。如果您不想将它们保留在历史记录中,也可以使用它来从堆栈中提取特定提交,但这可能会使您的存储库处于您可能不想要的状态。
如果您提交了合并:
git reset HEAD~1
# Make sure what you are reverting is in fact the merge files
git add .
git reset --hard
$ git reset f836e4c1fa51524658b9f026eb5efa24afaf3a36
或使用--hard
(这将删除所有本地,未提交的更改!):
$ git reset f836e4c1fa51524658b9f026eb5efa24afaf3a36 --hard
在错误合并提交之前使用那里的哈希值。$ git log 4c3e23f529b581c3cbe95350e84e66e3cb05704f
commit 4c3e23f529b581c3cbe95350e84e66e3cb05704f
...
commit 16b373a96b0a353f7454b141f7aa6f548c979d0a
...
git cherry-pick ec59ab844cf504e462f011c8cc7e5667ebb2e9c7
或者通过以下方式挑选提交范围:
首先在合并之前检查正确的更改:
git diff 5216b24822ea1c48069f648449997879bb49c070..4c3e23f529b581c3cbe95350e84e66e3cb05704f
首先在合并之前检查正确的更改:
git cherry-pick 5216b24822ea1c48069f648449997879bb49c070..4c3e23f529b581c3cbe95350e84e66e3cb05704f
这是您提交的正确提交的范围(不包括错误提交的合并)。你必须改变你的HEAD,当然不是你的,但是git HEAD ....
所以在回答之前让我们添加一些背景,解释这是什么HEAD
。
First of all what is HEAD?
HEAD
只是对当前分支上当前提交(最新)的引用。
在任何给定时间只能有一个HEAD
。 (不包括git worktree
)
HEAD
的内容存储在.git/HEAD
中,它包含当前提交的40字节SHA-1。
detached HEAD
如果你没有进行最新的提交 - 意味着HEAD
指向历史上的先前提交,它称为detached HEAD
。
在命令行上,它看起来像这样 - SHA-1而不是分支名称,因为HEAD
没有指向当前分支的尖端
git checkout
git checkout <commit_id>
git checkout -b <new branch> <commit_id>
git checkout HEAD~X // x is the number of commits t go back
这将检查指向所需提交的新分支。 此命令将签出到给定的提交。 此时,您可以创建一个分支并从此开始工作。
# Checkout a given commit.
# Doing so will result in a `detached HEAD` which mean that the `HEAD`
# is not pointing to the latest so you will need to checkout branch
# in order to be able to update the code.
git checkout <commit-id>
# create a new branch forked to the given commit
git checkout -b <branch name>
git reflog
您也可以随时使用reflog
。
git reflog
将显示更新HEAD
的任何更改,并检查所需的reflog条目将HEAD
设置回此提交。
每次修改HEAD时,reflog
都会有一个新条目
git reflog
git checkout HEAD@{...}
这将使您回到所需的提交
git reset --hard <commit_id>
将HEAD“移动”回所需的提交。
# This will destroy any local modifications.
# Don't do it if you have uncommitted work you want to keep.
git reset --hard 0d1d7fc32
# Alternatively, if there's work to keep:
git stash
git reset --hard 0d1d7fc32
git stash pop
# This saves the modifications, then reapplies that patch after resetting.
# You could get merge conflicts if you've modified things which were
# changed since the commit you reset to.
git rebase --no-autostash
。git revert <sha-1>
“撤消”给定的提交或提交范围。 reset命令将“撤消”给定提交中所做的任何更改。 将提交具有撤消补丁的新提交,同时原始提交也将保留在历史记录中。
# add new commit with the undo of the original one.
# the <sha-1> can be any commit(s) or commit range
git revert <sha-1>
此架构说明了哪个命令执行的操作。
正如你所看到的那样reset && checkout
修改了HEAD
。
如果您注意到在合并后需要立即恢复,并且在合并尝试后没有做任何其他操作,则可以发出以下命令:git reset --hard HEAD@{1}
。
基本上,如果合并后没有其他任何东西提交,你的合并sha
将指向HEAD@{0}
,因此HEAD@{1}
将是合并之前的前一点。
最简单的机会,比这里说的任何事情简单得多:
删除本地分支(本地分支,而不是远程分支)并再次将其拉出。这样您就可以撤消主分支上的更改,任何人都会受到您不想推送的更改的影响。重新开始吧。
在这种情况下,您将需要使用git reset --hard <branch_name>
重置分支。如果要在重置之前保存更改,请确保创建新分支和git checkout <branch_name>
。
您也可以使用git reset --hard <commit_id>
将状态重置为特定提交。
如果已经推动了更改,则可以使用git revert <branch_name>
。请务必查看如何在其他场景中使用git revert and git checkout。
git stash
git branch -d the_local_branch
git checkout -t <name of remote>
git stash apply
这对我有用.. !!
它可以通过多种方式完成。
1)堕胎合并
如果你介于一个错误的合并(错误地完成错误的分支),并希望避免合并返回到最新的分支,如下所示:
git merge --abort
2)将HEAD重置为远程分支
如果您使用远程开发分支,则可以将HEAD重置为远程分支上的最后一次提交,如下所示:
git reset --hard origin/develop
3)删除当前分支,并从远程存储库再次签出
考虑到,你正在开发本地仓库中的分支,与远程/开发分支同步,你可以这样做:
git checkout master
##to delete one branch, you need to be on another branch, otherwise you will fall with the branch :)
git branch -D develop
git checkout -b develop origin/develop
见chapter 4 in the Git book和the original post by Linus Torvalds。
要撤消已推送的合并:
git revert -m 1 commit_hash
如果你再次提交分支,请确保恢复恢复,如Linus所说。
只需创建新的分支,然后挑选所需的提交。
它的更安全,更简单,然后在上面的许多答案中描述重置
奇怪的是,最简单的命令丢失了。大多数答案都有效,但撤消刚刚进行的合并,这是一种简单而安全的方法:
git reset --merge ORIG_HEAD
ref ORIG_HEAD
将指向合并之前的原始提交。
(--merge
选项与合并无关。它就像git reset --hard ORIG_HEAD
一样,但更安全,因为它不会触及未提交的更改。)
对于较新的Git版本,如果您还没有提交合并并且您有合并冲突,您可以简单地执行:
git merge --abort
来自man git merge
:
[此]只能在合并导致冲突后运行。
git merge --abort
将中止合并过程并尝试重建合并前状态。
您应该重置为上一次提交。这应该工作:
git reset --hard HEAD^
甚至HEAD^^
还原那个还原提交。如果您不确定应该采取多少步骤,则可以随时提供完整的SHA参考。
如果您遇到问题且主分支没有任何本地更改,您可以重置为origin/master
。
最近,我一直在使用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
强制这个分支在合并之前进行跟踪,并随身携带。
使用现代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 --abort
撤消,所以它们不仅是旧的和新的语法相同的东西。
就个人而言,我发现git reset --merge
在日常工作中更加强大和有用,所以这是我一直使用的。
好吧,这里给我的其他人的答案很接近,但是没有用。这就是我做的。
这样做......
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