Git笔记(三)– 浏览历史

​本文介绍浏览项目历史的各种方法。我们将学习如何搜索历史提交记录,例如按作者、日期、消息查找,我们还将了解如何将项目恢复到较早的时间点,如何比较各个提交以查看已更改的文件,如何查看文件的历史记录,查看它从最初开始的变化情况以及谁编写了每一行代码。并将向您展示一个很棒的工具,用于快速查找应用程序中的错误提交。


获取存储库

访问https://pan.baidu.com/s/1CKWdXi9dpz-6Vb0rEkHmAA,提取码是u4zc ,获取venus.zip文件,解压。venus目录作为本文的示例项目。


查看历史记录

我们已学过查看快照历史记录的简单用法,进入Venus目录,键入 git log 能看到相关信息,信息较多的话,按空格可以向下翻页,上下箭头可以上下翻页,中途退出则按q。

如果要查看每次提交的差异,需加上 –stat参数。

git log –oneline –stat 

通过加 –stat参数,我们能到每次提交文件修改的汇总信息。比如最新一次提交,5个文件被修改,共7行插入,4行删除。很多时候不加 –oneline只用 –stat可以查看更详细的修改信息。

使用 –patch参数可以进一步查看每次提交文件内容的变化。

git log –oneline –patch


过滤历史记录

实际项目通常有上百甚至上千条提交记录,可以通过作者、日期、提交的备注信息、内容等进行查找。

只显示最近3条提交:

git log –oneline -3 

查找作者为Mosh的提交:

git log –oneline –author=”Mosh”

查找在2020-08-17日及之前的提交记录:

 git log –oneline –before=”2020-08-17″

除了before也可以使用after,意思是给定的日期及之后的提交。除了确定的日期,也可以使用相对的日期,比如yesterday、one week ago、two days ago、one month ago,等等。

git log –oneline –befor=”one week ago”

查找备注信息有特定关键字的提交:

git log –oneline –grep=”GUI”

注意是大小写敏感的,如果写成 gui 查找到的内容是不一样的。

也可以根据提交的内容进行查找,比如查找我们在哪个提交里添加了某个函数。

git log –oneline -S”OBJECTIVES”

可以添加 –patch参数查看具体的修改内容。

git log –oneline -S”OBJECTIVES” –patch

可以查看某个范围内的提交记录。

git log –oneline fb0d184..edb3594

可以查看涉及某个文件或多个文件的提交,直接加上文件名即可。

git log –oneline toc.txt

为了区分参数和文件,可以加上 — 进行分隔,如下:

git log –oneline — toc.txt

如果也要查看具体的更改,可以加上 –patch,但注意要加在分隔的文件前面,不能加在后面。

git log –oneline –patch — toc.txt


格式化输出

我们可以使用–pretty=format 再加上一些占位符格式化输出。

比如占位符%an表示作者,%H表示提交的完整Hash,如果使用%h则表示简短的hash码。

git log –pretty=format:”%an committed %H”

再看,%cd表示时间。

git log –pretty=format:”%an committed %h on %cd”

我们也可以用占位符%C<COLOR>将输出进行着色,比如我们想让作者显示绿色,而其他保持不变。

git log –pretty=format:”%Cgreen%an%Creset committed %h on %cd”

更多的占位符可以查看Git官网。

https://git-scm.com/docs/git-log


别名

使用别名,可以将常用的长命令设置为短小的名字,方便输入且避免出错。比如:

git config –global alias.lg “log –pretty=format:’%an committed %h'”

我们将 log –pretty=format:’%an committed %h’ 设为别名 lg,可以查看设置确认。

git config –global -e

设置完成后,我们就可以用 git lg 格式化成我们要输出的格式了。

我们可以再设一个有用的别名

git config –global alias.unstage “restore –staged .”

当我们需要取消暂存时,执行 git unstage 即可。


查看提交

我们已知道查看提交使用的是 git show 命令,可以通过提供某个提交ID或HEAD~2这种表示查看具体的提交。

git show后面再提供文件名可以查看该提交的改动后版本。

git show HEAD~2:sections/creating-snapshots/staging-changes.txt

