git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* bug report: dates on diff
@ 2017-07-06 12:54 Todd Lewis
  2017-07-06 16:22 ` Junio C Hamano
  0 siblings, 1 reply; 5+ messages in thread
From: Todd Lewis @ 2017-07-06 12:54 UTC (permalink / raw)
  To: git

I've run into what I think is a bug wrt date handling in "git diff". I have some
historical data with which I'm attempting to populate a new git repo with
back-dated commits. That appears to work. But referencing those commits by date
with "git diff" does not. (I have no idea if the problem is limited to "git
diff"; that's just where I've been banging my head.)

I'm using git version 2.9.4.

Below is a recreation of the problem from scratch using made up data. Note that
the "git log" output shows the commits with the correct dates, but referencing
"master@{any-date-before-git-init}" throws a "Warning: Log for 'master' only
goes back to ..." and it erroneously selects the first commit (for 2010 in the
example below, instead of the requested 2012 commit).

Here's the terminal session demonstrating the problem:

[utoddl@tarna tmp]$ mkdir gitbug

[utoddl@tarna tmp]$ cd gitbug

[utoddl@tarna gitbug]$ git init
Initialized empty Git repository in /tmp/gitbug/.git/

[utoddl@tarna gitbug]$ for year in 2010 2011 2012 2013 2014 ; do
> echo "Charter for year $year." > charter_01-01-$year.txt
> touch -d"$year-01-01" charter_01-01-$year.txt
> done

[utoddl@tarna gitbug]$ ls -al
total 20
drwxrwxr-x.  3 utoddl utoddl 160 Jul  6 08:14 .
drwxrwxrwt. 19 root   root   420 Jul  6 08:12 ..
-rw-rw-r--.  1 utoddl utoddl  23 Jan  1  2010 charter_01-01-2010.txt
-rw-rw-r--.  1 utoddl utoddl  23 Jan  1  2011 charter_01-01-2011.txt
-rw-rw-r--.  1 utoddl utoddl  23 Jan  1  2012 charter_01-01-2012.txt
-rw-rw-r--.  1 utoddl utoddl  23 Jan  1  2013 charter_01-01-2013.txt
-rw-rw-r--.  1 utoddl utoddl  23 Jan  1  2014 charter_01-01-2014.txt
drwxrwxr-x.  7 utoddl utoddl 200 Jul  6 08:12 .git

[utoddl@tarna gitbug]$ for year in 2010 2011 2012 2013 2014 ; do
> cp -p charter_01-01-$year.txt charter.txt
> git add charter.txt
> git commit --date="01-01-$year" -m "Committing charter for $year." charter.txt
> done
[master (root-commit) f5dc22c] Committing charter for 2010.
 Date: Fri Jan 1 07:19:45 2010 -0500
 1 file changed, 1 insertion(+)
 create mode 100644 charter.txt
cp: overwrite 'charter.txt'? y
[master dec8944] Committing charter for 2011.
 Date: Sat Jan 1 07:19:47 2011 -0500
 1 file changed, 1 insertion(+), 1 deletion(-)
cp: overwrite 'charter.txt'? y
[master cab72e0] Committing charter for 2012.
 Date: Sun Jan 1 07:19:48 2012 -0500
 1 file changed, 1 insertion(+), 1 deletion(-)
cp: overwrite 'charter.txt'? y
[master a0cbf74] Committing charter for 2013.
 Date: Tue Jan 1 07:19:49 2013 -0500
 1 file changed, 1 insertion(+), 1 deletion(-)
cp: overwrite 'charter.txt'? y
[master a75164c] Committing charter for 2014.
 Date: Wed Jan 1 07:19:53 2014 -0500
 1 file changed, 1 insertion(+), 1 deletion(-)

[utoddl@tarna gitbug]$ git log
commit a75164cdf56b5f7b10e7575ee4aa4f653656e456
Author: Todd Lewis <utoddl@email.unc.edu>
Date:   Wed Jan 1 07:19:53 2014 -0500

    Committing charter for 2014.

commit a0cbf74320f5b2309f697a48a8026328a998d787
Author: Todd Lewis <utoddl@email.unc.edu>
Date:   Tue Jan 1 07:19:49 2013 -0500

    Committing charter for 2013.

commit cab72e0902cb4130de49c5d898ef4cc2daf1e2d1
Author: Todd Lewis <utoddl@email.unc.edu>
Date:   Sun Jan 1 07:19:48 2012 -0500

    Committing charter for 2012.

commit dec8944f3c411f5f667cdfefee0609d38298489f
Author: Todd Lewis <utoddl@email.unc.edu>
Date:   Sat Jan 1 07:19:47 2011 -0500

    Committing charter for 2011.

commit f5dc22c636dd66a51e74dc01935a4879bd4946d6
Author: Todd Lewis <utoddl@email.unc.edu>
Date:   Fri Jan 1 07:19:45 2010 -0500

    Committing charter for 2010.

[utoddl@tarna gitbug]$ git diff master@{01-01-2012} charter.txt
warning: Log for 'master' only goes back to Thu, 6 Jul 2017 08:19:45 -0400.
diff --git a/charter.txt b/charter.txt
index a18dbc9..29fedf9 100644
--- a/charter.txt
+++ b/charter.txt
@@ -1 +1 @@
-Charter for year 2010.
+Charter for year 2014.
[utoddl@tarna gitbug]$

-- 
   +--------------------------------------------------------------+
  / Todd_Lewis@unc.edu  919-445-0091  http://www.unc.edu/~utoddl /
 /      A man's home is his castle, in a manor of speaking.     /
+--------------------------------------------------------------+

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: bug report: dates on diff
  2017-07-06 12:54 bug report: dates on diff Todd Lewis
@ 2017-07-06 16:22 ` Junio C Hamano
  2017-07-06 17:32   ` Todd Lewis
  0 siblings, 1 reply; 5+ messages in thread
From: Junio C Hamano @ 2017-07-06 16:22 UTC (permalink / raw)
  To: Todd Lewis; +Cc: git

Todd Lewis <utoddl@email.unc.edu> writes:

> [utoddl@tarna gitbug]$ git diff master@{01-01-2012} charter.txt
> warning: Log for 'master' only goes back to Thu, 6 Jul 2017 08:19:45 -0400.

What you observed is how <ref>@{<selector>} syntax is designed to
work, and is not limited to "git diff".  Any Git command e.g. "git
rev-parse master@{01-01-2012}", would and should behave the same
way.

The thing to note is that the syntax does not pay any attention to
author or committer dates recorded in the commit objects.  In fact,
if you have a ref that points at an object that is not a commit-ish,
you can still use the syntax.  If you did this, for example

    $ git config core.logallrefupdates always

    $ one=$(echo one | git hash-object --stdin -w)
    $ git update-ref refs/my/blob $one

    ... time passes ...

    $ two=$(echo two | git hash-object --stdin -w)
    $ git update-ref refs/my/blob $two

then "git show my/blob@{2.minutes.ago}" will show the blob object
your refs/my/blob ref was pointing at 2 minutes ago.

And as you may know, blobs do not record any timestamp.  So how does
this work?  

The reason why this works is because the time in <ref>@{$time}
syntax is about asking what was pointed by the <ref> back in $time
in your repository.  It does not matter what timestamp the object
that was pointed by the <ref> has (or does not have).

If you didn't create this repository back in 2012, then the syntax
"master@{01-01-2012}" that asks "Back at the beginning of 2012, what
object did the master branch point at?" does not have a sensible
answer.  That can be seen in the warning you got from Git.

Hope this clarifies.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: bug report: dates on diff
  2017-07-06 16:22 ` Junio C Hamano
