Git(五):查询Git历史记录

来源:互联网 发布:制作电子地图的软件 编辑:程序博客网 时间:2024/05/17 06:36
     历史记录非常有用,它能够显示谁在何时修改了哪行代码,以及修改的原因。它还可以显示该文件两个版本之间的差异。除了查看,Git还允许你修改历史记录,不过,修改需谨慎,篡改历史的人,你懂的。     
     本章例子可以从GitHub上克隆下来:
$ git clone git://github.com/tswicegood/mysite-chp5.git

查看Git日志

     Git日志是按时间倒序显示的。在工作目录树中,在命令提示符后输入git log可以看到日志:
$ git log

     你可以上下滚动浏览日志。屏幕底部出现的冒号":",表示还有更多信息等待输出。(按"j"向下浏览,"k"向上浏览,"q"退出)。
     在不带参数的git log命令输出中,每个提交有四部分信息:提交名称、提交人、提交日期、提交留言。
     使用git log -p可以查看版本之间的代码差异。
     使用git log -n,n用数字替代,可以查看最近n条日志记录。
     也可以给git log命令传递一个指定的版本,并以此作为查看日志的起始点(查看在那之前的全部提交):

     在上面输入的是提交版本的前缀,请尽量多输长一些,如果匹配不上或者匹配到多个结果,Git就会报错。

指定查找范围     

     可以使用--since、--before选项来对记录进行时间上的过滤,例如:
$ git log --since="5 hours" 表示显示5小时内的历史记录。
$ git log --before="5 hours" -1 表示显示5小时前的最后一条记录。
     --since和--before参数接受大多数英文格式的日期。Git工具本身能够识别诸如--ince="24 hours"、--since="1 minute"、--before="2008-10.01"这样格式的日期,哪怕是日期中既有连字符又有句点。
     Git支持输出两个版本之间的日志记录。
$ git log 18f822e...0bb3dfb 表示输出在18f822e之后(不包括自己)到0bb3dfb之间(包括自己)的历史记录。
     在表示版本的过程中可以使用HEAD表示当前的版本,如:
$ git log 18f822e...HEAD
     也可以不输入HEAD,因为GIt假定"..."后面省略的值为HEAD,如:
$ git log 18f822e...
     当指定查找范围时,也可以用标签名称替换提交名称。如下:
$ git log --pretty=format:"%h %s" 1.0..HEAD

     注意这次在git log命令后添加了参数--pretty,format:"%h %s"告诉Git显示提交名称(哈希值)的缩写,以及提交留言的第一行,即标题。
     当git log命令什么都没有输出时,要注意输入是否正确。
     另一种指定版本的常见方法是指出它和另一版本的关系,此时有两种操作符可供使用:
  • ^:一个脱字号作用相当于回溯一个版本。18f822e^是指18f822e之前的那个版本。 18f822e^^是指它之前的之前的那个版本等同于18f822e^2。
  • ~N:波浪字符加数字的操作符是指回溯N个版本。借用刚才的例子,18f822e~1是指18f822e的父节点。
     可以混合使用这两种操作符,下面三个命令得到一样的结果:
$ git log -1 HEAD^^^
$ git log -1 HEAD^~2
$ git log -1 HEAD~1^^
$ git log -1 HEAD~1^^
     也可以在查找范围中使用带有脱字符或波浪符号的命令。
$ git log HEAD~10..HEAD

查看版本之间的差异

     可以使用git diff查看版本之间的差异,使用方式上与git log类似,可以指定两个具体的版本。如:
$ git diff 18f822e

     如果不带第二个参数,表示与当前HEAD的比较。
     在git diff命令中使用标签作为参数,是一种获取发布版本之间代码量统计的好方法。可以利用它计算出修改和删除的代码行数。这是通过--stat参数实现的,如:
$ git diff --stat 1.0
 

查明该向谁问责

     可以使用命令git blame,查看特定代码块的历史信息。该命令的输出结果是代码块中的每行代码前附加前缀信息、其中包括提交名称、提交人和提交时间。
$ git blame contact.html

     git blame命令模式会显示所有行的信息。我们可以利用"<开始>,<结束>"表示,<开始>和<结束>参数可以是数字。
$ git blame -L 12,13 hello.html 将显示第12、13行代码的信息
     <结束>这个参数不必非得指定一个数字,可以使用+N或者-N指定范围。
$ git blame -L 12,-3 hello.html
     也可以使用正则表达式进行匹配行内容,和已经查询以往某个版本中的内容。如:
$ git blame -L "/<\/body>/",-2 4333289e^ -- index.html
     注意上面有--,这是通知Git查询指定文件。

跟踪内容

     Git可以跟踪代码或者文件的粘贴和复制,为了尽量避免误判,Git至少要匹配三行才认为是复制和粘贴的结果。
     为了演示过程,现在在工作目录下创建一个名为original.txt的文件,并且输入以下三行内容:
This is the first line.
This happens to be the second line.
And this, it's the third and final line.
     然后在git中添加并提交文件。
     然后再编辑整个文件,并且将前三行复制粘贴到随后的三行。然后保存提交。现在可以执行git blame命令查看文件中每一行的历史记录了:
