threads / discuss / 33241

Which file is older in history?

Subject: Which file is older in history?

## tl;dr

7 messages between Mar 20, 2013 and Mar 21, 2013.

replies: 6people: 3as markdown or json

Ramkumar Ramachandra· Mar 20, 2013, 20:21 UTC · lore
Hi,

I want to compare two files in a git repository and tell which one was introduced into the repository earlier, assuming that they're in the same history line (by ancestry, not timestamp). The naive way to do this is to find the individual commits that introduced the files (`rev-list HEAD -- <filename> | tail -n 1`), and query whether there are commits between them (`rev-list commit1 ^commit2`). However, this is slow. What about bisecting the history until we find a tree that contains one file but not the other?

Thanks.
Ram
Junio C Hamano· Mar 20, 2013, 20:46 UTC · re: Ramkumar Ramachandra · lore

Re: Which file is older in history?

Ramkumar Ramachandra <artagnon@gmail.com> writes:
Show 5 quoted lines
> I want to compare two files in a git repository and tell which one was
> introduced into the repository earlier, assuming that they're in the
> same history line (by ancestry, not timestamp).  The naive way to do
> this is to find the individual commits that introduced the files
> (`rev-list HEAD -- <filename> | tail -n 1`), and...
This must be a trick question but the naïve way I think of is
	git log --diff-filter=A -- path1 path2
Ramkumar Ramachandra· Mar 21, 2013, 11:59 UTC · re: Junio C Hamano · lore

Re: Which file is older in history?

Junio C Hamano wrote:
Show 11 quoted lines
> Ramkumar Ramachandra <artagnon@gmail.com> writes:
>
>> I want to compare two files in a git repository and tell which one was
>> introduced into the repository earlier, assuming that they're in the
>> same history line (by ancestry, not timestamp).  The naive way to do
>> this is to find the individual commits that introduced the files
>> (`rev-list HEAD -- <filename> | tail -n 1`), and...
>
> This must be a trick question but the naïve way I think of is
>
>         git log --diff-filter=A -- path1 path2

Thanks, I didn't know about --diff-filter. I'll need one extra step to figure out which commit corresponds to the introduction of which file, no?

Jeff King· Mar 21, 2013, 12:21 UTC · re: Ramkumar Ramachandra · lore

Re: Which file is older in history?

On Thu, Mar 21, 2013 at 05:29:39PM +0530, Ramkumar Ramachandra wrote:
Show 7 quoted lines
> > This must be a trick question but the naïve way I think of is
> >
> >         git log --diff-filter=A -- path1 path2
> 
> Thanks, I didn't know about --diff-filter.  I'll need one extra step
> to figure out which commit corresponds to the introduction of which
> file, no?
Maybe
  git log --format=%H --name-status --diff-filter=A -- path1 path2 |
  perl -lne '
    if (/[0-9a-f]{40}/) { $commit = $& }
    elsif (/^A\t(.*)/) { $h{$1} = $commit }
    END { print "$h{$_} $_" for keys(%h) }
  '
?
-Peff
Jeff King· Mar 21, 2013, 12:24 UTC · re: Jeff King · lore

Re: Which file is older in history?

On Thu, Mar 21, 2013 at 08:21:30AM -0400, Jeff King wrote:
Show 18 quoted lines
> On Thu, Mar 21, 2013 at 05:29:39PM +0530, Ramkumar Ramachandra wrote:
> 
> > > This must be a trick question but the naïve way I think of is
> > >
> > >         git log --diff-filter=A -- path1 path2
> > 
> > Thanks, I didn't know about --diff-filter.  I'll need one extra step
> > to figure out which commit corresponds to the introduction of which
> > file, no?
> 
> Maybe
> 
>   git log --format=%H --name-status --diff-filter=A -- path1 path2 |
>   perl -lne '
>     if (/[0-9a-f]{40}/) { $commit = $& }
>     elsif (/^A\t(.*)/) { $h{$1} = $commit }
>     END { print "$h{$_} $_" for keys(%h) }
>   '

Actually, I only looked at your question, not the original point, which was not which commit was which, but which one was older. If you just want to know which is older, then just:

  git log --format=%H --name-status --diff-filter=A -- path1 path2 |
  grep ^A |
  tail -1

which uses the regular traversal order (i.e., mostly following commit timestamps). You can use --topo-order if you want to make sure it follows the graph structure.

-Peff
Ramkumar Ramachandra· Mar 21, 2013, 12:32 UTC · re: Jeff King · lore

Re: Which file is older in history?

Jeff King wrote:
Show 28 quoted lines
> On Thu, Mar 21, 2013 at 08:21:30AM -0400, Jeff King wrote:
>
>> On Thu, Mar 21, 2013 at 05:29:39PM +0530, Ramkumar Ramachandra wrote:
>>
>> > > This must be a trick question but the naïve way I think of is
>> > >
>> > >         git log --diff-filter=A -- path1 path2
>> >
>> > Thanks, I didn't know about --diff-filter.  I'll need one extra step
>> > to figure out which commit corresponds to the introduction of which
>> > file, no?
>>
>> Maybe
>>
>>   git log --format=%H --name-status --diff-filter=A -- path1 path2 |
>>   perl -lne '
>>     if (/[0-9a-f]{40}/) { $commit = $& }
>>     elsif (/^A\t(.*)/) { $h{$1} = $commit }
>>     END { print "$h{$_} $_" for keys(%h) }
>>   '
>
> Actually, I only looked at your question, not the original point, which
> was not which commit was which, but which one was older. If you just
> want to know which is older, then just:
>
>   git log --format=%H --name-status --diff-filter=A -- path1 path2 |
>   grep ^A |
>   tail -1
Great!  I just learnt about --name-status now.
Nit: tail -<n> is deprecated in favor of tail -n <n>, I think.  It's
nicer to have definite fixed command line options, as opposed to
parsing an arbitrary -(*) and deciding if \1 is a \d+.
Jeff King· Mar 21, 2013, 13:26 UTC · re: Ramkumar Ramachandra · lore

Re: Which file is older in history?

On Thu, Mar 21, 2013 at 06:02:32PM +0530, Ramkumar Ramachandra wrote:
Show 5 quoted lines
> >   git log --format=%H --name-status --diff-filter=A -- path1 path2 |
> >   grep ^A |
> >   tail -1
> 
> Great!  I just learnt about --name-status now.
You can also use "--name-only", but the parsing is a little less robust.
> Nit: tail -<n> is deprecated in favor of tail -n <n>, I think.  It's
> nicer to have definite fixed command line options, as opposed to
> parsing an arbitrary -(*) and deciding if \1 is a \d+.

Yeah, POSIX has always specified "-n" for tail, as well as for head. I remember in the late 90's and early 00's running into systems where POSIX "head -n" did not work, and you _had_ to use "head -1". I don't recall now if that was the case for tail, too, nor what system that was on (but if I had to guess, I'd say pre-Solaris SunOS).

So yeah. Using "tail -n 1" is probably a better idea in the long run.
-Peff

← back to recent threads