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

tri*_*nth 3 git version-control dvcs git-log git-branch

我试图使用参数来使用列表中给定范围内的列表所有提交git log.由于某种原因,它似乎没有给我正确的结果(或者我可能理解错误的命令?).

这是我正在做的步骤:

  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
    ...
    
    Run Code Online (Sandbox Code Playgroud)
  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
    
    Run Code Online (Sandbox Code Playgroud)

哇!当我预期8时,我实际上在该输出中有13个提交.这里发生了什么?修订范围是否是在给定提交后获得show commit的正确机制?或者这是一个错误?

tor*_*rek 7

这里的问题在于"后"的滑溜概念.

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

$ 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"
Run Code Online (Sandbox Code Playgroud)

这比你的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
Run Code Online (Sandbox Code Playgroud)

(我们得到了一组不同的"最顶层"提交,因为--graph修改了遍历,这就是为什么我去了10次提交).

要明白是怎么回事,你必须超越git loggit rev-list.像许多git命令一样,git log 用于 git rev-list选择要显示的修订版本.(有些git命令实际运行,git rev-list而其他人共享其源代码,但无论哪种方式都可以运行相同的.)

git修订符号x..y^x y(或者y ^x- 这意味着同样的事情)的简写.无论你写了一个名称,如masterorigin/stable/havana,或间接的名字一样HEAD,或原始提交-ID,或缩短原始提交-ID一样77bad25,在xy部分解决底层git的对象(在我们的情况下,应提交) .您可以使用git rev-parse以下方法观察解决步骤:

$ git rev-parse master
77bad252096f7a4a8174340f0f2a3baf1fd52195
$ git rev-parse HEAD
77bad252096f7a4a8174340f0f2a3baf1fd52195
$ git rev-parse origin/stable/havana
0bf0bb4b5df64f7266c903a986d0b90a1f223822
Run Code Online (Sandbox Code Playgroud)

什么git rev-list有这样做是向后工作从这次提交找到其父犯(S),然后从这些提交给他们的父母,等等.结果是一个祖先集.

master在这一点上,祖先没有特别的顺序:

  • master 本身: 77bad25...
  • master的第一个父母,git rev-parse master^1:d4d712a...
  • master的第二个父母,git rev-parse master^2:d0a02fa...
  • master第一个父母的第一个父母,git rev-parse master^1^1:d5bde44...
  • master第一位父母的第二位父母git rev-parse master^1^2:1d340cc...

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

$ git rev-list master | wc -l
   27918
Run Code Online (Sandbox Code Playgroud)

因此,git rev-list master选择所有27,000个和一些提交,git log master并将显示所有这些(按某种顺序,根据传递给git rev-listvia的其他选项修改订单git log).

要排除其中的一些,您可以告诉git rev-list从一些特定的修订开始 - 例如01381b8- 并找到它的所有祖先(包括01381b8它自己):

$ git rev-list 01381b8 | wc -l
   27901
Run Code Online (Sandbox Code Playgroud)

此时,这比通过开始master和向后工作找到的提交少了17次(并且在第二个列表中没有提交,而第一个列表中没有提交).因此,如果你告诉git rev-list你"所有提交开始master,减去从01381b8" 开始的所有提交",你应该得到17个提交:

$ git rev-list master ^01381b8 | wc -l
      17
Run Code Online (Sandbox Code Playgroud)

事实上,这就是我们所看到的.(实际的列表并不是那么有趣,但你可以看到它git rev-list master ^01381b8,或者相当于git rev-list 01381b8..master.)

git log给定相同的修订范围,这些提交将显示给您.

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