选择修订版本
简短的 SHA-1
Git 十分智能,只需要提供 SHA-1 的前几个字符就可以获得对应的那次提交,当然,提供的 SHA-1 字符数量不得少于 4 个,并且没有歧义——也就是说,当前仓库中只有一个对象以这段 SHA-1 开头。
例如查看一次指定的提交,假设执行 git log 命令来查看之前新增一个功能的那次提交:
$ git log
commit 734713bc047d87bf7eac9674765ae793478c50d3
Author: Scott Chacon <schacon@gmail.com>
Date: Fri Jan 2 18:32:33 2009 -0800
fixed refs handling, added gc auto, updated tests
commit d921970aadf03b3cf0e71becdaab3147ba71cdef
Merge: 1c002dd... 35cfb2b...
Author: Scott Chacon <schacon@gmail.com>
Date: Thu Dec 11 15:08:43 2008 -0800
Merge commit 'phedders/rdocs'
commit 1c002dd4b536e7479fe34593e72e6c6c1819e53b
Author: Scott Chacon <schacon@gmail.com>
Date: Thu Dec 11 14:58:32 2008 -0800
added some blame and merge stuff
假设这个提交是 1c002dd…,如果想 git show 这个提交,下面的命令是等价的(假设简短的版本没有歧
义):
$ git show 1c002dd4b536e7479fe34593e72e6c6c1819e53b
$ git show 1c002dd4b536e7479f
$ git show 1c002d
Git 可以为 SHA-1 值生成出简短且唯一的缩写。
通常 8 到 10 个字符就已经足够在一个项目中避免 SHA-1 的歧义。
分支引用
指明一次提交最直接的方法是有一个指向它的分支引用。这样就可以在任意一个 Git 命令中使用这个分支名来代替对应的提交对象或者 SHA-1 值。例如,想要查看一个分支的最后一次提交的对象,假设 topic1 分支指向 ca82a6d ,那么以下的命令是等价的:
$ git show ca82a6dff817ec66f44342007202690a93763949
$ git show topic1
如果想知道某个分支指向哪个特定的 SHA-1,或者想看任何一个例子中被简写的 SHA-1 ,可以使用一个叫做 rev-parse 的 Git 探测工具。可以在你的分支上执行 rev-parse
$ git rev-parse topic1
ca82a6dff817ec66f44342007202690a93763949
引用日志
当工作时, Git 会在后台保存一个引用日志(reflog),引用日志记录了最近几个月你的 HEAD 和分支引用所
指向的历史。
可以使用 git reflog 来查看引用日志
$ 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 就会将这个信息存储到引用日志这个历史记录里。通过这些数
据,可以很方便地获取之前的提交历史。如果想查看仓库中 HEAD 在五次前的所指向的提交,可以使用 @{n} 来引用 reflog 中输出的提交记录。
$ git show HEAD@{5}
同样可以使用这个语法来查看某个分支在一定时间前的位置。例如,查看的 master 分支在昨天的时候指向了哪个提交,你可以输入
$ git show master@{yesterday}
就会显示昨天该分支的顶端指向了哪个提交。这个方法只对还在引用日志里的数据有用。
可以运行 git log -g 来查看类似于 git log 输出格式的引用日志信息:
$ git log -g master
commit 734713bc047d87bf7eac9674765ae793478c50d3
Reflog: master@{0} (Scott Chacon <schacon@gmail.com>)
Reflog message: commit: fixed refs handling, added gc auto, updated
Author: Scott Chacon <schacon@gmail.com>
Date: Fri Jan 2 18:32:33 2009 -0800
fixed refs handling, added gc auto, updated tests
commit d921970aadf03b3cf0e71becdaab3147ba71cdef
Reflog: master@{1} (Scott Chacon <schacon@gmail.com>)
Reflog message: merge phedders/rdocs: Merge made by recursive.
Author: Scott Chacon <schacon@gmail.com>
Date: Thu Dec 11 15:08:43 2008 -0800
Merge commit 'phedders/rdocs'
值得注意的是,引用日志只存在于本地仓库,一个记录你在你自己的仓库里做过什么的日志。其他人拷贝的仓库里的引用日志不会和你的相同;而新克隆一个仓库的时候,引用日志是空的,因为你在仓库里还没有操作。
git show HEAD@{2.months.ago} 这条命令只有在你克隆了一个项目至少两个月时才会有用——如果
是五分钟前克隆的仓库,那么它将不会有结果返回。
祖先引用
祖先引用是另一种指明一个提交的方式。如果在引用的尾部加上一个 ^, Git 会将其解析为该引用的上一个提交。
可以使用 HEAD^ 来查看上一个提交,也就是 “HEAD 的父提交”:
$ git show HEAD^
也可以在 ^ 后面添加一个数字——例如 d921970^2 代表 “d921970 的第二父提交”这个语法只适用于合并(merge)的提交,因为合并提交会有多个父提交。第一父提交是合并时所在分支,而第二父提交是所合并的分支。
另一种指明祖先提交的方法是 ~。同样是指向第一父提交,因此 HEAD~ 和 HEAD^ 是等价的。而区别在于在后面加数字的时候。HEAD~2 代表 “第一父提交的第一父提交”,也就是 “祖父提交” —— Git 会根据指定的次
数获取对应的第一父提交。
提交区间
最常用的指明提交区间语法是双点。这种语法可以让 Git 选出在一个分支中而不在另一个分支中的提交。例如,有如下的提交历史

