git log revision range提供了不正确的提交范围

时间:2014-06-15 01:37:48

标签: git version-control git-branch dvcs git-log

我正在尝试使用git log的参数在分支上的给定范围内使用list all all。出于某种原因,它似乎没有给我正确的结果(或者我理解错误的命令?)。

以下是我正在做的步骤:

  1. 克隆回购

    git clone https://github.com/openstack/nova.git

  2. git log这些是最后9次提交:

    d5bde44 Merge "Make metadata password routines use Instance object"
    6cbc9ee Merge "Fix object change detection"
    39b7875 Merge "Fix object leak in nova.tests.objects.test_fields.TestObject"
    94d1034 Merge "maint: correct docstring parameter description"
    6407f17 Merge "Fix live_migration method's docstring"
    7406661 Merge "Fix infinitely reschedule instance due to miss retry info"
    9d8a34f Merge "Remove unused code from test_compute_cells"
    429cd4b Fix object change detection
    01381b8 Fix object leak in nova.tests.objects.test_fields.TestObject
    ...
    
  3. 假设我想在01381b8之后开始提交所有提交。我发出git log 01381b8..HEAD并看到以下输出:

    d5bde44 Merge "Make metadata password routines use Instance object"
    6cbc9ee Merge "Fix object change detection"
    39b7875 Merge "Fix object leak in nova.tests.objects.test_fields.TestObject"
    94d1034 Merge "maint: correct docstring parameter description"
    6407f17 Merge "Fix live_migration method's docstring"
    7406661 Merge "Fix infinitely reschedule instance due to miss retry info"
    9d8a34f Merge "Remove unused code from test_compute_cells"
    429cd4b Fix object change detection
    2214bc0 Remove unused code from test_compute_cells
    9639b55 Fix infinitely reschedule instance due to miss retry info
    a5184d3 Fix live_migration method's docstring
    76729a3 maint: correct docstring parameter description
    28224a6 Make metadata password routines use Instance object
    
  4. 哇!当我预期 8 时,我实际上在该输出中有 13 提交。这里发生了什么?修订范围是否是在给定提交后获得show commit的正确机制?或者这是一个错误吗?

2 个答案:

答案 0 :(得分:5)

这里的问题在于“后”的滑溜概念。

提交不是“之前”和“之后”,因为它们“嵌入图表中”。在这种情况下,由于存储库是可克隆的,我克隆了它。显然它很活跃:

$ git log --oneline -9
77bad25 Merge "Remove deprecated config option names: Juno Edition"
d4d712a Merge "Deprecate instance_get_by_uuid() from conductor"
d5bde44 Merge "Make metadata password routines use Instance object"
6cbc9ee Merge "Fix object change detection"
39b7875 Merge "Fix object leak in nova.tests.objects.test_fields.TestObject"
94d1034 Merge "maint: correct docstring parameter description"
6407f17 Merge "Fix live_migration method's docstring"
7406661 Merge "Fix infinitely reschedule instance due to miss retry info"
9d8a34f Merge "Remove unused code from test_compute_cells"

这比你的last-9输出更新。但更有意思的是,如果添加--graph来记录这些内容,我们会看到这些内容(我会将数字增加到10):

$ git log --oneline --graph -n 10

*   77bad25 Merge "Remove deprecated config option names: Juno Edition"
|\  
| * d0a02fa Remove deprecated config option names: Juno Edition
* |   d4d712a Merge "Deprecate instance_get_by_uuid() from conductor"
|\ \  
| * | 1d340cc Deprecate instance_get_by_uuid() from conductor
* | |   d5bde44 Merge "Make metadata password routines use Instance object"
|\ \ \  
| |/ /  
| * | 28224a6 Make metadata password routines use Instance object
* | |   6cbc9ee Merge "Fix object change detection"
|\ \ \  
| * | | 429cd4b Fix object change detection
* | | |   39b7875 Merge "Fix object leak in nova.tests.objects.test_fields.TestO
|\ \ \ \  
| |/ / /  
| * | | 01381b8 Fix object leak in nova.tests.objects.test_fields.TestObject

(我们得到了一组不同的“最顶层”提交,因为--graph修改了遍历,这就是我提交10次提交的原因。

要了解这里发生了什么,您需要超越git loggit rev-list。与许多git命令一样,git log 使用 git rev-list来选择要显示的修订版。 (有些git命令实际上运行git rev-list而其他人共享其源代码,但无论哪种方式都可以运行相同的。)

git修订符号x..y^x y(或y ^x的简写 - 这些意思相同。无论是编写master还是origin/stable/havana之类的名称,还是像HEAD这样的间接名称,还是原始提交ID,或缩写为77bad25的原始提交ID, xy部分被解析为底层的git对象(在我们的例子中应该是一个提交)。您可以使用git rev-parse

观察解决步骤
$ git rev-parse master
77bad252096f7a4a8174340f0f2a3baf1fd52195
$ git rev-parse HEAD
77bad252096f7a4a8174340f0f2a3baf1fd52195
$ git rev-parse origin/stable/havana
0bf0bb4b5df64f7266c903a986d0b90a1f223822

git rev-list对此做的是从此提交向后工作以查找其父提交,然后从这些提交到其父级,依此类推。结果是一个祖先集。

此时master的祖先没有特别的顺序:

  • master本身:77bad25...
  • master的第一位家长git rev-parse master^1d4d712a...
  • master的第二位家长git rev-parse master^2d0a02fa...
  • master的第一位家长的第一位家长git rev-parse master^1^1d5bde44...
  • master的第一位家长的第二位家长git rev-parse master^1^21d340cc...

当然还有更多,回去做多次提交:

$ git rev-list master | wc -l
   27918

所以git rev-list master会选择所有27,000个和一些提交,而git log master会显示所有这些提交(按某种顺序,根据传递给{{1的其他选项修改订单)通过git rev-list)。

要排除部分内容,您可以告诉git log从某个特定修订开始 - 例如git rev-list - 并查找其所有祖先(包括01381b8本身):

01381b8

此时,这比从$ git rev-list 01381b8 | wc -l 27901 开始并向后工作所发现的提交少了17次(并且在第二个列表中没有提交但未在第一个列表中提交)。因此,如果你告诉master给你“从git rev-list开始的所有提交,减去从master开始的所有提交”,你应该得到17次提交:

01381b8

确实这就是我们所看到的。 (实际列表并不是那么有趣,但您可以使用$ git rev-list master ^01381b8 | wc -l 17 或等效git rev-list master ^01381b8来查看它。)

这些提交是git rev-list 01381b8..master将在给出相同修订范围的情况下显示的提交。

您可以花几天时间研究git log文档并仍然遗漏项目(例如,git rev-list告诉您“启用父级重写”和“暗示--graph”,直到我检查刚才,我忘记了父改写部分。幸运的是,这里不适用,只需要--topo-order强制绘制的图形按日期而不是拓扑排序。)

答案 1 :(得分:-2)

使用以下命令,

  

git log --graph --pretty = format:'%Cblue%h%Creset - %C(红色)%d%Creset%s   %Cgreen(%cr)%C(粗体蓝色)<%an>%Creset' - 简称 - 提交

它会以丰富多彩的方式为您提供一行中的提交日志,包括分支名称,作者详细信息,图表,日期。

试试这个!!真的很棒。