@ 2017-07-06 17:32   ` Todd Lewis
  2017-07-06 18:03     ` Junio C Hamano
  0 siblings, 1 reply; 5+ messages in thread
From: Todd Lewis @ 2017-07-06 17:32 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git



On 07/06/2017 12:22 PM, Junio C Hamano wrote:
> If you didn't create this repository back in 2012, then the syntax
> "master@{01-01-2012}" that asks "Back at the beginning of 2012, what
> object did the master branch point at?" does not have a sensible
> answer.  That can be seen in the warning you got from Git.
> 
> Hope this clarifies.

Thanks; it does explain what I saw, and even makes some sense.

However, it does leave me scratching my head about how to accomplish what I set
out to do, or just how to reference commits by their dates as displayed by git
log w/o either changing the system time/date when committing historic data
(which seems like a total no-no), or making multiple passes over "get log" to
determine how to ref. Perhaps there's a way to patch the log to match dates
recorded in relevant objects?

Trying not to sound snide, but, what's the point of "--date=" on commits if you
can't use it later? Granted, things always seem harder until you understand how
the work. Thanks again.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: bug report: dates on diff
  2017-07-06 17:32   ` Todd Lewis
@ 2017-07-06 18:03     ` Junio C Hamano
  2017-07-06 18:05       ` Junio C Hamano
  0 siblings, 1 reply; 5+ messages in thread
From: Junio C Hamano @ 2017-07-06 18:03 UTC (permalink / raw)
  To: Todd Lewis; +Cc: git

Todd Lewis <utoddl@email.unc.edu> writes:

> Trying not to sound snide, but, what's the point of "--date=" on commits if you
> can't use it later? Granted, things always seem harder until you understand how
> the work. Thanks again.

You do not sound snide at all, at least to me ;-)

Imagine this scenario:

 - Contributor A writes a change on 2017-07-01 and send it in to me
 - Contributor B writes a change on 2017-07-03 and send it in to me
 - I apply change from B on 2017-07-04 on 'master'
 - I apply change from A on 2017-07-05 on 'master'
 - You clone the resulting repository from me on 2017-07-06

Now, you have at the tip of 'master' in your repository the commit
that records the change by contributor A.

And there are three times that are relevant to your tip of 'master'.

 - When was the commit that sits at the tip of 'master' made?
 - When was the change recorded in that commit made?
 - When was the commit made at the tip of _your_ 'master'?

and the answers are 2017-07-01, 2017-07-05 and 2017-07-06, respectively.
They are called "committer", "author" and "reflog" timestamps.

The 'master@{<time>}' syntax is about the reflog timestamp.  It
never looks at the former two.  In general whenever you see <ref>@{...},
that is talking about the information that is stored in "reflog",
the record of when and in what order the <ref> in _your_ repository
pointed at various objects.

The "commit --date=<time>" is about tweaking the "author" timestamp
the commit records.  It does not affect the "committer" timestamp.
By definition (of what "reflog" is), it will not affect the reflog
timestamp, because the reflog timestamp for a particular commit
would be different across repositories.  I had A's commit on _my_
master on 2017-07-05, but the time you had it on _your_ master was
not until 2017-07-06.

I think the best way to do this properly would be to extend the
"<ref>^{...}" syntax so that we can say e.g.

    git show "master^{#author-time > 2017-01-01}"

to mean "traverse from the tip of 'master' and find the first commit
that satisfies the given expression, "author-time > 2017-01-01", i.e.
has author timestamp that is later than the specified date.  Which
would be in line with the existing

    git show "master^{/my commit message}"

that means "traverse from the tip of 'master' and find the first
commit that has 'my commit message' in the log message".

Note that "git log --since=<time> --until=<time> master" would be
the thing that is closest to what you would want that already
exists, but that limits by the "committer" timestamp.  You _could_
lie about both author and committer timestamp when building the
backdated history and use this mechanism, but we have author and
committer timestamps that are distinct for a reason, so it is a
rather poor workaround.



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: bug report: dates on diff
  2017-07-06 18:03     ` Junio C Hamano
