summaryrefslogtreecommitdiff
path: root/refs.c
diff options
context:
space:
mode:
authorJeff King <peff@peff.net>2012-10-04 04:02:53 -0400
committerJunio C Hamano <gitster@pobox.com>2012-10-04 20:34:28 -0700
commit6c4a060d7d895c90610eb442cb4f910fe43ef13a (patch)
tree8d7a9e6e23919cc3d5eeb477145298d352cd6583 /refs.c
parente6dbffa67b8e4c463a8fe18e8599b8623d7f0485 (diff)
downloadgit-6c4a060d7d895c90610eb442cb4f910fe43ef13a.tar.gz
peel_ref: check object type before loading
The point of peel_ref is to dereference tags; if the base object is not a tag, then we can return early without even loading the object into memory. This patch accomplishes that by checking sha1_object_info for the type. For a packed object, we can get away with just looking in the pack index. For a loose object, we only need to inflate the first couple of header bytes. This is a bit of a gamble; if we do find a tag object, then we will end up loading the content anyway, and the extra lookup will have been wasteful. However, if it is not a tag object, then we save loading the object entirely. Depending on the ratio of non-tags to tags in the input, this can be a minor win or minor loss. However, it does give us one potential major win: if a ref points to a large blob (e.g., via an unannotated tag), then we can avoid looking at it entirely. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'refs.c')
-rw-r--r--refs.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/refs.c b/refs.c
index f672ad93a6..02e47b1157 100644
--- a/refs.c
+++ b/refs.c
@@ -1225,8 +1225,15 @@ int peel_ref(const char *refname, unsigned char *sha1)
}
fallback:
- o = parse_object(base);
- if (o && o->type == OBJ_TAG) {
+ o = lookup_unknown_object(base);
+ if (o->type == OBJ_NONE) {
+ int type = sha1_object_info(base, NULL);
+ if (type < 0)
+ return -1;
+ o->type = type;
+ }
+
+ if (o->type == OBJ_TAG) {
o = deref_tag_noverify(o);
if (o) {
hashcpy(sha1, o->sha1);