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
按日期
如果你想要查看某一特定时间段内的提交,你可以使用--after
或 --before
标记来按日期筛选。它们都接受好几种日期格式作为参数。比如说,下面的命令会显示2014年7月1日后(含)的提交:
git log --after="2014-7-1"
你也可以传入相对的日期,比如一周前("1 week ago
")或者昨天("yesterday
"):
get log --after="yesterday"
你可以同时提供--before
和 --after
来检索两个日期之间的提交。比如,为了显示2014年7月1日到2014年7月4日之间的提交,你可以这么写:
git log --after="2014-7-1" --before="2014-7-4"
注意--since
、--until
标记和--after
、--before
标记分别是等价的。
按作者
当你只想看某一特定作者的提交的时候,你可以使用--author
标记。它接受正则表达式,返回所有作者名字满足这个规则的提交。如果你知道那个作者的确切名字你可以直接传入文本字符串:
git log --author="John"
它会显示所有作者叫John的提交。作者名不一定是全匹配,只要包含那个子串就会匹配。
你也可以用正则表达式来创建更复杂的检索。比如,下面这个命令检索名叫Mary或John的作者的提交。
git log --author="John\|Mary"
注意作者的邮箱地址也算作是作者的名字,所以你也可以用这个选项来按邮箱检索。
如果你的工作流区分提交者和作者,--committer
也能以相同的方式使用。
按提交信息
按提交信息来过滤提交,你可以使用--grep
标记。它和上面的--author
标记差不多,只不过它搜索的是提交信息而不是作者。
比如说,你的团队规范要求在提交信息中包括相关的issue编号,你可以用下面这个命令来显示这个issue相关的所有提交:
git log --grep="JRA-224:"
你也可以传入-i
参数来忽略大小写匹配。
按文件
很多时候,你只对某个特定文件的更改感兴趣。为了显示某个特定文件的历史,你只需要传入文件路径。比如说,下面这个命令返回所有和foo.py
和bar.py
文件相关的提交:
git log -- foo.py bar.py
--
告诉git log
接下来的参数是文件路径而不是分支名。如果分支名和文件名不可能冲突,你可以省略--
。
按内容
我们还可以根据源代码中某一行的增加和删除来搜索提交。这被称为pickaxe,它接受形如-S"<string>"
的参数。比如说,当你想要知道Hello, World!
字符串是什么时候加到项目中哪个文件中去的,你可以使用下面这个命令:
git log -S "Hello, World!"
如果你想用正则表达式而不是字符串来搜索,你可以使用-G"<regex>"
标记。
这是一个非常强大的调试工具,它能让你定位到所有影响代码中特定一行的提交。它甚至可以让你看到某一行是什么时候复制或者移动到另一个文件中去的。
按范围
你可以传入范围来筛选提交。这个范围由下面这样的格式指定,其中<since>
和<until>
是提交的引用:
git log <since>..<until>
这个命令在你使用分支引用作为参数时特别有用。这是显示两个分支之间区别最简单的方式。看看下面这个命令:
git log master..feature
其中的master..feature范围包含了在feature分支而不在master分支中所有的提交。换句话说,这个命令可以看出从master分支fork到feature分支后发生了哪些变化。它可以这样可视化:
注意如果你更改范围的前后顺序(feature..master),你会获取到master分支而非feature分支上的所有提交。如果git log
输出了全部两个分支的提交,这说明你的提交历史已经分叉了。
过滤合并提交
git log
输出时默认包括合并提交。但是,如果你的团队采用强制合并策略(意思是merge你修改的上游分支而不是将你的分支rebase到上游分支),你的项目历史中会有很多外来的提交。
你可以通过--no-merges
标记来排除这些提交:
git log --no-merges
另一方面,如果你只对合并提交感兴趣,你可以使用--merges
标记:
git log --merges
它会返回所有包含两个父节点的提交。
总结
你现在应该对使用git log
来格式化输出和选择你要显示的提交的用法比较熟悉了。它允许你查看你项目历史中任何需要的内容。
这些技巧是你Git工具箱中重要的部分,不过注意git log
往往和其他Git命令连着使用。当你找到了你要的提交,你把它传给git checkout
、git revert
或是其他控制提交历史的工具。所以,请继续坚持Git高级用法的学习。
Git log高级用法的更多相关文章
- 问题: 查看某个文件的修改记录| git log 高级用法
参考文章: git查看某个文件的修改历史 5.3 Git log 高级用法 基本步骤 git log --pretty=oneline [文件名] git show [节点] git log 两周高级 ...
- git log 高级用法
转自:https://github.com/geeeeeeeeek/git-recipes/wiki/5.3-Git-log%E9%AB%98%E7%BA%A7%E7%94%A8%E6%B3%95 内 ...
- git log的用法
git log 查看 提交历史默认不用任何参数的话,git log 会按提交时间列出所有的更新,最近的更新排在最上面. git log --graph --pretty=format:'%Cred%h ...
- 接上篇:Git Worktree 高级使用,这样清爽多了
前言 上一篇文章 Git Worktree 大法真香 带大家了解了 git worktree 是如何帮助我同时在多个分支工作,并且互不影响的.但是创建 worktree 的目录位置不是在当前项目下,总 ...
- Git 高级用法,你会了吗?
请注意我有意跳过了 git commit.git pull/push 之类的基本命令,这份小抄的主题是 git 的一些「高级」用法. 导航 -- 跳到之前的分支 git checkout - 查看历史 ...
- Python彩蛋、字典、列表高级用法、元类、混入、迭代器、生成器、生成式、git
一.类与类的关系 关注公众号"轻松学编程"了解更多. is-a 继承 继承是指一个类(称为子类.子接口)继承另外一个类(称为父类.父接口)的功能, 并可以增加它自己的新功能的能力. ...
- Git 高级用法,喜欢就拿去用
如果你觉得 git 很迷惑人,那么这份小抄正是为你准备的! 请注意我有意跳过了 git commit.git pull/push 之类的基本命令,这份小抄的主题是 git 的一些「高级」用法. 导航 ...
- Git log diff config高级进阶
Git 历史相关和 git config 高级进阶 前一段时间分享了一篇<更好的 git log>简要介绍怎么美化 git log 命令,其中提到了 alias命令,今天再继续谈谈 git ...
- [转] console.log的高级用法
//基本用法 console.log('最常见用法\n换行'); console.error('输出错误信息 会以红色显示'); console.warn('打印警告信息 会以黄色显示'); cons ...
随机推荐
- 002.TPerlRegEx简单测试
我要做什么? 将一个字符串中的所有连续的数字替换成一个* 代码: program Project1; {$APPTYPE CONSOLE} uses System.SysUtils, PerlRegE ...
- 【BZOJ】1016: [JSOI2008]最小生成树计数 深搜+并查集
最小生成树计数 Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小 ...
- 今年的IT大趋势是虚拟现实
从今年下半年开始,陆陆续续出现了一些基于虚拟现实技术的创业公司,先是从IT新闻中的一篇创业故事中了解到这个方向,后来再是身边一个以前的朋友也发布了类似的产品. 从他们的产品来看,基本都是围绕教育行业开 ...
- 软件测试 -- alpha测试和beta测试的区别
alpha测试是在用户组织模拟软件系统的运行环境下的一种验收测试,由用户或第三方测试公司进行的测试,模拟各类用户行为对即将面市的软件产品进行测试,试图发现并修改错误. Beta测试是用户公司组织各方面 ...
- Python之添加新元素
现在,班里有3名同学: >>> L = ['Adam', 'Lisa', 'Bart'] 今天,班里转来一名新同学 Paul,如何把新同学添加到现有的 list 中呢? 第一个办法是 ...
- 我的PHP之旅--PHP的判断、循环语句
if语句 <?php if ($a = "some string") { // 就算括号中不是bool值,php也会自动转换为bool值 上一节写过各个类型转换bool值 / ...
- vs2013运行c语言出现:无法查找或打开 PDB 文件。
vs2013运行c语言出现:无法查找或打开 PDB 文件. “ConsoleApplication1.exe”(Win32): 已加载“C:\Users\hp\Documents\Visual ...
- ExpressionTree——让反射性能向硬编码看齐
缘起 最近又换了工作.然后开心是以后又能比较频繁的关注博客园了.办离职手续的这一个月梳理了下近一年自己写的东西,然后就有了此文以及附带的代码. 反射 关于反射,窃以为,他只是比较慢.在这个前提下,个人 ...
- python中的reduce
python中的reduce内建函数是一个二元操作函数,他用来将一个数据集合(链表,元组等)中的所有数据进行下列操作:用传给reduce中的函数 func()(必须是一个二元操作函数)先对集合中的第1 ...
- loadmore & scroll
loadmore <link rel="stylesheet" href="http://code.jquery.com/mobile/1.0.1/jquery.m ...