Thread (3 messages) flat view 3 messages, 3 authors, 2016-06-15

Re: How do I specify a revision for "git blame" by date?

From: <hidden>
Date: 2016-06-15 22:54:07

Thomas Rast [off-list ref] wrote:
perryh@pluto.rain.com writes:
quoted
How do I get "git blame" to operate "as of" a particular date in
the past, without having to manually look up the corresponding
SHA1 using "git rev-list"?  For example, I can get a report as
of 2011-12-29 by doing something like:

  $ git rev-list --all --date-order --format="%h %ai" .
  ...
  7c69106 2012-01-03 ...
  b4227af 2011-12-27 ...
  ...

  $ git blame <file> b4227af

but I want to have git look up the last revision prior to the
given date, by doing something like

  $ git blame <file> @{2011-12-29}
You are looking at two different dates:

a) The dates stored within the commit object:

   - committer date, similarly shown by %ci: when the commit
     was created.
   - author date, shown by %ai: when "this" commit was "first
     created".

   These are properties of the commits, and thus part of the project
   history.  Anyone who clones the project sees the same dates.

b) The dates in the reflog, tracking the movement of *your local*
   refs (like the name implies).  The HEAD reflog tracks what *you*
   had "currently checked out" at a given time.

An automated search in (b) is possible with the @{} syntax, but
note that it tracks the *branch state*.  It says nothing about how
"current" a certain resulting commit was.  For example, if you say

  git checkout v1.6.0
  sleep 2
  git checkout -
  git show '@{1 second ago}'

you will see the commit for v1.6.0 from back in 2008.

An automated search in (a) is hard, mostly because in nonlinear
history there is not usually a single (and well-defined) commit
that could be returned.
Given that we are discussing "git blame", which reports on the
history of a file (specifically the commit in which each line
originated), I think (a) must logically be included in the search
-- especially if (as in the example) the date specified is earlier
than any time in (b).  Perhaps such a request needs to use some
other syntax rather than @{}, but surely the capability ought to
be provided somehow.
Git could attempt to search all of your branches, like you have
done above ...
Actually, I am not at all sure that one would want --all in the
general case; it works well in my particular case because all
branches in this repository have been merged back to master.

Intuitively, I suspect that the default search set should be all
commits reachable from HEAD.  (BTW I may not have the terminology
exactly right; while I have been working with other CM systems
for a couple of decades, I am quite new to git and there is much
about it that I do not yet understand.)
but which one among all commits from that date should it pick?
The latest one that is not later than the specified date (and time
-- a timestamp within {} can provide more granularity than just
the day; in the example provided there were in fact no commits on
2011-12-29 so no ambiguity would arise from using the date alone.)
Furthermore, the result set to pick from will change if you
fetch more history into your repo.
Using the "commits reachable from HEAD" strategy above, I think
not, unless I also merge from some of that additional history.
It's even worse with the author (as opposed to committer) dates:
those are not even remotely close to monotonic in most repos,
because they are kept across rewriting.  (The committer dates
would be monotonic if everyone kept their clocks in sync and
avoided filter-branch tricks.)
Since it is the file's included commits that "git blame" reports on,
I doubt it would be all that useful to deal in anything other than
commit dates.  (I seem to have copy-pasted the wrong format in the
rev-list part of the example -- it should be "%h %ci".)
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help