指定特定的提交

有时候,我们想要获得某一个或者多个提交的信息,这样就可以回到那个指定的提交,或者是从那个提交开始衍生出一个新的分支。而选中一个提交意味着我们需要关于那个提交的信息。

指定提交大致有以下这么一些方法:

  • 40 位 SHA-1 值/短 SHA-1 值
  • 分支名,表示该分支的最新提交
  • 标签名,标签指定的提交
  • HEAD,当前分支的最新提交
  • ORIG_HEAD,合并、重置操作会把初始提交赋值给它,即在重大改变发生之前的 HEAD 的备份
  • FETCH_HEAD,最新的从远程仓库 fetch 过来的分支
  • MERGE_HEAD,被合并的分支
  • 根据提交的父子关系,~/^

获得单个提交

短 SHA-1 值

每个提交对象都有一个 SHA-1 值,很显然我们可以通过这个值来指定一个提交,但是没有人愿意记住一个 40 位的字符。好在我们可以指定一个简化版本,只要不少于 4 位,而且没有歧义就行:

$ git log --abbrev-commit --pretty=oneline
ca82a6d changed the version number
085bb3b removed unnecessary test code
a11bef0 first commit

分支引用

不管是长还是短,SHA-1 值都远不是友好的方式。另一种方式是指定一个指向目标提交对象的分支引用。如果想知道某个分支指向哪个特定的 SHA-1,可以用rev-parse这个底层命令:

$ git rev-parse master
ca82a6dff817ec66f44342007202690a93763949

引用日志(reflog)

当你在工作时,Git会在后台保存一个引用日志,这里面记录了最近几个月你的 HEAD 和分支引用所指向的历史。每当你的 HEAD 所指向的位置发生了变化,Git 就会把这个信息存储到引用日志里面。通过这个数据,你甚至可以查看到已经删除或硬重置的记录:

$ git reflog
734713b HEAD@{0}: commit: fixed refs handling, added gc auto, updated
d921970 HEAD@{1}: merge phedders/rdocs: Merge made by recursive.
1c002dd HEAD@{2}: commit: added some blame and merge stuff
1c36188 HEAD@{3}: rebase -i (squash): updating HEAD
95df984 HEAD@{4}: commit: # This is a combination of two commits.
1c36188 HEAD@{5}: rebase -i (squash): updating HEAD
7e05da5 HEAD@{6}: rebase -i (pick): updating HEAD

// 查看仓库中 HEAD 在五次前所指向的提交:
$ git show HEAD@{5}

// 查看 master 分支昨天指向了哪个提交
$ git show master@{yesterday}

值得注意的是,引用日志只存在于本地仓库,一个记录你在你自己的仓库里做过什么的日志。 其他人拷贝的仓库里的引用日志不会和你的相同;而你新克隆一个仓库的时候,引用日志是空的,因为你在仓库里还没有操作。git show HEAD@{2.months.ago} 这条命令只有在你克隆了一个项目至少两个月时才会有用——如果你是五分钟前克隆的仓库,那么它将不会有结果返回。

祖先引用

指定祖先引用有两种方式:~^:

// 表示指定提交的第二个父对象
$ git show d921970^2

// 表示指定提交的(第一个)父对象的(第一个)父对象
$ git show d921970~2

可见当符号后面的数字是1的话,那么两种方式是等价的;否则^一般只用在合并提交。当然,二者也可以合作,HEAD~2^2表示当前提交的祖父提交的第二个父对象。

获取提交区间

前面聊的都是获取单个提交。当你有很多分支的时候,获取区间提交对管理分支十分有用。比如,你可以用它来解决"这个分支还有哪些尚未合并到主分支的提交?"这个问题。

双点

在 HEAD 上,不在 origin/master 上的提交:

// 如果留空双点的右边,则默认为 HEAD
$ git log origin/master..HEAD

这个命令会输出在你当前分支上却不在远程跟踪分支上的提交。如果要执行 push,那这个命令展示了将要推送到远程的提交。

多点

双点只能在两个分支之间做操作,多点则更强大。比如,你想查看所有被refArefB包含但不被refC包含的提交,可以输入下面任意一个命令:

$ git log refA refB ^refC
$ git log refA refB --not refC

三点

用来选出被两个引用中的一个包含,但又不被两者同时包含的提交:

// 选出各自独有的提交,F/E 属于一个分支,D/C属于另一分支
$ git log master...experiment --left-right
<F
<E
>D
>C

资料

atlassian Tutorial,关于 refs,refspec,reflog 等基础的全面介绍。

results matching ""

    No results matching ""