Re: Finding file revisions
- From
Linus Torvalds <torvalds@osdl.org>
- Date
- Apr 27, 2005, 22:19 UTC
- Message-ID
- <Pine.LNX.4.58.0504271506290.18901@ppc970.osdl.org>
- In-Reply-To
- <200504271423.37433.mason@suse.com>
On Wed, 27 Apr 2005, Chris Mason wrote:
Show 7 quoted lines
> > So, new prog attached. New usage: > > file-changes [-c commit_id] [-s commit_id] file ... > > -c is the commit where you want to start searching > -s is the commit where you want to stop searching
Your script will do some funky stuff, because you incorrectly think that the rev-list is sorted linearly. It's not. It's sorted in a rough chronological order, but you really can't do the "last" vs "cur" thing that you do, because two commits after each other in the rev-list listing may well be from two totally different branches, so when you compare one tree against the other, you're really doing something pretty nonsensical.
diff-tree will happily compare trees that aren't related, so it will "work" in a sense, but it doesn't actually do what you think it does ;)
So what you should do is basically something like
open(RL, "rev-list $commit|") || die "rev-list failed";
while(<RL>) {
chomp;
my $cur = $_;(so far so good) but then you should look at the _parents_ of that commit, ie do (NOTE NOTE NOTE! I'm a total perl idiot, so I'm not going to do this right):
open(PARENT, "cat-file commit $cur") || die "cat-file failed");
while(<PARENT>) {
chomp;
my @words = split;
if ($words[1] == "tree")
continue;
if ($words[1] != "parent")
break;
test_diff($cur, $words[2]);
}
close(PARENT);
}
close(RL);and now your "test_diff()" thing can do the tree diff.
That way you actually do "tree-diff" on the thing you should do, and it will show you _which_ way it changed in a merge (ie if you hit a merge-point, it will do a tree-diff against both parents, and show you which one had the difference - then you'll obviously usually see that same difference later on when you dig down to the actual changeset that did it too).
Remember: time is not a nice linear stream.
Linus