Skip to content

Commit ec0c579

Browse files
jonathantanmygitster
authored andcommitted
revision: use commit graph in get_reference()
When fetching into a repository, a connectivity check is first made by check_exist_and_connected() in builtin/fetch.c that runs: git rev-list --objects --stdin --not --all --quiet <(list of objects) If the client repository has many refs, this command can be slow, regardless of the nature of the server repository or what is being fetched. A profiler reveals that most of the time is spent in setup_revisions() (approx. 60/63), and of the time spent in setup_revisions(), most of it is spent in parse_object() (approx. 49/60). This is because setup_revisions() parses the target of every ref (from "--all"), and parse_object() reads the buffer of the object. Reading the buffer is unnecessary if the repository has a commit graph and if the ref points to a commit (which is typically the case). This patch uses the commit graph wherever possible; on my computer, when I run the above command with a list of 1 object on a many-ref repository, I get a speedup from 1.8s to 1.0s. Another way to accomplish this effect would be to modify parse_object() to use the commit graph if possible; however, I did not want to change parse_object()'s current behavior of always checking the object signature of the returned object. Signed-off-by: Jonathan Tan <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent ff509c5 commit ec0c579

File tree

1 file changed

+14
-1
lines changed

1 file changed

+14
-1
lines changed

revision.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,20 @@ static struct object *get_reference(struct rev_info *revs, const char *name,
212212
{
213213
struct object *object;
214214

215-
object = parse_object(revs->repo, oid);
215+
/*
216+
* If the repository has commit graphs, repo_parse_commit() avoids
217+
* reading the object buffer, so use it whenever possible.
218+
*/
219+
if (oid_object_info(revs->repo, oid, NULL) == OBJ_COMMIT) {
220+
struct commit *c = lookup_commit(revs->repo, oid);
221+
if (!repo_parse_commit(revs->repo, c))
222+
object = (struct object *) c;
223+
else
224+
object = NULL;
225+
} else {
226+
object = parse_object(revs->repo, oid);
227+
}
228+
216229
if (!object) {
217230
if (revs->ignore_missing)
218231
return object;

0 commit comments

Comments
 (0)