threads / discuss / 38265

Why do dates in refspecs require the reflog?

Subject: Why do dates in refspecs require the reflog?

## tl;dr

9 messages between Dec 30, 2014 and Dec 31, 2014.

replies: 8people: 5as markdown or json

Robert Dailey· Dec 30, 2014, 20:12 UTC · lore
I was surprised to find today that the following didn't work as expected:
$ git show master@{"1 year ago"}:Path/To/File.h

It gave me the following warning which did not make the problem obvious at all: warning: Log for 'master' only goes back to Mon, 8 Sep 2014 12:08:44 -0500.

What it is trying to tell me (and I only found this out after a lot of poking and prodding around Google) is that I can't refer to a commit by date if it extends beyond the range of the reflog.

I don't understand why this requirement is in place. Each commit has a time stamp, so in theory it should be possible to calculate an absolute date from the duration specified in the refspec and grab the commit from `git log` from that.

I can only assume I'm oversimplifying things and that there is a good reason for this. If I can't get this to work, how can I view the contents of a file at a specified relative time frame as I have done above?

Stefan Beller· Dec 30, 2014, 20:16 UTC · re: Robert Dailey · lore

Re: Why do dates in refspecs require the reflog?

On Tue, Dec 30, 2014 at 12:12 PM, Robert Dailey <rcdailey.lists@gmail.com> wrote:

Show 15 quoted lines
> I was surprised to find today that the following didn't work as expected:
>
> $ git show master@{"1 year ago"}:Path/To/File.h
>
> It gave me the following warning which did not make the problem obvious at all:
> warning: Log for 'master' only goes back to Mon, 8 Sep 2014 12:08:44 -0500.
>
> What it is trying to tell me (and I only found this out after a lot of
> poking and prodding around Google) is that I can't refer to a commit
> by date if it extends beyond the range of the reflog.
>
> I don't understand why this requirement is in place. Each commit has a
> time stamp, so in theory it should be possible to calculate an
> absolute date from the duration specified in the refspec and grab the
> commit from `git log` from that.

Because the commit may have existed at a certain date, but not in the branch. It may have been merged at a later time. I am not sure if this is the actual reason though.

Show 9 quoted lines
>
> I can only assume I'm oversimplifying things and that there is a good
> reason for this. If I can't get this to work, how can I view the
> contents of a file at a specified relative time frame as I have done
> above?
> --
> To unsubscribe from this list: send the line "unsubscribe git" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
Junio C Hamano· Dec 30, 2014, 20:31 UTC · re: Robert Dailey · lore

Re: Why do dates in refspecs require the reflog?

Robert Dailey <rcdailey.lists@gmail.com> writes:
Show 15 quoted lines
> I was surprised to find today that the following didn't work as expected:
>
> $ git show master@{"1 year ago"}:Path/To/File.h
>
> It gave me the following warning which did not make the problem obvious at all:
> warning: Log for 'master' only goes back to Mon, 8 Sep 2014 12:08:44 -0500.
>
> What it is trying to tell me (and I only found this out after a lot of
> poking and prodding around Google) is that I can't refer to a commit
> by date if it extends beyond the range of the reflog.
>
> I don't understand why this requirement is in place. Each commit has a
> time stamp, so in theory it should be possible to calculate an
> absolute date from the duration specified in the refspec and grab the
> commit from `git log` from that.

The reason is because the dates on the commit object itself do not have anything to do with the question you are asking with the "@{date}" notation. master@{at-this-time} notation specifies the commit that was at the tip of your master branch at the specified time, and that information can _only_ come from your own reflogs.

If you did this in your copy of git.git repository today:
    $ git checkout -b test e83c5163316f89bfbd
    $ sleep 3600
    $ git reset --hard master
    $ git show test@{20.minutes.ago}

you will see e83c516, even though that commit is almost 10 years old. Now what was at the tip of your "test" branch on April 7th, 2005? The answer is "nothing", as most likely your 'test' branch did not exist back then.

And that is why "git show test@{2005/04/07}" will not (and should not) look at the timestamps in commit objects.

Junio C Hamano· Dec 30, 2014, 20:47 UTC · re: Robert Dailey · lore

Re: Why do dates in refspecs require the reflog?

Robert Dailey <rcdailey.lists@gmail.com> writes:
> ... how can I view the
> contents of a file at a specified relative time frame ...

"git log --until=A --since=B master" asks Git to start traversing the history backward from the tip of your current 'master' branch, without showing anything until it finds a commit with timestamp A (or before), and then show the commits it finds during the traversal until it finds a commit with timestamp B (or before) and then stop.

Which I think is the closest thing you are asking for.

Note that there is *no* guarantee that any of these commits you find that way was actually at the tip of the public history (i.e. the one casual users would have seen after running "git clone" at that time).

The committer may have started working at around time B, worked for quite some time, and pushed the result out way after time A. Then the first time general public observed the commits you find in that time range could be after time A by many weeks, which is perfectly normal in the real, distributed, world.

Michael Haggerty· Dec 30, 2014, 20:52 UTC · re: Robert Dailey · lore

Re: Why do dates in refspecs require the reflog?

