Teach git-rev-list to follow just a specified set of files
commitcf4845441c3931731643859dc80a79e52bcd3e0f
authorLinus Torvalds <torvalds@osdl.org>
Fri, 21 Oct 2005 04:25:09 +0000 (20 21:25 -0700)
committerJunio C Hamano <junkio@cox.net>
Sun, 23 Oct 2005 05:49:52 +0000 (22 22:49 -0700)
tree0ef1266d6640a6837ae8db89201f0b108b544d09
parentac1b3d1248f36b26c2eab55022b9a54bde36b1ee
Teach git-rev-list to follow just a specified set of files

This is the first cut at a git-rev-list that knows to ignore commits that
don't change a certain file (or set of files).

NOTE! For now it only prunes _merge_ commits, and follows the parent where
there are no differences in the set of files specified. In the long run,
I'd like to make it re-write the straight-line history too, but for now
the merge simplification is much more fundamentally important (the
rewriting of straight-line history is largely a separate simplification
phase, but the merge simplification needs to happen early if we want to
optimize away unnecessary commit parsing).

If all parents of a merge change some of the files, the merge is left as
is, so the end result is in no way guaranteed to be a linear history, but
it will often be a lot /more/ linear than the full tree, since it prunes
out parents that didn't matter for that set of files.

As an example from the current kernel:

[torvalds@g5 linux]$ git-rev-list HEAD | wc -l
9885
[torvalds@g5 linux]$ git-rev-list HEAD -- Makefile | wc -l
4084
[torvalds@g5 linux]$ git-rev-list HEAD -- drivers/usb | wc -l
5206

and you can also use 'gitk' to more visually see the pruning of the
history tree, with something like

gitk -- drivers/usb

showing a simplified history that tries to follow the first parent in a
merge that is the parent that fully defines drivers/usb/.

Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
rev-list.c