我不小心在本地主分支上运行了gitmergesome_other_branch。我还没有将更改推送给origin master。如何撤消合并?
合并后,git状态显示:
# On branch master
# Your branch is ahead of 'origin/master' by 5 commits.
我如何撤销所有这些提交?
我不小心在本地主分支上运行了gitmergesome_other_branch。我还没有将更改推送给origin master。如何撤消合并?
合并后,git状态显示:
# On branch master
# Your branch is ahead of 'origin/master' by 5 commits.
我如何撤销所有这些提交?
当前回答
假设您的本地主机不领先于源/主机,您应该能够
git reset --hard origin/<branch-name>
因此,假设您在master上执行了此操作,那么您的本地master分支看起来应该与origin/master相同。
其他回答
使用git reflog检查合并之前的提交(git refog将是比git log更好的选项)。然后,您可以使用以下方法重置它:
git reset --hard commit_sha
还有另一种方法:
git reset --hard HEAD~1
它会让你回到我的承诺。
请注意,任何已修改和未提交/未提交的文件都将重置为其未修改的状态。要保留它们,要么隐藏更改,要么查看下面的--merge选项。
正如@Velmont在下面的回答中所建议的,在这个直接案例中,使用:
git reset --hard ORIG_HEAD
可能会产生更好的结果,因为它应该保留您的更改。ORIG_HEAD将在合并发生之前直接指向提交,因此您不必自己寻找它。
另一个技巧是使用--merge开关而不是--hard,因为它不会不必要地重置文件:
git reset --merge ORIG_HEAD
--合并重置索引并更新<commit>和HEAD之间不同的工作树中的文件,但保留索引和工作树之间不同的文件(即具有尚未添加的更改)。
你必须改变你的头,当然不是你的,而是你的头。。。。
所以在回答之前,让我们添加一些背景,解释一下这个HEAD是什么。
首先,什么是头部?
HEAD只是对当前分支上当前提交(最新)的引用。在任何给定时间只能有一个HEAD。(不包括git工作树)
HEAD的内容存储在.git/HEAD中,它包含当前提交的40字节SHA-1。
分离式封头
如果您不在最近一次提交中,这意味着HEAD指向历史上的先前提交,它称为分离的HEAD。
在命令行上,它看起来像-SHA-1而不是分支名称,因为HEAD没有指向当前分支的末端
关于如何从分离的HEAD恢复的几个选项:
git校验
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>
数字刷新
您也可以始终使用reflog。git reflog将显示更新HEAD的任何更改,检查所需的reflog条目将将HEAD设置回该提交。
每次修改HEAD时,reflog中都会有一个新条目
git reflog
git checkout HEAD@{...}
这会让你回到你想要的承诺
git reset--hard<commit_id>
将你的头“移”回所需的位置。
# 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 2.7以来)您也可以使用git rebase--也可以不使用autostash。
git还原<sha-1>
“撤消”给定的提交或提交范围。重置命令将“撤消”给定提交中所做的任何更改。将提交带有撤销补丁的新提交,而原始提交也将保留在历史记录中。
# 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>
此模式说明了哪个命令执行什么操作。正如您可以看到的那样,重置和签出修改HEAD。
如果你还没有提交,你只能使用
$ git checkout -f
它将撤消合并(以及您所做的一切)。
您应该重置为上一次提交。这应该是有效的:
git reset --hard HEAD^
或者甚至HEAD^^还原该还原提交。如果您不确定应该后退多少步,您可以始终提供完整的SHA参考。
如果出现问题,并且主分支没有任何本地更改,则可以重置为原始/主分支。
最近,我一直在使用git reflog来帮助解决这个问题。只有在合并刚刚发生并且在您的机器上时,这才有效。
git-relog可能会返回如下内容:
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来强制该分支在合并之前跟踪,然后继续。