这个git reset命令中的~1是什么意思?

cfi*_*her 3 git

git reset HEAD~1

我的印象是~1意味着:从HEAD开始,跟随1个链接,并将HEAD标记设置为新的提交节点.我在期待

git reset HEAD~2

按照2个链接然后设置HEAD标记.但是,如果我尝试它,我会收到一个错误:

$ git reflog
c83bbda HEAD@{0}: reset: moving to HEAD~1
44c3540 HEAD@{1}: commit: you will be garbage soon
c83bbda HEAD@{2}: reset: moving to HEAD~1
aee7955 HEAD@{3}: commit: back to 4 lines
c83bbda HEAD@{4}: reset: moving to HEAD~1
19ec1d5 HEAD@{5}: commit: 3 lines
c83bbda HEAD@{6}: reset: moving to HEAD~1
a049538 HEAD@{7}: commit: added new line
c83bbda HEAD@{8}: commit (initial): first commit


$ git reset --hard HEAD~2
fatal: ambiguous argument 'HEAD~2': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
Run Code Online (Sandbox Code Playgroud)

显然我错了,但git reset的doc页面在澄清这一点时并不是很有用.那么,~1是什么意思,我为什么需要呢?

tor*_*rek 5

HEAD~1是"第一个父母HEAD",而HEAD~2"是第一个父母的第一个父母HEAD,依此类推(因此HEAD~n对于某些n就像是HEAD后跟n个^符号而没有数字).再次,所有细节都在git-rev中-parse手册页.

git reset与"向后计数"相混合时要小心HEAD. git reset通常会改变价值HEAD,例如:

$ git checkout master    # now on tip of "master" branch
$ git branch save master # copy branch tip to another label, for safekeeping
$ git reset HEAD^        # or git reset HEAD~1
Run Code Online (Sandbox Code Playgroud)

移动HEAD(和master)到它的第一个父.命名父母的另一种方式是save^,而另一种方式是save~1.此举完成后,虽然,HEAD现在的名字是父母的修订,所以HEAD^名称及其家长:

$ git reset HEAD^
Run Code Online (Sandbox Code Playgroud)

移动你回来又迈进了一步,使masterHEAD现在的名字一样提交该save~2名称.这很容易看到git rev-parse,它告诉你一些符号名称映射到的commit-ID:

$ git rev-parse save~2 master
0f5a13497dd3da8aff8e452c8f56630f83253e79
0f5a13497dd3da8aff8e452c8f56630f83253e79
Run Code Online (Sandbox Code Playgroud)

此时,您可以使用以下命令恢复master到保存点:

$ git reset save
Run Code Online (Sandbox Code Playgroud)

移动HEADmaster返回到已保存的修订版,然后save如果您愿意,可以安全删除:

$ git branch -d save
Run Code Online (Sandbox Code Playgroud)

请注意,您也可以保存一个保存点git tag:分支和标记之间的唯一区别是"在分支上"(标记不移动,分支执行)和签出时新签入的行为(标签将您置于"分离的HEAD"=非分支状态,分支名称将您置于"分支上"状态).