草庐IT

Git log 进阶用法(含格式化、以及数据过滤)

Jay.... 2023-04-10 原文

🏆 文章目标:了解学习进阶的Git log用法,用于解决产品发版时的一些需求。
🍀 Git log 进阶用法(含格式化、以及数据过滤)
✅ 创作者:Jay…
🎉 个人主页:Jay的个人主页
🍁 展望:若本篇讲解内容帮助到您,请帮忙点个赞吧,您的支持是我继续写作的最大动力,谢谢。🙏

需求

这篇文章由需求引发的学习,下面是关于Git log的常见需求,大家可以带着这几点疑问,了解Git log的使用方式,主要包含格式化,和数据过滤:

  1. 系统发版时,想要针对特定时间,获取所有的提交记录?
  2. 查看某个人的提交记录,且忽略合并的记录?
  3. 查看提交记录,并且按照自定义格式输出,如 提交信息 提交人

方案

为节省大家的时间,有对应需求的朋友,可以直接使用如下命令。感兴趣的朋友可以继续阅读,了解并使用其他方式。

1、系统发版时,想要针对特定时间,获取所有的提交记录?

 git log --oneline --after="2023-3-20" --before="2023-3-27"

2、查看某个人的提交记录,且忽略合并的记录?

 git log --oneline --no-merges --author jay 

3、查看提交记录,并且按照自定义格式输出,如 提交信息 提交人

 git log --oneline --pretty=format:"%cn && %s" 

格式化

当需要回顾Git 的Log提交日志时,可以参考如下案例,并可以按照需求格式化Log日志。如下为几种常见的输出案例。

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

常用的格式选项有:

格式选项输出结果描述
%H提交对象的散列值,即:校验和
%h提交对象的简短的散列值
%T树对象的散列值
%t树对象的简短的散列值
%P父对象的散列值
%p父对象的简短的散列值
%an作者的名称
%ae作者的邮箱
%ad创作的日期,可使用-data=<选用指定日期格式>
%ar相当于当前日期的创作日期
%cn提交者的名称
%ce提交者的邮箱
%cd提交日期
%cr相当于当前日期的提交日期
%s提交信息的主题(相当于提交时附加的内容)

除了让你只看到关注的信息,这个--pretty=format:"<string>" 选项在你想要在另一个命令中使用日志内容是尤为有用的。

数据过滤

格式化提交输出只是git log其中的一个用途。另一半是理解如何通过一些条件或参数过滤提交历史中的数据。接下来会介绍一些案例:

所有的用法都可以和上面讨论过的格式化选项结合起来。

按数量

git log最基础的过滤选项是限制显示的提交数量。当你只对最近几次提交感兴趣时,它可以节省你一页一页查看的时间。

你可以在后面加上-选项。比如说,下面这个命令会显示最新的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.pybar.py文件相关的提交:

git log -- foo.py bar.py

–告诉git log接下来的参数是文件路径而不是分支名。如果分支名和文件名不可能冲突,你可以省略–。

按内容

我们还可以根据源代码中某一行的增加和删除来搜索提交。这被称为pickaxe,它接受形如-S""的参数。比如说,当你想要知道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 进阶用法(含格式化、以及数据过滤)的更多相关文章

  1. ruby - 使用 ruby​​ 将 HTML 转换为纯文本并维护结构/格式 - 2

    我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h

  2. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  3. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  4. ruby - Ruby 有 `Pair` 数据类型吗? - 2

    有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳

  5. ruby-on-rails - 将 Ruby 中的日期/时间格式化为 YYYY-MM-DD HH :MM:SS - 2

    这个问题在这里已经有了答案:Railsformattingdate(4个答案)关闭4年前。我想格式化Time.Now函数以显示YYYY-MM-DDHH:MM:SS而不是:“2018-03-0909:47:19+0000”该函数需要放在时间中.现在功能。require‘roo’require‘roo-xls’require‘byebug’file_name=ARGV.first||“Template.xlsx”excel_file=Roo::Spreadsheet.open(“./#{file_name}“,extension::xlsx)xml=Nokogiri::XML::Build

  6. ruby - 我可以将我的 README.textile 以正确的格式放入我的 RDoc 中吗? - 2

    我喜欢使用Textile或Markdown为我的项目编写自述文件,但是当我生成RDoc时,自述文件被解释为RDoc并且看起来非常糟糕。有没有办法让RDoc通过RedCloth或BlueCloth而不是它自己的格式化程序运行文件?它可以配置为自动检测文件后缀的格式吗?(例如README.textile通过RedCloth运行,但README.mdown通过BlueCloth运行) 最佳答案 使用YARD直接代替RDoc将允许您包含Textile或Markdown文件,只要它们的文件后缀是合理的。我经常使用类似于以下Rake任务的东西:

  7. ruby - 是否有用于序列化和反序列化各种格式的对象层次结构的模式? - 2

    给定一个复杂的对象层次结构,幸运的是它不包含循环引用,我如何实现支持各种格式的序列化?我不是来讨论实际实现的。相反,我正在寻找可能会派上用场的设计模式提示。更准确地说:我正在使用Ruby,我想解析XML和JSON数据以构建复杂的对象层次结构。此外,应该可以将该层次结构序列化为JSON、XML和可能的HTML。我可以为此使用Builder模式吗?在任何提到的情况下,我都有某种结构化数据-无论是在内存中还是文本中-我想用它来构建其他东西。我认为将序列化逻辑与实际业务逻辑分开会很好,这样我以后就可以轻松支持多种XML格式。 最佳答案 我最

  8. ruby-on-rails - 事件管理员日期过滤器日期格式自定义 - 2

    是否有简单的方法来更改默认ISO格式(yyyy-mm-dd)的ActiveAdmin日期过滤器显示格式? 最佳答案 您可以像这样为日期选择器提供额外的选项,而不是覆盖js:=f.input:my_date,as::datepicker,datepicker_options:{dateFormat:"mm/dd/yy"} 关于ruby-on-rails-事件管理员日期过滤器日期格式自定义,我们在StackOverflow上找到一个类似的问题: https://s

  9. ruby - 我如何添加二进制数据来遏制 POST - 2

    我正在尝试使用Curbgem执行以下POST以解析云curl-XPOST\-H"X-Parse-Application-Id:PARSE_APP_ID"\-H"X-Parse-REST-API-Key:PARSE_API_KEY"\-H"Content-Type:image/jpeg"\--data-binary'@myPicture.jpg'\https://api.parse.com/1/files/pic.jpg用这个:curl=Curl::Easy.new("https://api.parse.com/1/files/lion.jpg")curl.multipart_form_

  10. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

随机推荐