Git log 高级用法
BY 童仲毅(geeeeeeeeek@github)
这是一篇在原文(BY atlassian)基础上演绎的译文。除非另行注明,页面上所有内容采用知识共享-署名(CC BY 2.5 AU)协议共享。
每一个版本控制系统的出现都是为了让你记录代码的变化。你可以看到项目的历史记录——谁贡献了什么、bug 是什么时候引入的,还可以撤回有问题的更改。但是,首先你得知道如何使用它。这也就是为什么会有 git log
这个命令。
到现在为止,你应该已经知道如何用 git log
命令来显示最基本的提交信息。但除此之外,你还可以传入各种不同的参数来获得不一样的输出。
git log
有两个高级用法:一是自定义提交的输出格式,二是过滤输出哪些提交。这两个用法合二为一,你就可以找到你项目中你需要的任何信息。
格式化 Log 输出
首先,这篇文章会展示几种 git log
格式化输出的例子。大多数例子只是通过标记向 git log
请求或多或少的信息。
如果你不喜欢默认的 git log
格式,你可以用 git config
的别名功能来给你想要的格式创建一个快捷方式。
Oneline
--oneline
标记把每一个提交压缩到了一行中。它默认只显示提交ID和提交信息的第一行。git log --oneline
的输出一般是这样的:
0e25143 Merge branch 'feature'
ad8621a Fix a bug in the feature
16b36c6 Add a new feature
23ad9ad Add the initial code base
它对于获得项目的总体情况很有帮助。
Decorate
很多时候,知道每个提交关联的分支或者标签很有用。--decorate
标记让 git log
显示指向这个提交的所有引用(比如说分支、标签等)。
这可以和另一个配置项一起使用。比如,执行 git log --oneline --decorate
会将提交历史格式化成这样:
0e25143 (HEAD, master) Merge branch 'feature'
ad8621a (feature) Fix a bug in the feature
16b36c6 Add a new feature
23ad9ad (tag: v0.9) Add the initial code base
在这个例子中,你(通过HEAD标记)可以看到最上面那个提交已经被 checkout 了,而且它还是 master 分支的尾端。第二个提交有另一个 feature 分支指向它,以及最后那个提交带有 v0.9 标签。
分支、标签、HEAD 还有提交历史是你 Git 仓库中包含的所有信息。因此,这个命令让你更完整地观察项目结构。
Diff
git log
提供了很多选项来显示两个提交之间的差异。其中最常用的两个是 --stat
和 -p
。
--stat
选项显示每次提交的文件增删数量(注意:修改一行记作增加一行且删去一行),当你想要查看提交引入的变化时这会非常有用。比如说,下面这个提交在 hello.py 文件中增加了 67 行,删去了 38 行。
commit f2a238924e89ca1d4947662928218a06d39068c3
Author: John <john@example.com>
Date: Fri Jun 25 17:30:28 2014 -0500
Add a new feature
hello.py | 105 ++++++++++++++++++++++++-----------------
1 file changed, 67 insertion(+), 38 deletions(-)
文件名后面+和-的数量是这个提交造成的更改中增删的相对比例。它给你一个直观的感觉,关于这次提交有多少改动。如果你想知道每次提交删改的绝对数量,你可以将 -p
选项传入git log
。这样提交所有的删改都会被输出:
commit 16b36c697eb2d24302f89aa22d9170dfe609855b
Author: Mary <mary@example.com>
Date: Fri Jun 25 17:31:57 2014 -0500
Fix a bug in the feature
diff --git a/hello.py b/hello.py
index 18ca709..c673b40 100644
--- a/hello.py
+++ b/hello.py
@@ -13,14 +13,14 @@ B
-print("Hello, World!")
+print("Hello, Git!")
对于改 动很多的提交来说,这个输出会变得又长又大。一般来说,当你输出所有删改的时候,你是想要查找某一具体的改动,这时你就要用到 pickaxe
选项。
Shortlog
git shortlog
是一种特殊的 git log
,它是为创建发布声明设计的。它把每个提交按作者分类,显示提交信息的第一行。这样可以容易地看到谁做了什么。
比如说,两个开发者为项目贡献了 5 个提交,那么 git shortlog
输出会是这样的:
Mary (2):
Fix a bug in the feature
Fix a serious security hole in our framework
John (3):
Add the initial code base
Add a new feature
Merge branch 'feature'
默认情况下,git shortlog
把输出按作者名字排序,但你可以传入 -n
选项来按每个作者提交数量排序。
Graph
--graph
选项绘制一个 ASCII 图像来展示提交历史的分支结构。它经常和 --oneline
和 --decorate
两个选项一起使用,这样会更容易查看哪个提交属于哪个分支:
git log --graph --oneline --decorate
For a simple repository with just 2 branches, this will produce the following:
* 0e25143 (HEAD, master) Merge branch 'feature'
|\
| * 16b36c6 Fix a bug in the new feature
| * 23ad9ad Start a new feature
* | ad8621a Fix a critical security issue
|/
* 400e4b7 Fix typos in the documentation
* 160e224 Add the initial code base
星号表明这个提交所在的分支,所以上图的意思是 23ad9ad
和 16b36c6
这两个提交在 topic 分支上,其余的在 master 分支上。
虽然这对简单的项目来说是个很好用的选择,但你可能会更喜欢 gitk 或 SourceTree 这些更强大的可视化工具来分析大型项目。
自定义格式
对于其他的 git log
格式需求,你都可以使用 --pretty=format:"<string>"
选项。它允许你使用像 printf 一样的占位符来输出提交。
比如,下面命令中的 %cn
、%h
和 %cd
这三种占位符会被分别替换为作者名字、缩略标识和提交日期。
git log --pretty=format:"%cn committed %h on %cd"
This results in the following format for each commit:
John committed 400e4b7 on Fri Jun 24 12:30:04 2014 -0500
John committed 89ab2cf on Thu Jun 23 17:09:42 2014 -0500
Mary committed 180e223 on Wed Jun 22 17:21:19 2014 -0500
John committed f12ca28 on Wed Jun 22 13:50:31 2014 -0500
完整的占位符清单可以在文档中找到。
除了让你只看到关注的信息,这个 --pretty=format:"<string>"
选项在你想要在另一个命令中使用日志内容是尤为有用的。
过滤提交历史
格式化提交输出只是 git log
其中的一个用途。另一半是理解如何浏览整个提交历史。接下来的文章会介绍如何用 git log
选择项目历史中的特定提交。所有的用法都可以和上面讨论过的格式化选项结合起来。
按数量
git log
最基础的过滤选项是限制显示的提交数量。当你只对最近几次提交感兴趣时,它可以节省你一页一页查看的时间。
你可以在后面加上 -<n>
选项。比如说,下面这个命令会显示最新的 3 次提交:
git log -3