@ 2017-07-06 18:05       ` Junio C Hamano
  0 siblings, 0 replies; 5+ messages in thread
From: Junio C Hamano @ 2017-07-06 18:05 UTC (permalink / raw)
  To: Todd Lewis; +Cc: git

Junio C Hamano <gitster@pobox.com> writes:

> Imagine this scenario:
>
>  - Contributor A writes a change on 2017-07-01 and send it in to me
>  - Contributor B writes a change on 2017-07-03 and send it in to me
>  - I apply change from B on 2017-07-04 on 'master'
>  - I apply change from A on 2017-07-05 on 'master'
>  - You clone the resulting repository from me on 2017-07-06
>
> Now, you have at the tip of 'master' in your repository the commit
> that records the change by contributor A.
>
> And there are three times that are relevant to your tip of 'master'.
>
>  - When was the commit that sits at the tip of 'master' made?
>  - When was the change recorded in that commit made?
>  - When was the commit made at the tip of _your_ 'master'?
>
> and the answers are 2017-07-01, 2017-07-05 and 2017-07-06, respectively.
> They are called "committer", "author" and "reflog" timestamps.

Oops, obviously the dates have to be 2017-07-05, 2017-07-01 and
2017-07-06.  I made the commit on the 5th (i.e. "committer"
timestamp) that records a change written on the 1st (i.e. "author"
timestamp).

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2017-07-06 18:05 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-07-06 12:54 bug report: dates on diff Todd Lewis
2017-07-06 16:22 ` Junio C Hamano
2017-07-06 17:32   ` Todd Lewis
2017-07-06 18:03     ` Junio C Hamano
2017-07-06 18:05       ` Junio C Hamano

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).