Git - 查看提交历史

本文讲解使用 git 等工具查看提交历史的几种方式。

git log

在我理解中,实际上后面讲的各种方法都是基于 git log 命令行工具,且对于程序员而言,命令行才是正统;
默认不用任何参数的话,git log 会按提交时间列出所有的更新,最近的更新排在最上面。每次更新都有一个 SHA-1 校验和、作者的名字和电子邮件地址、提交时间,最后缩进一个段落显示提交说明。git log 命令行会默认打开一个 vim 编辑器,输入 :q 退出查看。
常用选项
-p 选项展开显示每次提交的内容差异;
-2 则仅显示最近的两次更新;
--word-diff 选项。可以将其添加到 git log -p 命令的后面,从而获取单词层面上的对比。在书籍、论文这种很大的文本文件上进行对比的时候;
--stat,仅显示简要的增改行数统计;

作者(author)和提交者(committer)的差别,作者指的是实际作出修改的人,提交者指的是最后将此工作成果提交到仓库的人。所以,当你为某个项目发布补丁,然后某个核心成员将你的补丁并入项目时,你就是作者,而那个核心成员就是提交者。
示例
查看 Git 仓库中,2018 年 9 月期间,Junio Hamano 提交的但未合并的测试脚本(位于项目的 t/ 目录下的文件),命令:
git log --pretty="%h - %s" --author=gitster --since="2018-09-01" --before="2018-09-30" --no-merges -- t/

git log -p -2
选项除了显示基本信息之外,还在附带每次 commit 的变化。常用于代码审查,或者快速浏览某个搭档提交的 commit 的变化。

git log -U1 --word-diff
这里并没有平常看到的添加行或者删除行的信息。这里的对比显示在行间。新增加的单词被 {+ +} 括起来,被删除的单词被 [- -] 括起来。在进行单词层面的对比的时候,你可能希望上下文( context )行数从默认的 3 行,减为 1 行,那么可以使用 -U1 选项。

git log --stat
每个提交都列出修改过的文件,以及其中添加和移除的行数,并在最后列出所有增减行数小计。 还有个常用的 --pretty 选项,可以指定使用完全不同于默认格式的方式展示提交历史。比如用 oneline 将每个提交放在一行显示,这在提交数很大时非常有用。另外还有 short,full 和 fuller 可以用,展示的信息或多或少有些不同。

用 oneline 或 format 时结合 --graph 选项,可以看到开头多出一些 ASCII 字符串表示的简单图形,形象地展示了每个提交所在的分支及其分化衍合情况。在我们之前提到的 Grit 项目仓库中可以看到:
git log --pretty=format:"%h %s" --graph

git log --pretty=oneline
format,可以定制要显示的记录格式,这样的输出便于后期编程提取分析:
git log --pretty=format:"%h - %an, %ar : %s"
列出常用的格式占位符写法及其代表的意义。

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

列出所有最近两周内的提交: git log --since=2.weeks or git log --since=2weeks

还可以给出若干搜索条件,列出符合的提交。用 --author 选项显示指定作者的提交,用 --grep 选项搜索提交说明中的关键字。(如果要得到同时满足这两个选项搜索条件的提交,就必须用 --all-match 选项。否则满足任意一个条件的提交都会被匹配出来)

git log选项是路径(path),如果只关心某些文件或者目录的历史提交,可以在 git log 选项的最后指定它们的路径。因为是放在最后位置上的选项,所以用两个短划线(–)隔开之前的选项和后面限定的路径名。

汇总表格如下

选项 说明
-p 按补丁格式显示每个更新之间的差异。
--word-diff 按 word diff 格式显示差异。
--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 的简化用法。
-(n) 仅显示最近的 n 条提交;不常用,Git 在输出所有提交时会自动调用分页程序(less),要看更早的更新只需翻到下页即可。
--since, --after 仅显示指定时间之后的提交。
--until, --before 仅显示指定时间之前的提交。
--author 仅显示指定作者相关的提交。
--committer 仅显示指定提交者相关的提交。

gitk

安装 Git 之后就自带 gitk 图形化工具,用 Tcl/Tk 写成,相当于 git log 命令的可视化版本,凡是 git log 可以用的选项也都能用在 gitk 上。在 git 代码库下面 输入 gitk 命令就可以打开这个图形化工具。

IDEA——version control——log

自从使用 IDEA 之后,基本上也不会再去定位到本地的代码仓库,然后右键打开一个命令行窗口,输入命令 git log 或者 gitk,而是就地直接使用 IDEA 的 version control——log 功能,IDEA 默认也是可以看到 graph 形式的 git log,而且也支持各种条件搜索,发布简洁地看到提交历史。
在这里插入图片描述
比如最前面的编辑框可以输入查询条件,随后的 regex 或者 match case 表示查询条件的匹配模式;
在这里插入图片描述
随后的 branch 可以选择哪个 branch 的提交历史记录;
再往后的 user,date,path,以及其他足够日常开发应用。

source tree

试用过 source tree,比 Tortoise Git 更专业,毕竟是收费软件,把版本控制管理做到极致,破解方法参考版本控制工具 Git 使用笔记。一般情况下,只要你熟悉 Git 的原理之后,就不需要所谓的图形化工具,也就不需要 source tree 这样的专业工具;不过对于有些版本控制很严格的项目,比如实施 Git Flow 开发模式的项目,branch 或者 tag 就会比较复杂,此时 source tree 就会派上用场。
附图 Git Flow
在这里插入图片描述
IDEA 甚至提供 Git Flow 插件
Git Flow 参考:
参考1
参考2

git log vs git reflog

git reflog

reference log,查看引用日志。
参考git reflog
里面提到:
记录的是本地仓库的所有 git 操作,比如 git pull 都会记录下来。原文:record when the tips of branches and other references were updated in the local repository.
引用日志信息只存在于本地——这是一个记录你在你自己的仓库里做过什么的日志。其他人拷贝的仓库里的引用日志不会和你的相同;而你新克隆一个仓库的时候,引用日志是空的,因为你在仓库里还没有操作。git show HEAD@{2.months.ago} 这条命令只有在你克隆一个项目至少两个月时才会有用——如果你是五分钟前克隆的仓库,那么它将不会有结果返回。
git reflog show accepts any of the options accepted by git log。大意就是 git reflog show 命令是 git log 命令的超集。
其余的子命令包括:

git reflog [show] [log-options] [<ref>]
git reflog expire [--expire=<time>] [--expire-unreachable=<time>]
	[--rewrite] [--updateref] [--stale-fix]
	[--dry-run | -n] [--verbose] [--all | <refs>…​]
git reflog delete [--rewrite] [--updateref]
	[--dry-run | -n] [--verbose] ref@{specifier}…​
git reflog exists <ref>

两者的区别:
git log:commit 的版本日志,版本回退后,使用git log 看不到回退版本号之后的版本记录;
git reflog:使用git 命令进行操作的日志,包括当前步骤所在哪个版本(一个commit 产生一个版本,指定版本回退只能回退到该commit) 以及操作的具体内容;版本回退后,仍然可以看到所有的版本记录,查看每个操作步骤所在的版本,可以根据版本号自由前进后退。

总之:如果在回退以后又想再次回到之前的版本,git reflog 可以查看所有分支的所有操作记录(包括commit和reset的操作),包括已经被删除的commit记录,git log则不能察看已经删除了的commit记录

猜你喜欢

转载自blog.csdn.net/lonelymanontheway/article/details/83022449