通过提供 –name-only 参数,只显示变动的文件名,而 –name-status 则同时显示文件变动的状态,比如M 表示被修改。

git show HEAD~2 –name-only

git show HEAD~2 –name-status


查看跨提交的更改

有时候需要查看多个提交后的变化,比如我们想查看最后第三个提交(HEAD~2)到当前提交(HEAD)之间的变化,可以使用git diff命令,并跟上这两个提交。

git diff HEAD~2 HEAD

如果仅查看这三个提交间的audience.txt文件的变化,再带上文件名即可。

git diff HEAD~2 HEAD audience.txt

同样的,我们可以添加 –name-only和 –name-status参数。

git diff HEAD~2 HEAD –name-only

git diff HEAD~2 HEAD –name-status


签出提交

恢复工作到之前的快照,使用git checkout 命令。

用git log –oneline 检查存储库的快照,比如有一个快照的ID是dad47ed,就可以使用命令恢复。

git checkout dad47ed

Git警告目前处于“detached HEAD ”的状态,这是什么意思?

存储库的各次提交是链式存储的,第个提交总是指向前一个提交,这种结构能让Git维护历史记录。存储库可以有多个分支,用于实现不同的功能。Master是主分支或者叫主线,它是默认的分支,有些版本控制系统称其为Trunk。

HEAD是一个指针,指明当前工作的分支是哪个,我们这个例子里,当前工作分支是Master。

通过git checkout dad47ed命令,我们将HEAD指向了dad47ed这个提交。

这种情况下,HEAD与分支Master是分离的,所以Git给出了警告。

在HEAD与分支分离的情况下,我们不应该创建提交,一般只用于查看代码。如果再创建提交的话,就会建在当前分离的HEAD之上。后面我们将HEAD指回分支MASTER,刚新建的提交将无法访问。

我们应该经常性检查这些无法访问的“死”提交,及时清除节省空间。

再用git log –oneline 检查,发现只能看到HEAD指向的及其前面提交的快照了。

如果想查看所有的提交,则需要加上 –all参数。

git log –oneline –all

我们也能看到HEAD与分支master是分离的。

如果让HEAD重新指向分支,很简单,执行:

git checkout master


使用 Bisect 查找错误

假如我们多次提交后,运行应用程序发现有错误,我们想查找是哪一次提交将这个错误带进来。我们可不想逐个签出来查看。

使用Bisect命令,我们可以快速地找到到底哪一个提交引进错误。首先启动它。

git bisect start

假设我们知道提交第一个快照时应用程序是正常的,那么目前我们知道的信息是:第一次正常,最后一次有错误。把这个信息告知Bisect。

git bisect bad

git bisect good  ca49180

第一句告知bisect 当前的提交(即最后的提交)是有错误的,第二句告知bisect 第一条提交(它的id是ca49180)是无错的。

bisect将指针指向正确(第一条)和错误(最后一条)的中间位置,并告诉我们大概还要测试的步骤和提交数。

当前的指针与master是分离的,我们可以运行测试应用程序,查看当前指针的快照是否有错。如果有错,说明是第一条提交至当前指针之间有错误,我们就需要再测试这一部分的提交,而后面提交的快照则不必测试。如果没错,说明当前指向的提交和前面的提交都是正确的,不必再作测试,我们需要测试后面的提交。

我们就假定经测试后当前指针指向的快照是正确的。告诉bisect。

git bisect good

bisect再一次告诉我需要测试的历史记录以及测试的步数。同时指针再向上移至中间位置。

再一次,我们测试应用程序,假设也是正常的。告知bisect。

git bisect good

bisect 继续向上移动指针到中间    ,我们再测试应用程序。假设也正常。我们继续告诉bisect

git bisect good

这下指针就移到最后一条的前一条了,gitsect提示没有其他提交的快照要测试了。我们再运行测试应用程序,发现有错误。于是我们告诉bisect。

git bisect bad

指针这次向下移动到中间条,再测试,假设应用程序出错了。于是再告诉bisect。

git bisect bad

于是Bisect找到首次提交有错的快照,同时列出详细的信息。

完成查找后返回分支master。

git bisect reset


使用Shortlog寻找贡献者

