Git日志解释道

时间:2014-03-01 20:00:31

标签: git git-log

对于我正在构建的git日志查看器,我只是查看git log输出并且想知道三件事。由于没有关于Git SCM书中的完全输出和类似资源的文档,我不得不问SO:

  1. index 1234567..1234567 123456是什么?它与提交sha
  2. 不匹配
  3. 更改行的逗号后面的int是什么? @@ -40,20 +40,20 @@
  4. 更改后的第二个@@之后的部分是什么?
  5. 示例,取自Git SCM Book "Viewing the commit history"

    $ git log -p -2
    commit ca82a6dff817ec66f44342007202690a93763949
    Author: Scott Chacon <schacon@gee-mail.com>
    Date:   Mon Mar 17 21:52:11 2008 -0700
    
        changed the version number
    
    diff --git a/Rakefile b/Rakefile
    index a874b73..8f94139 100644
    --- a/Rakefile
    +++ b/Rakefile
    @@ -5,5 +5,5 @@ require 'rake/gempackagetask'
     spec = Gem::Specification.new do |s|
         s.name      =   "simplegit"
    -    s.version   =   "0.1.0"
    +    s.version   =   "0.1.1"
         s.author    =   "Scott Chacon"
         s.email     =   "schacon@gee-mail.com
    

3 个答案:

答案 0 :(得分:6)

  

<强> 1。什么是指数1234567..1234567 123456?它与提交sha?

不匹配

来自git-log man page

  

索引行包括之前和之后的SHA-1校验和   更改。 &lt;模式&gt;如果文件模式没有改变,则包括在内;   否则,单独的行表示旧模式和新模式。

好的,很酷......但这是什么意思?

因此,git通过使用地址在内部存储对象来工作。这些SHA-1校验和是更改之前和之后文件版本的地址。

您可以通过使用git-internal命令来查看这些文件:

$git cat-file -p a874b73
<--- the contents of the file before the commit --->

$git cat-file -p 8f94139
<--- the contents of the file after the commit --->

第二个数字<mode>表示unix文件权限。请参阅this answer for more info about how to read them

请参阅下文,了解哈希的示例!

编辑:哎呀,忘了解决第二和第三个问题。

  

<强> 2。更改行的逗号后面的int是什么? @@ -40,20 +40,20 @@?

使用unified diff format显示更改。维基百科的文章有一个很好的解释,但基本上这一行是range information。它由两对组成:第一对具有-符号,第二对具有+符号。 -对引用原始文件,+对引用第二个文件。 在每对中,第一个数字是要显示的块的起始行号,第二个数字是将显示的行数。

所以@@ -10,5 +10,10 @@

这意味着您已经添加了5行,因此第二个版本中的块长了5行。

  

第3。在第二个@@之后,对于更改的行,该部分是什么?

这一行应该是块所在的上下文。所以,正如@ TimWolla在下面的回答所指出的,如果这是一个C / C ++程序,那可能就是这个块所在的函数的名称。在这种情况下,行require 'rake/gempackagetask'是ruby,可能是程序的第一行,因此diff认为它是一个适当的名称来引用此部分。


以下是git的SHA-1校验和的几个例子:

$ touch newfileA newfileB
$ git add newfile*
$ git commit -m 'added new files'
[master a49cb1c] added new files
 2 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 newfileA
 create mode 100644 newfileB

$ git log -p -1
commit a49cb1c5292082a6ed9c7f09e1bce2636e60ab93
Author: Nathan Daly <NHDaly@gmail.com>
Date:   Sat Mar 1 16:10:49 2014 -0500

    added new files

diff --git a/newfileA b/newfileA
new file mode 100644
index 0000000..e69de29
diff --git a/newfileB b/newfileB
new file mode 100644
index 0000000..e69de29

您可以看到在提交之前文件不存在(因为没有地址引用以前的版本:因此索引0000000),并且在创建它们之后,这些文件的blob具有地址e69de29。它们共享相同的哈希,因为文件是相同的,所以没有理由拥有空文件的不同副本。