On 12/30/2014 09:12 PM, Robert Dailey wrote:
Show 20 quoted lines
> I was surprised to find today that the following didn't work as expected:
> 
> $ git show master@{"1 year ago"}:Path/To/File.h
> 
> It gave me the following warning which did not make the problem obvious at all:
> warning: Log for 'master' only goes back to Mon, 8 Sep 2014 12:08:44 -0500.
> 
> What it is trying to tell me (and I only found this out after a lot of
> poking and prodding around Google) is that I can't refer to a commit
> by date if it extends beyond the range of the reflog.
> 
> I don't understand why this requirement is in place. Each commit has a
> time stamp, so in theory it should be possible to calculate an
> absolute date from the duration specified in the refspec and grab the
> commit from `git log` from that.
> 
> I can only assume I'm oversimplifying things and that there is a good
> reason for this. If I can't get this to work, how can I view the
> contents of a file at a specified relative time frame as I have done
> above?
The syntax you are using,
    master@{"1 year ago"}

tells you "what commit was the master branch in this clone pointing at one year ago?" What you presumably expected is "What is the last [1] commit that is *currently* on the master branch that was committed at least one year ago?"

The command to ask your question is something like
    git log --date-order --before='1 year ago' -1 master

There is yet a third similar question: "What is the last commit that is currently on the master branch that was *authored* at least one year ago? Please note that this question is even subtler, because author timestamps are often out-of-order even on a single branch (whereas commit timestamps are usually in order). I don't know of a simple git command to answer this question.

Michael

[1] Note that "last" is a bit subtle, because the history of "master" probably contains multiple branches with interleaved dates. So depending on your needs, you might want to add an option like "--first-parent"

-- 
Michael Haggerty
mhagger@alum.mit.edu
Junio C Hamano· Dec 30, 2014, 20:55 UTC · re: Michael Haggerty · lore

Re: Why do dates in refspecs require the reflog?

Michael Haggerty <mhagger@alum.mit.edu> writes:
Show 6 quoted lines
> There is yet a third similar question: "What is the last commit that is
> currently on the master branch that was *authored* at least one year
> ago? Please note that this question is even subtler, because author
> timestamps are often out-of-order even on a single branch (whereas
> commit timestamps are usually in order). I don't know of a simple git
> command to answer this question.
--author-date-order?
Robert Dailey· Dec 30, 2014, 21:39 UTC · re: Junio C Hamano · lore

Re: Why do dates in refspecs require the reflog?

On Tue, Dec 30, 2014 at 2:55 PM, Junio C Hamano <gitster@pobox.com> wrote:
Show 10 quoted lines
> Michael Haggerty <mhagger@alum.mit.edu> writes:
>
>> There is yet a third similar question: "What is the last commit that is
>> currently on the master branch that was *authored* at least one year
>> ago? Please note that this question is even subtler, because author
>> timestamps are often out-of-order even on a single branch (whereas
>> commit timestamps are usually in order). I don't know of a simple git
>> command to answer this question.
>
> --author-date-order?

Thanks to everyone for explaining this, it makes sense now. I've been using git a long time and I found this rather unintuitive because my mindset was not on "reflog" but instead "git log", so there was a huge misunderstanding.

Is it valid to use durations (as Michael has done) in the --since and --until options to `git log`? It also feels like there should be a shorthand for the `git log` usage in conjunction with `git show`... I could probably make an alias for it. But basically what I'm looking for is this (please correct me if I'm wrong):

$ git log --since='1 year ago' -1 (somehow grab the SHA1 from the commit printed above) $ git show <grabbed SHA1>:Path/To/File.h (path to file is parameterized above)

So basically these two commands together could be stuffed into an alias:
$ git log-show '1 year ago' Path/To/File.h

This is the best I can come up with for now. Note also that "accuracy" isn't important here, just "closest matching". I appreciate and understand that things can be out of order (as far as commit timestamps go, since you can rebase and reorder things). Accuracy for these things aren't too important because usually I will use them for bisect or an approximation of where in time I want to see a file for code reference (i.e. how a function "used to look back then").

Jeff King· Dec 31, 2014, 01:26 UTC · re: Robert Dailey · lore

Re: Why do dates in refspecs require the reflog?

On Tue, Dec 30, 2014 at 03:39:53PM -0600, Robert Dailey wrote:
> It also feels like there should be a
> shorthand for the `git log` usage in conjunction with `git show`... I
> could probably make an alias for it.

One thing I didn't see mentioned in this thread is that the question "show me the commit closest to time X" does not have a single answer. When there are branches, there may be many such answers, one for each line of simultaneous development.

So people tend not to ask that question[1], and therefore nobody bothered to make a convenient shorthand for it.

-Peff
[1] What do they ask instead? I find most of my older queries for
    commits are satisfied following parent links from well-known points.
    E.g., finding where topic X was merged, and then walking backwards
    using "^2" to see the tip of the original topic.
    If I am looking for information about a particular file about a year
    ago, I often turn to "-S" or git-blame (actually, "tig blame" in my
    case, which lets you walk backwards interactively).
    But of course the exact query will depend on just what it is you
    want to know. :)
Michael Haggerty· Dec 30, 2014, 21:49 UTC · re: Junio C Hamano · lore

Re: Why do dates in refspecs require the reflog?

On 12/30/2014 09:55 PM, Junio C Hamano wrote:
Show 10 quoted lines
> Michael Haggerty <mhagger@alum.mit.edu> writes:
> 
>> There is yet a third similar question: "What is the last commit that is
>> currently on the master branch that was *authored* at least one year
>> ago? Please note that this question is even subtler, because author
>> timestamps are often out-of-order even on a single branch (whereas
>> commit timestamps are usually in order). I don't know of a simple git
>> command to answer this question.
> 
> --author-date-order?

Does --author-date-order cause --before/--after/--since/--until to use author dates rather than commit dates? The documentation doesn't mention that effect. If not, then it doesn't help much.

Michael
-- 
Michael Haggerty
mhagger@alum.mit.edu

← back to recent threads