想要查看 experiment 分支中还有哪些提交尚未被合并入 master 分支。可以使用 master…experiment
来让 Git 显示这些提交。也就是 “在 experiment 分支中而不在 master 分支中的提交”。示例:
$ git log master..experiment
D
C
反过来,如果你想查看在 master 分支中而不在 experiment 分支中的提交,你只要交换分支名即
可。experiment…master 会显示在 master 分支中而不在 experiment 分支中的提交:
$ git log experiment..master
F
E
"$ git log origin/master…HEAD"命令会输出在你当前分支中而不在远程 origin 中的提交。
Git 允许在任意引用前加上 ^ 字符或者 --not 来指明不希望提交被包含其中的分支。因此下列3个命令是等价的:
$ git log refA..refB
$ git log ^refA refB
$ git log refB --not refA
比如,你想查看所有被refA 或 refB 包含的但是不被 refC 包含的提交,可以输入下面中的任意一个命令
$ git log refA refB ^refC
$ git log refA refB --not refC
这个语法可以选择出被两个引用中的一个包含但又不被两者同时包含的提交。

如果想看 master 或者 experiment 中包含的但不是两者共有的提交,可以执行
$ git log master...experiment
F
E
D
C
这种情形下,log 命令的一个常用参数是 --left-right,它会显示每个提交到底处于哪一侧的分支。这会让
输出数据更加清晰。
$ git log --left-right master...experiment
< F
< E
> D
> C
交互式暂存
如果运行 git add 时使用 -i 或者 --interactive 选项,Git 将会进入一个交互式终端模式,显示类似
下面的东西:
$ git add -i
staged unstaged path
1: unchanged +0/-1 TODO
2: unchanged +1/-1 index.html
3: unchanged +5/-1 lib/simplegit.rb
*** Commands ***
1: status 2: update 3: revert 4: add untracked
5: patch 6: diff 7: quit 8: help
What now>
这个命令以非常不同的视图显示了暂存区 - 基本上与 git status 是相同的信息,但是更简明扼要一些。它将暂存的修改列在左侧,未暂存的修改列在右侧。
在这块区域后是命令区域。在这里可以做一些工作,包括暂存文件、取消暂存文件、暂存文件的一部分、添加未被追踪的文件、查看暂存内容的区别。
如果在 What now> 提示符后键入 2 或 u,脚本将会提示想要暂存哪个文件。
每个文件前面的 * 意味着选中的文件将会被暂存。如果在 Update>> 提示符后不输入任何东西并直接按回车,Git 将会暂存之前选择的文件。
如果这时想要取消暂存文件,使用 3 或 r(撤消)选项。
如果想要查看已暂存内容的区别,可以使用 6 或 d(区别)命令。
Git 也可以暂存文件的特定部分。例如,如果在某一个文件中做了两处修改,但只想要暂存其中的一个而不是另一个,Git 会帮你轻松地完成。从交互式提示符中,输入 5 或 p(补丁)。Git 会询问你想要部分暂存哪些文件;然后,对已选择文件的每一个部分,它都会一个个地显示文件区别并询问你是否想要暂存它们。
也可以不必在交互式添加模式中做部分文件暂存 - 可以在命令行中使用 git add -p 或 git add --patch 来启动同样的脚本。
更进一步地,可以使用 reset --patch 命令的补丁模式来部分重置文件,通过 checkout --patch 命令来部分检出文件与 stash save --patch 命令来部分暂存文件。

本文详细介绍了Git中如何使用SHA-1简写来引用提交,以及如何利用分支引用、引用日志和祖先引用来追踪和管理提交历史。通过示例展示了如何查看特定提交、分支状态以及在不同分支间的提交差异。此外,还提到了交互式暂存功能,允许用户灵活地选择暂存文件的修改部分。

被折叠的 条评论
为什么被折叠?



