查看提交记录

Git 做为版本管理工具,最重要的特色之一就是强大的记录查询,可以花式查看各种提交历史和变动,同时也支持过滤和筛选。本章主要介绍 logdiff 等工具的使用

Log

通过 git log 命令可以查看过去的提交记录。这个命令非常常用,但也非常复杂,常见的有以下几种:

基础命令

在我的配置中,输入 gg,它会单行展示提交历史,也支持展示分支的关系,如图所示。

它的完整命令是:

alias gg='git lg'

lg 命令可以通过上一节介绍的 gitconfig 来配置:

[alias]
    lg = log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%ci) %C(bold blue) <%an>%Creset' --abbrev-commit

常用拓展

如果只想简单的查看提交历史,使用 gg 命令就足够了。但如果想查看更细的内容,gg 就不太够用了。我们可以输入 ggs 命令,它在 gg 的基础上会展示每次提交具体改动的文件,等价于命令 gg --stat,如图所示:

如果想查看某次提交具体的变动,可以使用 ggp 命令。它在 gg 的基础上会展示文件的具体改动,等价于命令 gg -p,如图所示

进阶使用

  1. 输入 gga,可以展示所有的分支,一般建议用它代替 gg,它等价于命令 gg --all
  2. 不管是gg,还是衍生出来的 ggsggp,后面都可以加上 -n,比如 ggs -2,或者 ggp -1,表示只显示前 n 个提交
  3. 如果想看某一个区间内的 log,可以输入 gg HEAD~3..HEAD,注意区间是左开右闭,所以这个命令会查看三次提交的记录。注意较早的提交要写在左边。
  4. 如果只记得某次提交内容(content)里有一个词,比如 networksetup,可以用 ggp -G networksetup 来查找所有提交内容中包含 networksetup 的提交。-G 选项和 -S 选项主要有两个区别, 前者可以接收正则,而后者只会查找那些导致 string 出现次数发现变动的提交,比如把 name:0 换成 name:1,用 -S 就无法搜索到 name, 因为它的出现次数并没有改变,但是用 -G 可以。
  5. 如果只记得某次提交记录(message)里有一个词,比如 highlight,可以用 ggp --grep highlight 来查找所有提交记录中包含 highlight 的提交
  6. 如果想查看某个文件中某一段代码的提交记录,可以用 ggp -L start,end:file_name 命令,详情请参考 Git grep 这一节的用法。
  7. 如果想查看某个文件或者文件夹的改动历史,可以输入 gg file_name,当然 ggsggp 也都是支持的。

Diff

  1. 输入 gd 即可查看工作区内的变动,等价于命令 git diff
  2. 输入 gds 可以查看暂存区的变动,也就是查看那些被 git add 了的文件的变动,等价于命令 git diff --staged
  3. 输入 gdc 可以查看最近一次提交的变动,等价于命令 git diff HEAD^ HEAD
  4. 输入 gdcr 可以倒过来查看某次提交的变动,它的第一个参数是提交的 SHA-1 值,如果不写则是 HEAD,所以 gdcrgdc 是恰好相反的 diff。这样的好处是如果 想撤销某次提交,只要用 gdcr sha-1 就可以获得那次提交的逆提交,如果想要精确到只恢复某个文件,第二个参数可以是文件名。比如 gdcr sha-1 file_name | git apply
  5. 输入 gdt 即可用外部 diff 工具查看 diff,它是 git difftool --no-prompt --extcmd "icdiff --line-numbers --no-bold" "$@" | less 命令的缩写,这个命令依赖 icdiff 这个工具,可以用 homebrew 安装。
  6. 输入 gdtsgdtc 可以对应的用外部 diff 查看已暂存和上次提交的变动,这些和 gdsgdc 命令基本上是一样的,区别在于使用外部 diff 工具,会更美观一些(当然速度也会更慢),效果如图所示

Grep

这个命令和 grep 的区别在于运行更快,而且可以指定搜索范围(比如是否搜索未跟踪文件,搜索某个特定的 tag 等),如果当前目录是 git 目录,可以用 ggrep 来替代 grep

ggrepgit grep --break --heading -n 命令的缩写,第一个参数表示不同文件的搜索结果间用空格分割,便于阅读。第二个参数非常有用,它不再在每一行输出前面加上文件名,而是在所有属于同一个文件的匹配之前加上一次文件名, 这样输出结果的可读性更高,-n 表示输出行号。

以查找 gignore 这个命令的历史为例,先输入 ggrep gignore,得到如图所示的结果,这告诉我们它定义在 zsh-config/git.sh 这个文件的第 25 行

然后输入 ggp -L 25,25:./zsh-config/git.sh,参数 —L 表示行内查找,即查找这个文件的第 25-25 行的提交记录,得到的结果如图所示:

提交的 SHA-1 值、日期、提交者等信息就完全显示出来了

提交区间

git 的提交区间指的是用两个点 A..B 或者三个点 A...B 的语法将 AB 两个提交连接起来,从而表示一系列提交。

这是非常容易让人产生疑惑的一个话题,主要是因为它没有固定的含义,需要根据不同的命令来记忆。本文主要结合 diff、log 这两个命令来介绍。

首先,假设我们基于初始提交建立了 a 和 b 两个分支,各有一次提交,如图所示。分支 a 的提交是数字,分支 b 的提交是字母。

diff

此时,双点语法 A..B 表示对比这 AB 两个提交的差异:

git diff branch_a..branch_b

# 直接对比两个 commit
# 等价于直接写空格

git diff branch_a branch_b

这个结果还是非常符合常识的,就不多解释了。

三点语法 A...B 则表示:AB 两次提交的共同祖先和 B 之间的 diff

git diff branch_a...branch_b

两个分支的共同祖先是第一次提交,因此上述命令其实是展示分支 b 和 b 的父提交之间的 diff。如图所示,

需要注意的是,如果两次提交在同一个分支上,那么双点和三点语法的效果是一致的

log

log 的双点语法 A..B 和 diff 的三点写法具有相同的含义,都表示仅在 B,但不在 A 的那些提交。如图所示:

比如:

ggp branch_b..branch_a

这个命令只会输出分支 a 的日志,如图所示:

三点语法 A...B表示的是那些只属于 A 提交,和只属于 B 提交的那些提交,如图所示:

例如:

ggp branch_b...branch_a

这个命令将单独得到分支 b 和 分支 a 上的各一次提交:

另外需要注意的是,根据我的实践,git show 中的双点、三点表示法和 git log 是一致的,就不另外说明了。

最后用一张图来总结:

results matching ""

    No results matching ""