一、查看提交历史
在提交了若干更新,又或者克隆了某个项目之后,你也许想回顾下提交历史。 完成这个任务最简单而又有效的工具是"git log"命令。
我们使用一个非常简单的"simplegit"项目作为示例。 运行下面的命令获取该项目:
$ git clone https://github.com/schacon/simplegit-progit
在此项目中运行"git log"命令时,可以看到下面的输出:

不传入任何参数的默认情况下"git log" 会按时间先后顺序列出所有的提交,最近的更新排在最上面。 正如你所看到的,这个命令会列出每个提交的SHA-1 校验和、作者的名字和电子邮件地址、提交时间以及提交说明。
"git log"有许多选项可以帮助你搜寻你所要找的提交, 下面我们会介绍几个最常用的选项。
其中一个比较有用的选项是-p,它会显示每次提交所引入的差异。 与此同时,你也可以使用-2选项来仅显示最近的两次提交:

该选项除了显示基本信息之外,还附带了每次commit的变化。 当进行代码审查,或者快速浏览某个搭档提交的commit 所带来的变化的时候,这个参数就非常有用了。也可以为git log 附带一系列的总结性选项。 比如你想看到每次提交的简略统计信息,可以使用--stat 选项:

--stat选项在每次提交的下面列出所有被修改过的文件、有多少文件被修改了以及被修改过的文件的哪些行被移除或是添加了。在每次提交的最后还有一个总结。
另一个非常有用的选项是--pretty。 这个选项可以使用不同于默认格式的方式展示提交历史。 这个选项有一些内建的子选项供你使用。比如oneline 会将每个提交放在一行显示,在浏览大量的提交时非常有用。另外还有short,full和 fuller选项,它们展示信息的格式基本一致,但是详尽程度不一:


选项 | 说明 |
---|---|
%H | 提交的完整哈希值 |
%h | 提交的简写哈希值 |
%T | 树的完整哈希值 |
%t | 树的简写哈希值 |
%P | 父提交的完整哈希值 |
%p | 父提交的简写哈希值 |
%an | 作者名字 |
%ae | 作者的电子邮件地址 |
%ad | 作者修订日期(可以用 --date= 选项定制格式) |
%ar | 作者修订日期,按多久以前的方式显示 |
%cn | 提交者(committer)的名字 |
%ce | 提交者的电子邮件地址 |
%cd | 提交日期 |
%cr | 提交日期(距今多长时间) |
%s | 提交说明 |
作者和提交者之间究竟有何差别, 其实作者指的是实际作出修改的人,提交者指的是最后将此工作成果提交到仓库的人。 所以,当你为某个项目发布补丁,然后某个核心成员将你的补丁并入项目时,你就是作者,而那个核心成员就是提交者。
当oneline或format与另一个log选项--graph结合使用时尤其有用。 这个选项添加了一些ASCII字符串来形象地展示你的分支、合并历史:
$ git log --pretty=format:"%h %s" --graph
* 2d3acf9 ignore errors from SIGCHLD on trap
* 5e3ee11 Merge branch 'master' of git://github.com/dustin/grit
|\
| * 420eac9 Added a method for getting the current branch.
* | 30e367c timeout code and tests
* | 5a09431 add timeout protection to grit
* | e1193f8 support for heads with slashes in them
|/
* d6016bc require time for xmlschema
* 11d191e Merge branch 'defunkt' into local
这种输出类型会在我们学完分支与合并以后变得更加有趣。
以上只是简单介绍了一些"git log"命令支持的选项。"git log"的常用选项 列出了我们目前涉及到的和没涉及到的选项,以及它们是如何影响"log"命令的输出的:
"git log"常用的选项选项 | 说明 |
---|---|
-p | 按补丁格式显示每个提交引入的差异。 |
--stat | 显示每次提交的文件修改统计信息。 |
--shortstat | 只显示 --stat 中最后的行数修改添加移除统计。 |
--name-only | 仅在提交信息后显示已修改的文件清单。 |
--name-status | 显示新增、修改、删除的文件清单。 |
--abbrev-commit | 仅显示SHA-1校验和所有40个字符中的前几个字符。 |
--relative-date | 使用较短的相对时间而不是完整格式显示日期(比如,"2 weeks ago") |
--graph | 在日志旁以 ASCII 图形显示分支与合并历史。 |
--pretty | 使用其他格式显示历史提交信息。可用的选项包括 oneline,short,full,fuller和format(用来定义自己的格式)。 |
二、限制输出长度
除了定制输出格式的选项之外,"git log" 还有许多非常实用的限制输出长度的选项,也就是只输出一部分的提交。 之前你已经看到过-2选项了,它只会显示最近的两条提交,实际上,你可以使用类似-<n> 的选项,其中的n可以是任何整数,表示仅显示最近的n条提交。 不过实践中这个选项不是很常用,因为Git 默认会将所有的输出传送到分页程序中,所以你一次只会看到一页的内容。
但是,类似--since和--until这种按照时间作限制的选项很有用。 例如,下面的命令会列出最近两周的所有提交:
$ git log --since=2.weeks
该命令可用的格式十分丰富——可以是类似"2008-01-15" 的具体的某一天,也可以是类似"2 years 1 day 3 minutes ago"的相对日期。
还可以过滤出匹配指定条件的提交。用--author 选项显示指定作者的提交,用--grep选项搜索提交说明中的关键字。 (请注意,如果你要同时对作者和提交说明进行过滤,就必须添加--all-match 选项,否则该命令将会匹配满足其中任意一个条件的提交)
另一个非常有用的过滤器是 -S,它接受一个字符串参数,并且只会显示那些添加或删除了该字符串的提交。 假设你想找出添加或删除了对某一个特定函数的引用的提交,可以调用:
$ git log -Sfunction_name
最后一个很实用的"git log"选项是路径(path), 如果只关心某些文件或者目录的历史提交,可以在 git log 选项的最后指定它们的路径。 因为是放在最后位置上的选项,所以用两个短划线(--)隔开之前的选项和后面限定的路径名。
在限制"git log"输出的选项中列出了常用的选项
限制"git log"输出的选项选项 | 说明 |
---|---|
-(n) | 仅显示最近的 n 条提交 |
--since, --after | 仅显示指定时间之后的提交 |
--until, --before | 仅显示指定时间之前的提交 |
--author | 仅显示作者匹配指定字符串的提交 |
--committer | 仅显示提交者匹配指定字符串的提交 |
--grep | 仅显示提交说明中包含指定字符串的提交 |
-S | 仅显示添加或删除内容匹配指定字符串的提交 |