LV01-Git-04-Git本地仓库-03-提交历史

本文主要是Git中查看提交历史记录的相关笔记,若笔记中有错误或者不合适的地方,欢迎批评指正😃。

点击查看使用工具及版本
Windows windows11
Ubuntu Ubuntu16.04的64位版本
VMware® Workstation 16 Pro 16.2.3 build-19376536
点击查看本文参考资料
点击查看相关文件下载
--- ---

【说明】本节笔记的相关操作在Windows下进行,因为VS Code有个Git的插件,可以很直观的演示一些东西。由于Git安装后自带一个Git-Bash终端,所以就不用Win下的命令行啦,就用的这个终端,因为它里边的命令与Linux很类似,而windows中的命令行有些命令与linux并不相同,为了统一,还是用用Git自带的终端啦。另外VS Code是可以选择使用的终端的,我直接将VS Code使用的终端改成了git-bash,这样更方便一些。

一、获取一个仓库

在 Pro Git Book 这本书中,有一个项目仓库作为提交记录查看的示例项目,我们将这个仓库clone下来:

1
git clone https://github.com/schacon/simplegit-progit

然后我们便会得到一个仓库:

image-20230622172904295

二、git log

1. 命令说明

这个就直接输入就好了:

1
git log [可选选项]

2. 可选选项

git log 的常用选项 列出了我们目前涉及到的和没涉及到的选项,以及它们是如何影响 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(用来定义自己的格式)。
--oneline --pretty=oneline --abbrev-commit 合用的简写。

3. 使用实例

当我们在此项目中运行 git log 命令时,可以看到下面的输出:

image-20230622173043768

不传入任何参数的默认情况下,git log 会按时间先后顺序列出所有的提交,最近的更新排在最上面。 正如所看到的,这个命令会列出每个提交的 SHA-1 校验和、作者的名字和电子邮件地址、提交时间以及提交说明。SHA-1 校验和也叫hash值,其实就代表了可以这一次的提交,每一次提交都会有这样一个独一无二的hash值。

三、git log -p

1. 命令说明

一个比较有用的选项是 -p--patch ,它会显示每次提交所引入的差异(按 补丁 的格式输出)。

1
git log -p [-n]

-n是可选的,其中 n 可以限制显示的日志条目数量,可以是任何整数,表示仅显示最近的 n 条提交。例如使用 -2 选项可以只显示最近的两次提交。该选项除了显示基本信息之外,还附带了每次提交的变化。 当进行代码审查,或者快速浏览某个搭档的提交所带来的变化的时候,这个参数就非常有用了。

2. 使用实例

我们显示一下最近一次提交记录:

1
git log -p -1

然后我们会看到如下信息:

image-20230622173508354

四、git log –stat

1. 命令说明

我们也可以为 git log 附带一系列的总结性选项。 比如要是我们想看到每次提交的简略统计信息,可以使用 --stat 选项:

1
git log --stat

2. 使用实例

我们在仓库中敲以下命令:

1
git log --stat

然后我们会得到以下信息:

image-20230622173911174

正如所看到的,--stat 选项在每次提交的下面列出所有被修改过的文件、有多少文件被修改了以及被修改过的文件的哪些行被移除或是添加了。 在每次提交的最后还有一个总结。

五、git log –pretty

1. 命令说明

另一个非常有用的选项是 --pretty。 这个选项可以使用不同于默认格式的方式展示提交历史。 这个选项有一些内建的子选项供我们使用。 比如 oneline 会将每个提交放在一行显示,在浏览大量的提交时非常有用。 另外还有 shortfullfuller 选项,它们展示信息的格式基本一致,但是详尽程度不一,一般的格式如下:

1
coption

2. oneline

我们来看一下option为oneline的时候,显示的提交记录的样式:

1
2
3
git log --pretty=oneline
# 也可以写成这样
git log --oneline # 把每一个提交信息压缩为一行

然后我们会看到以下输出信息:

image-20230622174320608