你可以通过散列一个空文件来看到这一点。我们得到与之前相同的哈希值(这次是全长):

$ touch blankfile
$ git hash-object blankfile
e69de29bb2d1d6434b8b29ae775ad8c2e48c5391

现在,如果我们更改文件的内容:

$ echo 'contents1' > newfileA
$ echo 'contents2' > newfileB
$ git add newfile*
$ git commit -m 'updated newfile contents'    
[master 76827d7] updated newfile contents
 2 files changed, 2 insertions(+)

$ git log -p -1
commit 76827d7af1846c6c0f07ac2b78771cbc34cd6056
Author: Nathan Daly <NHDaly@gmail.com>
Date:   Sat Mar 1 16:18:40 2014 -0500

    updated newfile contents

diff --git a/newfileA b/newfileA
index e69de29..a024003 100644
--- a/newfileA
+++ b/newfileA
@@ -0,0 +1 @@
+contents1
diff --git a/newfileB b/newfileB
index e69de29..6b46faa 100644
--- a/newfileB
+++ b/newfileB
@@ -0,0 +1 @@
+contents2

你可以看到他们现在有不同的哈希值。它们中的每一个都从e69de29的对象开始,并移动到具有不同地址的新对象。并且,为了验证这一点,我们可以从它们各自的哈希中获取这些对象的内容:

$ git cat-file -p a024003
contents1
$ git cat-file -p 6b46faa
contents2

最后,如果我们再次使它们的内容相等,它们将再次共享一个哈希值。 (同样,git这样做只是为了节省磁盘空间,因为这两个文件完全相同,但名称相同)

$ echo 'contents2' > newfileA
$ git add newfileA
$ git commit -m 'now files match'
$ git log -p -1
commit 3f63bcef9290fae616521ec1b380639c6026c5c5
Author: Nathan Daly <NHDaly@gmail.com>
Date:   Sat Mar 1 16:22:29 2014 -0500

    now files match

diff --git a/newfileA b/newfileA
index a024003..6b46faa 100644
--- a/newfileA
+++ b/newfileA
@@ -1 +1 @@
-contents1
+contents2

如您所见,现在newfileA也有哈希6b46faa,就像newfileB一样。

git中的每个对象都存储有这样的哈希地址,因此在您的git日志查看器应用程序中,您可以使用这些索引哈希向用户显示每个版本的文件内容!

答案 1 :(得分:3)

回答NHDaly答案未解决的问题:

  

更改行的逗号后面的int是什么? @@ -40,20 +40,20 @@?

这是长度(没有+-的行加上第一行-的行数和+的行数对于第二个)跟随的块。在这种情况下:显示的行数为20

  

更改后的第二行@@之后的部分是什么?

diff使用一种确定上下文的算法,它最适合C代码,它应该显示方法标题,例如参见Commit af87d2fe95 of the linux kernel

答案 2 :(得分:0)

作为对其他(优秀)答案的补充,这里有一些关于添加/删除行的更深入的例子,因为统一差异格式意味着没有逗号值1(行添加/删除)。这意味着没有逗号值并不意味着null,但1和零/ 0并不意味着null,而是1。这可能会让像我这样的程序员感到困惑。

实施例

以下示例暗示您正在调用git show --unified=0 $sha并且不显示未更改的行。 TimWolla在评论中指出(谢谢),将包括其他不变的行。

@@ -10,5 +10,10 @@

表示已删除5行并添加10行。

@@ -10,0 +10,2 @@

没有删除任何行,但添加了2行。

@@ -10 +10,2 @@

删除了一行,添加了两行。

@@ -10 +10 @@

删除了一行,并添加了一行。

@@ -10,7 +10 @@

删除了7行,并添加了1行。

@@ -10,7 +10,0 @@

删除了7行,没有添加任何行。