Search code examples
gitgit-rebasegit-rev-list

Timestamps on git commits after rebase?


I'm trying to undo my bad git practices from times past and in doing so, I want to get a list of commits to specific files, newer than a certain timestamp (older commits to these files were cherry-picked to the master branch, which I now realise was a very bad idea, considering that the originating branch was nowhere near finished). Illustrated simplified:

A---A1-...-CB1--CB2-...-CBm--A5--A6 | master
 \
  B1--B2--B3-...-Bm-...-Bn          | topic
 \
  B1--B2_3--B4-...-Bn                | topic-R
  • Commits B1..Bm were cherry-picked into master from the topic branch some time ago, illustrated here as CB1, CB2, etc.
  • Work on the files continued in the original topic branch (master branch didn't touch them), here as Bm+1..Bn
  • I recently created the topic-R branch as a copy of the topic branch, and interactively rebased it on top of merge-base with master to clean up the history (squash and fixup).

I now want to get a list of commits Bm+1..Bn from topic-R with git rev-list. So I found the commit CBm, and in the history (and rev-list output) of topic-R it shows the date I'd expect, some 9 months ago.

git rev-list --after "2020-08-07" <A>..topic-R --reverse -- <file list>

So I feed this to rev-list and surprisingly, I'm getting all the commits, as if the --after/--since filter was ignored. Passing --pretty to rev-list still shows the expected date under Date - a date from months ago, when the code was written. But when I pass --timestamp to rev-list, I see very recent timestamps on all of the commits in the list - from when I rebased the topic-R branch merely days ago.

What is going on here? Is there to way to tell rev-list to filter by the original timestamp, which is very obviously still available?

I know I can just use the Bm+1's hash from topic-R to limit the listing, but I'm curious what kinds of timestamps git keeps track of and if filtering by the original timestamp is possible.


Solution

  • Every commit has two date-and-time stamps. One is called the author date and one is called the committer date.

    When you make a new commit in the usual way, using git commit and no trickery, both are set to the same value. Git retrieves the current time from your computer clock, and if that's accurate, the new commit's two date-stamps are "now".

    When you make a commit using git cherry-pick or something that internally uses the cherry-pick machinery (such as git rebase), Git normally preserves the original author of the commit, and the original author-date. You become the committer, and "now" is the committer date.

    To see both time stamps with git log, use any of the formatting options that prints both. The simplest to use is git log --pretty=fuller.

    The --since and --until (or --after and --before) options to git log use the committer date only. (I think there should be a way to specify author dates, but there isn't.)