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

384 Views Asked by At

I wanted to get a list of all my commits to a repository since the start of the year. I tried with the obvious command, but it doesn't include any of them:

$ git log --pretty='format:%h %ae %cI %s' [email protected] --since=2017-01-01
$

Oddly, I have to use --since=2016-12-19, which gets me some of them:

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

But it's not all of them:

$ git log --pretty='format:%h %ae %cI %s' [email protected] | grep 2017- | wc -l
19

What's going on here? Does --since do something other than just remove commits from the output that are earlier than the given date?

2

There are 2 best solutions below

6
On BEST ANSWER

For better or worse (me, I'm in the "worse" camp), git defaults to the current time of day when you specify a date. Try --since='midnight 2016-12-20'

... okay. I haven't deciphered the code yet, but this looks awfully good for it:

~/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       [email protected]
|\  
| * cddd3c28b212        2017-01-06T22:10:08+11:00       2017-01-06T22:10:08+11:00       [email protected]
| * c337ff9019fb        2016-11-21T15:58:37-08:00       2016-11-21T15:58:37-08:00       [email protected]
| * aa46f91d69e7        2017-01-05T17:14:46+01:00       2017-01-05T17:14:46+01:00       [email protected]
| * d1ef4e265960        2017-01-06T21:12:08+11:00       2017-01-06T21:12:08+11:00       [email protected]
| * 76040295f609        2017-01-06T21:12:08+11:00       2017-01-06T21:12:08+11:00       [email protected]
| * 1b2b0886c923        2017-01-06T21:12:08+11:00       2017-01-06T21:12:08+11:00       [email protected]
| * 41782ed8bfb7        2017-01-06T15:30:31+08:00       2017-01-06T15:30:31+08:00       [email protected]
| * 318a182e13bb        2017-01-06T15:29:47+08:00       2017-01-06T15:29:47+08:00       [email protected]
| * b54b74578c69        2017-01-06T15:21:19+08:00       2017-01-06T15:21:19+08:00       [email protected]
| * 076ab8862963        2017-01-06T15:05:24+08:00       2017-01-06T15:05:24+08:00       [email protected]
| * 13ce7a2e81b0        2017-01-06T15:05:24+08:00       2017-01-06T15:05:24+08:00       [email protected]

Notice your commits are behind commit c337ff9, dated 2016-11-21. I'm betting there's an heuristic in there somewhere, that says if it encounters a commit dated more than a month before the cutoff it stops looking.

1
On

A few more notes, worthy of noting:

  1. Git uses the commit date, not the author date, for the min and max age parameters (at least as of current nearly-2.12 source). The output from the approxidate parser goes into revs->max_age (which is otherwise just -1) when using --since. This really should be documented, and I'm not sure older Git versions do the same thing.

  2. If revs->limited gets set, the function limit_revs gets called, which propagates an UNINTERESTING flag from parent commits to their children. The UNINTERESTING flag also gets set when one commit is past the max_age setting. This would prune all the children of a commit with a later committer date. However, revs->limited should not actually be set here, as it's turned on instead by commit limiting operations (including --ancestry-path and --simplify-by-decoration for instance).

  3. The internal function get_revision_1 does something similar if revs->limited is not set, except that it doesn't even add the parent commits.

Even though commit dates would normally be nondecreasing, it seems incorrect to assume they're nondecreasing, since one can always force a particular commit date on any given commit—even a merge commit—through the GIT_COMMITTER_DATE environment variable, for instance. Or, even in the absence of malice, computer clocks are not always correct. Should someone merge someone else's work when their computer is for some reason set to 1973, that doesn't put the other person's work in the past.