diff options
author | Linus Torvalds <torvalds@osdl.org> | 2005-10-18 18:29:17 -0700 |
---|---|---|
committer | Junio C Hamano <junkio@cox.net> | 2005-10-18 18:41:28 -0700 |
commit | fe5f51ce277df00cb01dfc984dba1e7128718e41 (patch) | |
tree | c358e2c3855b9a35a4685032d7fba2db65c0ecc4 /rev-list.c | |
parent | 3e04c62daab0a8481f907c30414ed246f284a1d9 (diff) | |
download | git-fe5f51ce277df00cb01dfc984dba1e7128718e41.tar.gz git-fe5f51ce277df00cb01dfc984dba1e7128718e41.tar.xz |
Optimize common case of git-rev-list
I took a look at webgit, and it looks like at least for the "projects"
page, the most common operation ends up being basically
git-rev-list --header --parents --max-count=1 HEAD
Now, the thing is, the way "git-rev-list" works, it always keeps on
popping the parents and parsing them in order to build the list of
parents, and it turns out that even though we just want a single commit,
git-rev-list will invariably look up _three_ generations of commits.
It will parse:
- the commit we want (it obviously needs this)
- it's parent(s) as part of the "pop_most_recent_commit()" logic
- it will then pop one of the parents before it notices that it doesn't
need any more
- and as part of popping the parent, it will parse the grandparent (again
due to "pop_most_recent_commit()".
Now, I've strace'd it, and it really is pretty efficient on the whole, but
if things aren't nicely cached, and with long-latency IO, doing those two
extra objects (at a minimum - if the parent is a merge it will be more) is
just wasted time, and potentially a lot of it.
So here's a quick special-case for the trivial case of "just one commit,
and no date-limits or other special rules".
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
Diffstat (limited to 'rev-list.c')
-rw-r--r-- | rev-list.c | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/rev-list.c b/rev-list.c index c60aa7295..3a32e405a 100644 --- a/rev-list.c +++ b/rev-list.c @@ -624,6 +624,11 @@ int main(int argc, char **argv) if (!merge_order) { sort_by_date(&list); + if (list && !limited && max_count == 1 && + !tag_objects && !tree_objects && !blob_objects) { + show_commit(list->item); + return 0; + } if (limited) list = limit_list(list); if (topo_order) |