检查你的分支然后重置它
根据您的描述,并假设您在查看 commit1(下图中的C1)之前位于某个名为 mybranch 的分支上,您必须处于以下情况:
C1 [HEAD]
\
C2 -- C3 [mybranch]
提交C2 和C3 仍然出现在git log 的输出中,因为它们仍然可以从mybranch 引用中访问。另请注意,HEAD 已分离。你应该做的是……
-
通过运行将HEAD 重新附加到mybranch
git checkout mybranch
这应该使您处于以下情况:
C1
\
C2 -- C3 [HEAD -> mybranch]
-
通过运行将mybranch 分支重置为其尖端的祖父母
git reset --hard mybranch~2
这应该使您处于以下情况:
C1 [HEAD -> mybranch]
由于提交 C2 和 C3 现在已变得无法访问(即“已删除”),因此它们未显示在最后一张图中。
为什么不先重新连接 HEAD 就无法重置
这可能有点厚颜无耻,但这里解释了为什么其他两个答案不起作用。正如 cmbuckley 在his comment 中正确指出的那样,
git reset 重置您当前所在分支的状态(因此您需要在该分支上才能执行此操作)。如果您已签出 commit1,则您可能不在分支上(分离的 HEAD 状态)。
由于 OP (Imray) 处于分离 HEAD 状态,运行 git-reset before 将 HEAD 重新附加到分支将不会移动有问题的分支引用。这是一个说明这一点的玩具示例。
# set things up
$ mkdir test
$ cd test
$ git init
Initialized empty Git repository in /Users/jubobs/Desktop/test/.git/
# create a first commit
$ touch README
$ git add .
$ git commit -m "add README"
[master (root-commit) 85137ba] add README
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 README
# create a second commit
$ printf "foo\n" > README
$ git commit -am "write 'foo' in README"
[master 3948e84] write 'foo' in README
1 file changed, 1 insertion(+)
# inspect the log
$ git log --graph --decorate --oneline --all
* 3948e84 (HEAD, master) write 'foo' in README
* 85137ba add README
# check out the second commit (which detaches the HEAD)
$ git checkout 3948e84
Note: checking out '3948e84'.
# (boilerplate stdout is omitted...)
HEAD is now at 3948e84... write 'foo' in README
# reset to the first commit (equivalent to 'git reset --hard 85137ba')
$ git reset --hard HEAD^
HEAD is now at 85137ba add README
$ git log --graph --decorate --oneline --all
* 3948e84 (master) write 'foo' in README
* 85137ba (HEAD) add README
注意git reset 命令将HEAD 移动到初始提交,但没有移动master 分支。第二次提交没有被“删除”,因为它仍然可以从master 获得可访问;因此它被列在git log 的输出中。