git(6)查询git历史记录(二)
1.查看版本之间的差异
使用命令git diff可以查看版本之间的差异。还是接着上篇文章中的例子来说明
git diff 18f822e
这个显示的是18f822e这个版本与当前工作目录树间的差异。
在命令git diff里,指定版本范围的方法与git log一样,唯一的差别是git diff输出的是最老版本与最新版本之间的差异,而不是按提交条目一个一个的显示。
在git diff命令中使用标签作为参数,是一种获取发布版本之间代码量统计的好方法,可以利用它计算出修改和删除的代码行数。
使用参数–stat,可以得到变更统计数据:
git diff –stat 1.0
这个例子命令git diff只传送了一个标签做参数,如果省略第二个参数,则git把HEAD当作默认值。
2.查明该向谁问责
git blame可以用来查看特定代码块的历史信息,该命令的输出结果代码块中的每行代码前附加前缀信息,其中包括提交名称,提交人和提交时间。
git blame hello.html
输出结果每行前8为字符是提交的哈希值,注意第一行有个脱字号,表示版本库中第一个提交。其次列出的是文件名index.html。因为hello.html原名是index.html,输出结果的第二列显示的是当初提交该行时的文件名,紧随其后显示的是提交人的姓名,提交时间,行号,以及该代码行。
git中通过给命令git blame传递参数-L能够缩小范围,它通过指定范围来告诉git只显示某些特定行的注释,此范围用参数“<开始>,<结束>”表示。
“<开始>,<结束>”参数可以是数字,例如显示文件hello.html的12和13行日志:
git blame –L 12,13 hello.html
<结束>这个参数不必非得指定数字,可以使用+N或者-N指定范围,使用这种方式生成的结果和前面例子中的结果完全相同:
git blame –L 12,+2 hello.html
使用-N记号可以减N行。
git还提供了另外一种指定<开始>和<结束>参数的方法:正则表达式。
git blame –L “/<\/body>/”,+2 hello.html
3.跟踪内容
git能够跟踪文件里甚至文件间的内容移动。
下面创建一个新的文件来演示这个功能。
创建一个名为original.txt文件,并添加一些内容。然后保存,添加并提交到版本库中:
git add original.txt
git commit –m “commit of original text file”
现在编辑这个文件,复制文件内容,然后将其粘帖在随后三行,然后保存,执行git diff将得到类似下面的输出结果:
提交修改到git版本库,现在可以使用git blame命令查看文件中每一行的历史提交记录:
git blame original.txt
从上图可以看出,输出结果的前三行的提交名称一样,后三行的提交名称一样,这就对应这目前位置的两次提交。
重新输入命令git blame,并加上参数-M。告诉git检测同一个文件内移动或复制的代码行:
git blame –M original.txt
结果显示所有提交名称相同,因为git跟踪的是内容,它在这里检测到了重复的内容。
git也可以跟踪文件之间的复制,下面复制文件original.txt到一个新文件,命令为copy.txt。
暂存并提交copy.txt,在命令git blame中添加参数-C -C来查看文件之间的复制:
git blame –C –C copy.txt
git不仅显示初始的提交名称ccdaace1,而且还有初始的文件名original.txt。给git log传递参数-C -C也能显示文件的复制信息。当用git log命令检测文件的复制时,还得传递参数-p,这样git出显示常规日志信息之外,还会显示代码的具体变动:
git log –C –C -p
到目前为止已介绍了查看历史记录的基本方法。下面介绍如何改写版本库历史。
4.撤销修改
4.1增补提交
为了演示,在文件contact.html中添加一个博客连接,但是故意把连接写错,然后提交本次修改:
git commit –m “add link to blog” -a
接下来修改该url后再次提交修改,并在git commit命令添加–amend参数:
git commit –C HEAD -a –amend
该命令使用的一个新参数-C,即告诉git复用指定提交留言,而不是从头再写一个。这个例子中指定的是HEAD。如果参数是小写-c就会打开预先设置好的编辑器,一边在已有提交留言基础上编辑修改。
git commit –c HEAD -a –amend
增补提交只能针对最后一个提交,如果想更正好几个提交之前的某个错误,则需使用git revert这个命令。
4.2反转提交
反转已经提交的改动,最简单的方法就是使用git revert命令,此命令通过在版本库中创建一个反向的新提交来抵消原来的提交改动。
参数git会立即提交反转结果,但是也可以通过-n参数告诉git先不要提交,这对于需要反转多个提交非常有用,运行多个git revert -n命令,git会暂存所有命令,然后一次性提交。
做反转操作的时候必须提供提交名称,以便让git知道要反转什么。反转总是按照从新到旧的倒序来操作,即最后的提交先反转。这样可以避免冲突。例如:
git revert –n HEAD
git revert –n e71360b5
git commit –m “revert e71360b5″
4.3复位
git提供复位版本库到一个特定版本的功能。命令git reset是以提交名称作为参数的,默认值是HEAD。可以使用“^”和“~”作为提交名称的修饰符来指定某个版本,HEAD^是指复位两个提交,540ecb7~3是指要复位540ecb7之前的3个提交。
命令git reset可以在复位版本库后,暂存工作目录树中因复位产生的与版本库的差异,以便提交。这是通过–soft参数实现的,它使得git暂存所有的因复位带来的差异,但不提交它。
最后介绍的一个选项是–hard,要小心使用。该选项会从版本库和工作目录树中同时删除提交。–hard就好像版本库中的删除键,并且不可以恢复。例如:
git reset –hard HEAD^
这样就将版本库复位到HEAD之前的那个版本库了。