使用git log
命令查找特定提交历史的高级技巧。其中的一些技巧配合格式化日志命令使用有奇效。
按照数量过滤
使用git log
命令时最基本的过滤方式就是按照可以显示的日志条数进行过滤。如果你只对最近几次提交感兴趣,这会节省在页面上查看所有提交的麻烦。
git log -3
按照日期过滤
如果你想查找特定时间段的提交历史,可以使用--after
或者--before
选项来通过日期过滤显示内容。这两个选项的值都可以接收不同形式的日期格式。比如下面的命令只显示2014年7月1日以及之后的提交历史信息。
git log --after="2014-7-1"
也可以传递相对时间比如"1 week ago"
表示一周前或者"yesterday"
表示昨天:
git log --after="yesterday"
如果想寻找时间区间内的提交历史,可以同时使用--before
和--after
选项。比如为了显示2014年7月1日到2014年7月4日之间提交可以向下面这样执行命令:
git log --after="2014-7-1" --before="2014-7-4"
此外需了解的是,git log
命令中还可以使用--since
和--until
选项,他们分别是--after
和--before
的同义词。
按照作者过滤
如果想查找某个特定作者的提交历史,可以使用--author
选项。该选项接受一个正则表达式,并且返回所有作者字段符合正则表达式的提交记录。当然如果你知道作者确切的名称,也可以直接传入一个普通字符串而无需使用正则表达式:
git log --author="John"
这条命令会显示所有由John
提交的记录。作者名称并不是必须完全一致,检索时会匹配包含给定参数的提交记录。
你也可以通过使用正则表达式来构建更加复杂的搜索方式。比如下面的例子就会去搜索Mary
或者John
提交的记录。
git log --author="John\|Mary"
请注意在作者字段中也包含提交者的email值,所以你也可以使用此选项来搜索特定email地址。
如果你的工作流程区分提交人和作者,那么--committer
选项操作也类似。
按照提交信息过滤
如果想按照提交信息过滤提交记录,可以使用--grep
选项。它的工作方式与--author
选项一致,只不过搜索的目标是提交信息而不是作者信息。
比如说你的团队规定提交信息中要包含对应的issue信息,那么就可以使用类似下面的命令来根据issue信息查找特定提交:
git log --grep="JRA-224:"
在使用时可以考虑传递-i
选项让git log
查找提交记录时忽略大小写。
按照文件过滤
很多时候,你可能只关心含有特定文件变更的提交。要想显示所有与这个文件相关的提交记录,那么可以将文件路径作为参数传递给git log
命令。比如下面的例子会返回所有与foo.py
和bar.py
文件有关的提交记录。
git log -- foo.py bar.py
--
参数告诉git log
命令接下来要传递的参数是文件路径而不是分支名称。如果你确定文件路径不会与分支名称混淆,也可以省略--
。
按照提交内容过滤
想要按照提交的具体内容来过滤提交记录,也是可以办到的。比如有时候你想知道添加或者删除某行代码的提交,可以使用-S""
这样的参数,这被叫做pickaxe
。比如如果你想知道Hello, World!
这行代码是什么时候被添加到项目里的,那么就可以执行下面的命令:
git log -S"Hello, World!"
如果想以正则表达式进行搜索,而不是通过字符串,那么可以修改一下上面的命令,改为传入-G""
这样的参数。
由于它提供了定位特定代码涉及到的所有提交记录的能力,这对于调试问题可能非常有用。这个命令甚至可以告诉你某行代码是什么时候被复制或者移动到另外一个文件的。
按照提交区间过滤
你可以向git log
命令传递一个表示提交之间的区间来筛选仅在这两次提交之间的所有提交记录。对于区间的表示如下所示:
git log ..
这个命令对于查找两个分支之间的区别非常有用。考虑下面这个命令:
git log main..feature
main..feature
这个提交区间的表述,会给出所有已经存在于feature
分支但还不存在于main
分支的提交记录。换句话说,也就是feature
分支已经距离main
分支有多远了。可以通过下图来理解:
请注意如果你对调区间的两端(feature..main
),你会得到所有已经存在于main
分支但还未存在于feature
分支的提交记录。如果git log
命令在执行这两个区间时都有返回,那么也就意味着你的提交历史已经分叉了。
过滤合并提交
git log
命令默认会含有合并提交。但是如果你的团队策略是“总是使用合并”(比如说总是在功能分支使用merge
来整合上游分支的新变更,而不是将功能分支rebase
到上游分支上),那么项目提交历史中会有大量冗余的合并提交节点。
通过传入--no-merges
选项,可以让git log
命令的输出过滤掉那些合并提交:
git log --no-merges
另外一方面,如果你只对合并提交感兴趣,也可以使用--merge
选项
git log --merges
这会输出所有含有两个及以上分支的提交记录。
总结
这些新技能是Git工具包中的重要组成部分,git log
命令经常与其他Git命令关联使用。一旦找到你所关心的那次提交,通常来说你都会需要使用git checkout
,git revert
或者其他什么命令来操作这次提交。所以,还需持续不断的学习Git的高级功能。