3. format

3.1 一般格式

这个参数可以定制记录的显示格式。 这样的输出对后期提取分析格外有用——因为我们知道输出的格式不会随着 Git 的更新而发生改变:

1
git log --pretty=format:"%h - %an, %ar : %s"

然后我们会看到如下输出信息:

image-20230622174535805

3.2 常用选项

git log --pretty=format 常用的选项 列出了 format 接受的常用格式占位符的写法及其代表的意义。

选项 说明
%H 提交对象(commit)的完整哈希字串
%h 提交对象的简短哈希字串
%T 树对象(tree)的完整哈希字串
%t 树对象的简短哈希字串
%P 父对象(parent)的完整哈希字串
%p 父对象的简短哈希字串
%an 作者(author)的名字
%ae 作者的电子邮件地址
%ad 作者修订日期(可以用 -date= 选项定制格式)
%ar 作者修订日期,按多久以前的方式显示
%cn 提交者(committer)的名字
%ce 提交者的电子邮件地址
%cd 提交日期( --date = 制定的格式)
%cr 提交日期,按多久以前的方式显示(1 day ago)
%s 提交说明
%d ref 名称
%n 换行
【说明】

(1)在选项前边加上 %C(color) 则可以分别指定输出内容的颜色, color 可选的值有 reset(默认的灰色),normal, black, red, green, yellow, blue, magenta, cyan, white 。另外说明一点就是 color 最好就是可以**带上圆括号 () **,这样既清晰,也不会出错。

(2)作者 和 提交者 之间究竟有何差别, 其实作者指的是实际作出修改的人,提交者指的是最后将此工作成果提交到仓库的人。 所以,当我们为某个项目发布补丁,然后某个核心成员将我们的补丁并入项目时,我们就是作者,而那个核心成员就是提交者。

3.3 自定义颜色实例

1
git log --pretty=format:"%Cgreen%an %Cred%h %Cblue%s"      # 以不同颜色显示提交者名字、提交说明和简短的哈希字符串

效果如下:

image-20230622175441377

六、git log –graph

1. 一般用法

这个 log 选项 --graph 一般与 onelineformat 或者--decorate结合使用。 这个选项添加了一些 ASCII 字符串来形象地展示我们的分支、合并历史,一般用法如下:

1
2
git log --graph --oneline --decorate   # 绘制一幅表示分支结构提交历史的ASCII图 
git log --pretty=format:"%h %s" --graph

2. 使用实例

我们可以使用上边的命令来查看仓库提交历史的ASCII图:

1
git log --graph --oneline --decorate

但是这个示例仓库提交不够多,也没有分支合并之类的,效果如下:

image-20230622175619629

我看手册上是提供了另一个仓库的ASCII图,这里写一下作为参考吧:

1
2
3
4
5
6
7
8
9
10
11
$ 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输出

1. 过滤指定的提交记录

除了定制输出格式的选项之外,git log 还有许多非常实用的限制输出长度的选项,也就是只输出一部分的提交。 我们可以使用类似 git log -p -<n> 的选项,其中的 n 可以是任何整数,表示仅显示最近的 n 条提交。 不过实践中这个选项不是很常用,因为 Git 默认会将所有的输出传送到分页程序中,所以我们一次只会看到一页的内容。

但是,类似 --since--until 这种按照时间作限制的选项很有用。 例如,下面的命令会列出最近两周的所有提交:

1
git log --since=2.weeks

该命令可用的格式十分丰富——可以是类似 "2008-01-15" 的具体的某一天,也可以是类似 "2 years 1 day 3 minutes ago" 的相对日期。

我们其实还可以过滤出匹配指定条件的提交。例如 用 --author 选项显示指定作者的提交,用 --grep 选项搜索提交说明中的关键字。我们可以指定多个 --author--grep 搜索条件,这样会只输出匹配 任意 --author 模式和 任意 --grep 模式的提交。然而,如果我们添加了 --all-match 选项, 则只会输出匹配 所有 --grep 模式的提交。

