0
点赞
收藏
分享

微信扫一扫

只会 git log? 其实 git 还有两个好用的 log 命令

git log 是经常用的 git 命令,用于展示 commit 历史的,除了它之外,git 还有两个 log 命令:git shortlog、git reflog。

后两个命令也很有用,但是很多人都不知道。

这篇文章我们就过一下这 3 个 git 的 log 命令吧。

用 git branch 看一下本地的分支,有 main、0.5-stable 这两个,当前在 main 分支:

只会 git log? 其实 git 还有两个好用的 log 命令_git

也就是这样的:

只会 git log? 其实 git 还有两个好用的 log 命令_前端_02

每个 commit 都有自己的 hash,并且记录着父 commit 的 hash。

分支名记录着它指向的 commit。

HEAD 指针指向当前的分支,这里就是 main 分支。

在 .git 的 HEAD 文件里也可以看到 HEAD 指针的指向:

只会 git log? 其实 git 还有两个好用的 log 命令_git_03

除了分支之外,tag 也是指向 commit 的一个指针。

比如 git tag -l 可以看到我本地有这些 tag:

只会 git log? 其实 git 还有两个好用的 log 命令_git_04

其实这些也就是指向某个 commit 的指针:

只会 git log? 其实 git 还有两个好用的 log 命令_正则_05

HEAD、branch、tag 这些都是指针,在 git 里叫做 ref。

git log 默认是打印的 HEAD 指针指向的 commit 的历史。

只会 git log? 其实 git 还有两个好用的 log 命令_Git_06

你也可以加任何一个 ref 来打印那个指针指向的 commit 的历史:

只会 git log? 其实 git 还有两个好用的 log 命令_后端_07

比如我加了 branch 的名字,那 log 的就是 0.5-stable 这个 branch 的历史。

也可以加 tag 的名字,或者某个具体 commit 的 hash 来打印它的历史:

只会 git log? 其实 git 还有两个好用的 log 命令_git_08

只会 git log? 其实 git 还有两个好用的 log 命令_Git_09

上面就是分别打印了某个 tag 的、某个 commit 的历史。

git log 支持一些 option 来对输出的 log 做限定。

比如你可以根据作者过滤:

git log --author="xxx"

只会 git log? 其实 git 还有两个好用的 log 命令_后端_10

支持模糊搜索。

你也可以根据 commit 的内容来过滤:

git log --grep="xxx"

只会 git log? 其实 git 还有两个好用的 log 命令_git_11

--grep 和 --author 不一样,它是支持正则的,你可以根据正则来过滤 commit message

比如这样:

git log --grep="Add.*runtime"

就是过滤 commit message 里有 Add 开头、中间任意个字符然后加 runtime 的 commit:

只会 git log? 其实 git 还有两个好用的 log 命令_Git_12

因为支持了正则,所以这个 --grep 是挺强大的。

此外,还可以根据时间来过滤,比如:

git log --after="2022-01-01" --before="2022-01-31"

就可以过滤 2022 年 1 月份的 commit:

只会 git log? 其实 git 还有两个好用的 log 命令_Git_13

这里的 --before、--after 可以换成 --until、--since,一样的含义。

我个人更习惯 before、after。

除了过滤之外,还可以控制打印的格式,比如:

git log --format="%h %as %s %an"

这里的 %h 是缩写的 commit hash,%as 是日期的一种格式,%s 是 commit 的主题,%an 是 commit 的作者。

打印出来的就是这样的:

只会 git log? 其实 git 还有两个好用的 log 命令_前端_14

我们可以给它加上一些换行,通过 %n:

git log --format="hash: %h %n日期: %as %n主题: %s %n作者: %an %n"

就是这样的:

只会 git log? 其实 git 还有两个好用的 log 命令_正则_15

还可以用 %Cred %Creset 包裹来把中间字符串变红,或者 %Cblue %Creset 包裹,把中间字符串变蓝:

git log --format="hash:%Cred %h %Creset%n日期: %as %n主题:%Cblue %s %Creset%n作者: %an %n"

效果是这样的:

只会 git log? 其实 git 还有两个好用的 log 命令_后端_16

具体有哪些变量、哪些颜色,可以去看文档。

总之,log 输出的格式和颜色是可以控制的。

学了这些 option 之后,我们来做个综合的需求吧。

周会的时候,我想看看某个同学上一周的 commit,应该怎么做呢?

比如这样:

git log --author="guang" --after="2022-01-01" --before="2022-01-07"

这样其实有问题,因为他可能不是在 main 分支开发的,可能是在某个 feture 分支开发的,然后合并到了 main。

如何查看他在所有分支的过去一周的 commit 呢?

