为什么 git log --since 不包括我期望的提交?

Why does git log --since not include the commits that I expect?

我想获得自年初以来我对 a repository 的所有承诺的列表。我尝试了明显的命令,但它不包含任何命令:

$ git log --pretty='format:%h %ae %cI %s' --author=cam@mcc.id.au --since=2017-01-01
$

奇怪的是,我必须使用 --since=2016-12-19,这让我得到了一些:

$ git log --pretty='format:%h %ae %cI %s' --author=cam@mcc.id.au --since=2016-12-20
$ git log --pretty='format:%h %ae %cI %s' --author=cam@mcc.id.au --since=2016-12-19
61569b5 cam@mcc.id.au 2017-01-02T16:25:22+08:00 Bug 1324624 - Tweak stylo crashtest assertion annotations a bit more.
7fca5ff cam@mcc.id.au 2016-12-29T16:32:01+08:00 Bug 1323892 - Followup to disable one more crashtest under stylo.
cd875e7 cam@mcc.id.au 2016-12-28T17:50:44+08:00 Bug 1326023 - Make Element::GetBindingURL return a strong reference. r=smaug
3c057d1 cam@mcc.id.au 2017-01-02T15:44:23+08:00 Bug 1323717 - Re-enable 1290994-4.html. r=manishearth
7a45228 cam@mcc.id.au 2016-12-28T17:50:44+08:00 Bug 1326023 - Make Element::GetBindingURL return a strong reference. r=smaug
171e45e cam@mcc.id.au 2017-01-03T18:35:15+08:00 Bug 1328223 - stylo: Ignore invalid URLs from @import rules. r=emilio
$

但不是全部:

$ git log --pretty='format:%h %ae %cI %s' --author=cam@mcc.id.au | grep 2017- | wc -l
19

这是怎么回事? --since 除了从输出中删除早于给定日期的提交之外,还会做其他事情吗?

无论好坏(我,我属于 "worse" 阵营),当您指定日期时,git 默认为当前时间。尝试 --since='midnight 2016-12-20'

...好吧。我还没有破译密码,但这看起来非常好:

~/src/gecko-dev$ lgdo @ --pretty=%h%x09%aI%x09%cI%x09%ae
*   1e82e8d0792b        2017-01-06T10:59:19-05:00       2017-01-06T10:59:19-05:00       ihsiao@mozilla.com
|\  
| * cddd3c28b212        2017-01-06T22:10:08+11:00       2017-01-06T22:10:08+11:00       me@upsuper.org
| * c337ff9019fb        2016-11-21T15:58:37-08:00       2016-11-21T15:58:37-08:00       olucafont6@yahoo.com
| * aa46f91d69e7        2017-01-05T17:14:46+01:00       2017-01-05T17:14:46+01:00       benj@benj.me
| * d1ef4e265960        2017-01-06T21:12:08+11:00       2017-01-06T21:12:08+11:00       me@upsuper.org
| * 76040295f609        2017-01-06T21:12:08+11:00       2017-01-06T21:12:08+11:00       me@upsuper.org
| * 1b2b0886c923        2017-01-06T21:12:08+11:00       2017-01-06T21:12:08+11:00       me@upsuper.org
| * 41782ed8bfb7        2017-01-06T15:30:31+08:00       2017-01-06T15:30:31+08:00       cam@mcc.id.au
| * 318a182e13bb        2017-01-06T15:29:47+08:00       2017-01-06T15:29:47+08:00       cam@mcc.id.au
| * b54b74578c69        2017-01-06T15:21:19+08:00       2017-01-06T15:21:19+08:00       cam@mcc.id.au
| * 076ab8862963        2017-01-06T15:05:24+08:00       2017-01-06T15:05:24+08:00       cam@mcc.id.au
| * 13ce7a2e81b0        2017-01-06T15:05:24+08:00       2017-01-06T15:05:24+08:00       cam@mcc.id.au

请注意,您的提交落后于日期为 2016-11-21 的提交 c337ff9。我敢打赌那里有一个启发式方法,它说如果遇到截止日期超过一个月的提交,它就会停止查找。

再补充几点,值得注意的是:

  1. Git 使用提交日期,而不是作者日期,用于最小和最大年龄参数(至少从当前 nearly-2.12 源开始)。当使用 --since 时,近似解析器的输出进入 revs->max_age(否则只是 -1)。这真的应该被记录下来,我不确定旧的 Git 版本是否做同样的事情。

  2. 如果 revs->limited 被设置,函数 limit_revs 被调用,它传播一个 UNINTERESTING 标志从 parent 提交到他们的 children.当一次提交超过 max_age 设置时,也会设置 UNINTERESTING 标志。这将删除具有较晚提交者日期的提交的所有 children。但是,revs->limited 实际上不应该在这里设置,因为它是由提交限制操作(例如包括 --ancestry-path--simplify-by-decoration)打开的。

  3. 内部函数get_revision_1does something similar if revs->limited is not set, except that it doesn't even add the parent commits.

尽管提交日期通常是不减少的,但假设它们是不减少的似乎是不正确的,因为人们总是可以强制一个例如,通过 GIT_COMMITTER_DATE 环境变量,任何给定提交(甚至是合并提交)的特定提交日期。或者,即使没有恶意,计算机时钟也不总是正确的。如果有人在他们的计算机出于某种原因设置为 1973 时合并其他人的工作,这不会将其他人的工作放在过去。