通过 git shortlog 可以查找到项目的贡献者。添加参数 -h 可以查看用法。

git shortlog -h

添加 -n 参数所有作者的提交进行排序。

git shortlog -n

添加 -s 可以隐藏提交信息,只查看作者

git shotlog -n -s

添加 -e 可以查看每个作者的Email。

git shortlog -n -s -e

还可以进行筛选,比如使用 –before 或 –after 参数来筛选某些时间段的提交信息。

git shortlog -n -s -e –before=”” –after=””


查看文件历史记录

项目里有个toc.txt文件,我们想查看对该文件有修改的历史记录,该如何操作?前面有谈到过,在git log 后添加 文件名即可。

git log toc.txt

希望单行显示,就添加 –oneline 参数。

git log –oneline toc.txt

查看修改的汇总信息,添加 –stat 参数。

git log –oneline –stat toc.txt

查看修改的详细内容,添加 –patch 参数。

git log –oneline –patch toc.txt


恢复删除的文件

假设我们不小心删除了某个文件如toc.txt,如何恢复?

模拟删除文件:git rm toc.txt ,并提交到存储库:git commit -m “Remove toc.txt”。

首先,我们得找到与toc.txt文件有关的快照提交记录。

git log –oneline toc.txt

可能会提示错误,因为最后一次删除的操作后找不到toc.txt文件,可以使用

git log –oneline — toc.txt

最后一个与toc.txt有关的提交就是该文件被删除,该快照是不存在toc.txt的,所以要签出它的前一个快照的toc.txt文件,这里前一个快照ID是a642e12。

git checkout a642e12 toc.txt

查看状态,并进行提交。

git status -s

git commit -m “Restore toc.txt”

这就是恢复删除文件的大致方法。


使用 Blame 查找代码作者

审查项目时发现有些代码臭不可言,可能想知道作者是谁,blame命令可以帮助我们。比如我们审查audience.txt文件。

git blame audience.txt

如果想知道作者的Email,可以添加 -e 参数。

git blame -e audience.txt 

当文件很大,我们不想查看所有行,可以通过大写的 -L 加首末行过滤。比如下面的命令只查看前3行的作者。

git blame -e -L 1,3 audience.txt


标记Tagging

有时候需要在项目的某些确定的历史提交点设置标记,比如V1.0,表示版本1.0。比如给当前的提交点打标记。

git tag v1.0

如果要在之前的提交点设置标签,可以带上提交id。

git tag v1.0 5e7a828

通过git log –oneline可以看到标记信息。

可以使用标记代替ID,比如签出。

git checkout v1.0

查看所有标记点,使用git tag。

git tag

默认创建的标记称为轻量标记,另一种是注释标签(annotated tag),它可以有一些属性比如标记名、email以及备注信息等。创建方法是加 -a 参数。

git tag -a v1.1 -m “My version 1.1”

上面的 -m 用于添加了说明信息。

通过 git tag 可以查看当前的标记列表,添加 -n 参数可以查看说明信息。

git tag -n

我们用git show 查看注释标记 v1.1,可以看到顶部有一些标记信息。

git show v1.1

一般而言,我们比轻量标记更喜欢使用注释标记。

删除标记使用 -d 参数

git tag -d v1.1


使用 VSCode 查看历史

在VSCode里查看历史,可以安装 GitLens插件。

GitLens可以完成大部分前面我们介绍的功能,但也有些限制,比如筛选快照只能使用单个条件,又比如没有bisect功能等等。


使用 GitKraken 浏览历史记录

使用GitKraken,可以查看提交列表,查找各次列表,标记提交,比较跨提交的差异等。

但就像之前说过的,图形工具相比命令行工具,总有些限制。GitKraken也不能多条件过滤查找历史记录。

GitKraken有一个小技巧需要提一下。利用Command + p 可以快捷执行一些Git命令。读者可以实际体会下,这里不赘述。


小结

本文介绍浏览项目历史的各种方法,包括如何搜索历史提交记录,如何将项目恢复到较早的时间点,如何比较各个提交以查看已更改的文件,如何查看文件的历史记录,并展示如何快速查找应用程序中的错误提交等。

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注