还有一个非常有用的过滤器是 -S(俗称“pickaxe”选项,取“用鹤嘴锄在土里捡石头”之意), 它接受一个字符串参数,并且只会显示那些添加或删除了该字符串的提交。 假设我们想找出添加或删除了对某一个特定函数的引用的提交,可以调用:

1
git log -S function_name

2. 常用的限制选项

选项 说明
-<n> 仅显示最近的 n 条提交。
--since, --after 仅显示指定时间之后的提交。
--until, --before 仅显示指定时间之前的提交。
--author 仅显示作者匹配指定字符串的提交。
--committer 仅显示提交者匹配指定字符串的提交。
--grep 仅显示提交说明中包含指定字符串的提交。
-S 仅显示添加或删除内容匹配指定字符串的提交。

3. 使用实例

如果要在 Git 源码库中查看 Junio Hamano 在 2008 年 10 月其间, 除了合并提交之外的哪一个提交修改了测试文件,可以使用下面的命令:

1
2
3
4
5
6
7
$ git log --pretty="%h - %s" --author='Junio C Hamano' --since="2008-10-01" --before="2008-11-01" --no-merges -- t/
5610e3b - Fix testcase failure when extended attributes are in use
acd3b9e - Enhance hold_lock_file_for_{update,append}() API
f563754 - demonstrate breakage of detached checkout with symbolic link HEAD
d1a43f2 - reset --hard/read-tree --reset -u: remove unmerged new paths
51a94af - Fix "checkout --track -b newbranch" on detached HEAD
b0ad11e - pull: allow "git pull origin $something:$current_branch" into an unborn branch

在近 40000 条提交中,上面的输出仅列出了符合条件的 6 条记录。

八、自定义提交历史记录

1. 定制 git log

1
2
3
4
# 个人定制版 git log
git log --graph --pretty=format:'%C(magenta)[%an]%C(reset) %C(red)%h%C(reset) : %C(green)%s%C(reset) %C(yellow)%d%C(reset) %C(blue)(%cr)%C(reset) ' --abbrev-commit --date=relative # 相对时间

git log --graph --pretty=format:'%C(magenta)[%an]%C(reset) %C(red)%h%C(reset) : %C(green)%s%C(reset) %C(yellow)%d%C(reset) %C(blue)(%cd)%C(reset) ' --abbrev-commit --date=format:'%Y-%m-%d %H:%M:%S' # 绝对时间

【说明】一般来说 format 后边跟的是双引号 " ,但是若想使用 alias 创建自定义命令的话,需要改为**单引号 ' **,否则会报错。

2. 自定义一个git log命令

上边的输入不免有些麻烦,每次都要输入这个么一长串命令嘛?Git其实是支持我们自定义命令的。

2.1 自定义方法一:修改 ~/.gitconfig 文件

linux中这个文件就在~/.gitconfig,在windows中,文件位于"C:\Users\<用户名>\.gitconfig"

1
vim ~/.gitconfig

打开后在结尾处添加以下内容:

1
2
[alias]
mylog = log --graph --pretty=format:'%C(magenta)[%an]%C(reset) %C(red)%h%C(reset) : %C(green)%s%C(reset) %C(yellow)%d%C(reset) %C(blue)(%cd)%C(reset) ' --abbrev-commit --date=format:'%Y-%m-%d %H:%M:%S'

2.2 自定义方法二:命令行输入

1
git config --global alias.mylog "log --graph --pretty=format:'%C(magenta)[%an]%C(reset) %C(red)%h%C(reset) : %C(green)%s%C(reset) %C(yellow)%d%C(reset) %C(blue)(%cd)%C(reset) ' --abbrev-commit --date=format:'%Y-%m-%d %H:%M:%S'"

其实这个样子配置的话,最后也是修改的家目录下的.gitconfig文件。

3. 运行自定义命令

1
git mylog

4. 实现效果

最终实现的效果如下:

image-20230622181340614