$ git blame original.txt

     可以看到不同的两次提交名。
     现在我们使用命令git blame带上参数-M可以检测同一个文件内的移动或复制代码行:
$ git blame -M original.txt  

可以看到这次所有的提交名称都相同。
     Git也可以跟踪文件之间内容的复制,下面复制文件original.txt到一个新文件,命名为copy.txt。
     暂存并提交copy.txt,在命令git blame中添加参数-C -C来查看文件之间的复制。
$ git blame -C -C copy.txt

      给git log命令传递-C -C参数,也能显示某一次提交中文件的复制信息,如果带上-p参数还会显示代码的具体变动:
$ git log -C -C -1 -p
     

撤销修改

     有时我们需要撤销提交,比如上次提交代码内容有缺陷。在集中式版本库中,撤销难以进行,因为别人可能已经down下来你那次提交后的代码。在Git中,可以很方便的进行撤销,因为在Git中所有修改都是在本地进行的,只有推入到公共版本库才能共享,所以只要未推入上游版本库的代码,我们在Git中就能轻松的进行撤销。     
     在Git的使用中,我们要注意只共享准备好的东西。在推入变更(到其他版本库)之前要确保变更是准备好的,在本地修改和提交,直到准备好才个共享。这样就不必担心在改写历史的时候对其他人造成影响。
增补提交
     我们可以利用Git把这次提交合并到上次提交之中。为了演示该操作, 请在文件contact.html中添加一些文字。

     接下来修改该文字,并且再次提交,并在git commit命令添加--amend参数:

     该git commit 命令使用-C参数,告诉Git复用某个版本的提交留言,该命令中是复用的HEAD的提交留言。如果参数是小写的-c,就会打开编辑器,以便在已有的提交留言基础上编辑修改。
     增补提交只能针对最后一个提交。如果想更正好几个提交前的某个错误,必须使用git revert命令,下面将介绍。
反转提交
     反转已经提交的变动,最简单的方式是使用git revert命令。此命令通过在版本库中创建一个"反向的"新提交来抵消原来提交的改动。
     通常Git会立即提交反转结果,但是也可以通过-n参数告诉Git先不要提交,这对于需要反转多个提交非常有用。运行多个git revert -n命令,Git会暂存所有的变更;然后做一次性提价。
     在反转操作的时候必须要提供提交名称,以便让Git知道要反转什么。举个例子,想要反转提交9267f21和HEAD。提示,反转总是按照从新到旧的倒序来操作,即最后的提交最先反转。这样可以避免在反转多个提交的时候,遇到一些不必要的冲突。




复位
     Git提供了复位版本库到一个特定版本的功能,命令git reset是以提交名称作为参数的,默认值是HEAD。
     可以用"^"和“~"作为提交名称的修饰符来指定某个版本。HEAD^是指要复位一个提交,9267f21~3是指要复位540ecb7之前的三个提交。
     命令git reset可以在复位版本库后,暂存工作目录树中因复位产生的与版本库的差异,以便提交。这对于在之前的提交中发现错误并需要更改时非常有用。
     这是通过--soft参数实现的,它使得Git暂存所有的因复位带来的差异,但不提交它。之后,用户可以修改这些内容再提交,或者干脆扔掉这些东西。
     另一个选项是--hard,这个选项会从版本库和工作目录树中同时删除提价。--hard就好像版本库中的删除键,并且不可以修复。
     下面简单演示这个选项的用法。前面示例中最后一次提交反转了两个文件的修改,假设这并无必要,下面撤销这个提交:
$ git reset -- hard HEAD^


重新改写历史记录

     有时我们需要改写历史记录,主要有以下几种用法:
  • 给历史记录重新排序
  • 将多个提交压合成一个提交
  • 将一个大的提交分解成为多个提交
     这其实是使用分布式版本控制系统带来的好处,如果是集中式,那么做这些操作会对其他程序员造成巨大的困惑。
     Git的交互式rebase命令,即git rebase -i,能够完成这类改写历史的工作。用这个命令,可以重新塑造历史。下面是当前版本库里的最后三个提交:

     在下面一节,我们将"ec5eb69"这个移到另外两个提交发生之前。
重新排序提交
     可使用命令git rebase的人机交互模式改写历史记录,交互模式启动的时候会调用事先设置好的编辑器。使用变基操作的交互模式,须提供重排提交的起始点作为参数。
     在这个例子中,我们想从HEAD~3(之后的那个提交)起,重排提交:
$ git rebase -i HEAD~3

     在编辑器中以"#"开头的都是注释,并且都会被Git忽略。现在把pick ec5eb69这一行移到最顶上一行。那么前三行就会是这个样子:

     保存编辑的内容并退出编辑器,Git开始变基操作。完成之后,可以通过git log 命令来查看新的顺序:

将多个提交压合成一个提交
     使用命令$ git rebase -i 版本x,将在交互模式中出现到版本x到HEAD版本的信息。我们可以压合任意多个提交,只需要移到目标行的下一行,并且将前面的pick改为squash后,保存即可。
将一个提交分解成多个提交
     比较麻烦,暂不介绍了,后来再利用GUI来介绍此操作。


1 0
原创粉丝点击