加个 --all 就好了:

git log --author="guang" --after="2022-01-01" --before="2022-01-07" --all

但这里面免不了多了一个 merge 的 commit,而这些 commit 其实没啥具体内容。

所以可以加个 --no-merges。

--merges 是只保留 merge 的 commit:

只会 git log? 其实 git 还有两个好用的 log 命令_Git_17

--no-merges 正好反过来,只保留非 merge 的 commit:

只会 git log? 其实 git 还有两个好用的 log 命令_前端_18

所以可以这样写:

git log --author="guang" --after="2022-01-01" --before="2022-01-07" --all --no-mreges

这就是 guang 在 2022-01-01 到 2022-01-07 这一周的在所有分支的 commit(排除了 merge 的 commit)。

但我如果想看所有同学的一周的 commit 这样也太麻烦了吧。

有没有什么按照人来分组统计的命令呢?

还真有,就是 git shortlog。

只会 git log? 其实 git 还有两个好用的 log 命令_后端_19

它展示的就是每个作者提交了多少个 commit,都是啥。

是一个 git log 的统计结果。

默认是按照作者名的字母顺序来排列的,也可以按照 commit 数来倒序排列:

git shortlog -n

只会 git log? 其实 git 还有两个好用的 log 命令_正则_20

这样我如果想看某段时间内,谁提交了哪些 commit,就可以这样写:

git shortlog -n --after="2022-01-01" --before="2022-01-31" --all --no-merges

就是输出在 2022-01-01 到 2022-01-31 这一个月内,所有人的 commit 的统计结果,包含所有分支的除去 merge commit 的 commit,按照 commit 数倒序排列。

只会 git log? 其实 git 还有两个好用的 log 命令_git_21

这里的 log 也可以修改格式:

git shortlog -n --after="2022-01-01" --before="2022-01-31" --all --no-merges --format="%h %as %s"

比如我只要 hash、日期、主题,就可以 --format="%h %as %s"

只会 git log? 其实 git 还有两个好用的 log 命令_前端_22

总之, git log 是查看 commit 历史的,而 git shortlog 是查看分组的统计结果的。

那 git reflog 是干啥的呢?

它是记录 ref 的修改历史的。

什么 ref 前面讲过了,branch、HEAD、tag 这些都是。

比如你新增了一个 commit、新建了一个 branch、新增了一个 tag、刚 pull 下来一个分支,这些都是对 ref 的修改。

git 会把它记录在 reflog 里。

只会 git log? 其实 git 还有两个好用的 log 命令_前端_23

比如这里的新的 commit、reset 到历史 commit、checkout 新分支等都是 ref 的变动。

只会 git log? 其实 git 还有两个好用的 log 命令_前端_24

但默认只显示 HEAD 指针的变化历史。

想看到所有分支的 ref 变化历史,可以加个 --all。

只会 git log? 其实 git 还有两个好用的 log 命令_后端_25

这样就多了别的分支的 ref 变化历史:

只会 git log? 其实 git 还有两个好用的 log 命令_前端_26

有的同学可能会问,记录 ref 变化历史干啥用?

比如说当你 git reset 到了一个之前的分支,又想恢复回去,这时候不知道之前的那个 commit 的 hash 是啥了。

这时候就可以看 reflog 里的 ref 变化历史,找到之前的 commit 的 hash。

然后 git reset 到那个 hash。

这就是 git reflog 的作用。

那这些 reflog 保存在哪里呢?

在 .git 的 logs/refs 目录下:

只会 git log? 其实 git 还有两个好用的 log 命令_Git_27

比如 HEAD 的 reflog,对比下是不是一毛一样(顺序是反的):

只会 git log? 其实 git 还有两个好用的 log 命令_正则_28

这里就是 reflog 保存的地方。

总结

git 有 3 个 log 命令:git log、git shortlog、git reflog。

git log 是查看 commit 历史的,可以指定 branch、tag、某个 commit 等来查看对应的 commit 历史。

可以通过 --author、--before、--after、--grep、--merges、--no-merges、--all 来过滤某个作者、某段时间内、某个 commit 内容、非 merge 的 commit、全部分支的 commit 等 commit。

还可以通过 --format 来指定输出的颜色和格式。

git shortlog 是 git log 的统计结果,可以按照作者来分组统计。比如查看上一周每个人提交了多少个 commit。

git reflog 记录的是 ref 的变化历史,比如分支切换、reset、新的 commit 等都会记录下来。

可以通过 git reflog 命令来查看,也可以直接在 .git/logs/refs 下查看。

git 的 3 个 log 命令各有各自的用途,都是很常用的 git 命令。

举报

相关推荐

0 条评论