Merge branch 'jk/peel-ref'
authorJeff King <peff@peff.net>
Thu, 25 Oct 2012 10:42:27 +0000 (06:42 -0400)
committerJeff King <peff@peff.net>
Thu, 25 Oct 2012 10:42:27 +0000 (06:42 -0400)
Speeds up "git upload-pack" (what is invoked by "git fetch" on the
other side of the connection) by reducing the cost to advertise the
branches and tags that are available in the repository.

* jk/peel-ref:
upload-pack: use peel_ref for ref advertisements
peel_ref: check object type before loading
peel_ref: do not return a null sha1
peel_ref: use faster deref_tag_noverify

builtin/describe.c
builtin/pack-objects.c
builtin/show-ref.c
refs.c
upload-pack.c
index 9fe11ed9de7b9e5c13187a630c45d8e44f50c851..04c185b1fbdc51ba9958fdb83d1c6616bcb0c18e 100644 (file)
@@ -144,7 +144,7 @@ static int get_name(const char *path, const unsigned char *sha1, int flag, void
        if (!all && !might_be_tag)
                return 0;
 
-       if (!peel_ref(path, peeled) && !is_null_sha1(peeled)) {
+       if (!peel_ref(path, peeled)) {
                is_tag = !!hashcmp(sha1, peeled);
        } else {
                hashcpy(peeled, sha1);
index 5e140640947cd9c38da00a01d8db9f036e8babd7..f069462cb03bbae46dae8d6b97420b3726690c47 100644 (file)
@@ -2033,7 +2033,6 @@ static int add_ref_tag(const char *path, const unsigned char *sha1, int flag, vo
 
        if (!prefixcmp(path, "refs/tags/") && /* is a tag? */
            !peel_ref(path, peeled)        && /* peelable? */
-           !is_null_sha1(peeled)          && /* annotated tag? */
            locate_object_entry(peeled))      /* object packed? */
                add_object_entry(sha1, OBJ_TAG, NULL, 0);
        return 0;
index 4eb016d6e53628f19d51a50aeb074bf424154026..8d9b76a02fd115c0285216c27c5232f345d0582d 100644 (file)
@@ -28,7 +28,6 @@ static void show_one(const char *refname, const unsigned char *sha1)
 
 static int show_ref(const char *refname, const unsigned char *sha1, int flag, void *cbdata)
 {
-       struct object *obj;
        const char *hex;
        unsigned char peeled[20];
 
@@ -79,25 +78,9 @@ static int show_ref(const char *refname, const unsigned char *sha1, int flag, vo
        if (!deref_tags)
                return 0;
 
-       if ((flag & REF_ISPACKED) && !peel_ref(refname, peeled)) {
-               if (!is_null_sha1(peeled)) {
-                       hex = find_unique_abbrev(peeled, abbrev);
-                       printf("%s %s^{}\n", hex, refname);
-               }
-       }
-       else {
-               obj = parse_object(sha1);
-               if (!obj)
-                       die("git show-ref: bad ref %s (%s)", refname,
-                           sha1_to_hex(sha1));
-               if (obj->type == OBJ_TAG) {
-                       obj = deref_tag(obj, refname, 0);
-                       if (!obj)
-                               die("git show-ref: bad tag at ref %s (%s)", refname,
-                                   sha1_to_hex(sha1));
-                       hex = find_unique_abbrev(obj->sha1, abbrev);
-                       printf("%s %s^{}\n", hex, refname);
-               }
+       if (!peel_ref(refname, peeled)) {
+               hex = find_unique_abbrev(peeled, abbrev);
+               printf("%s %s^{}\n", hex, refname);
        }
        return 0;
 }
diff --git a/refs.c b/refs.c
index da74a2b29a20a2c94fef61641e35980007c1ab95..02e47b1157c367f9233ae88870b9a43cbe1a7d52 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -1202,6 +1202,8 @@ int peel_ref(const char *refname, unsigned char *sha1)
        if (current_ref && (current_ref->name == refname
                || !strcmp(current_ref->name, refname))) {
                if (current_ref->flag & REF_KNOWS_PEELED) {
+                       if (is_null_sha1(current_ref->u.value.peeled))
+                           return -1;
                        hashcpy(sha1, current_ref->u.value.peeled);
                        return 0;
                }
@@ -1223,9 +1225,16 @@ int peel_ref(const char *refname, unsigned char *sha1)
        }
 
 fallback:
-       o = parse_object(base);
-       if (o && o->type == OBJ_TAG) {
-               o = deref_tag(o, refname, 0);
+       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);
                        return 0;
index 2e90ccb74fe45e6335ee6a76451da40d7d3f5a09..6142421ea1172f7fe6b57486a4f41b81d92bab85 100644 (file)
@@ -727,12 +727,7 @@ static int send_ref(const char *refname, const unsigned char *sha1, int flag, vo
                " include-tag multi_ack_detailed";
        struct object *o = lookup_unknown_object(sha1);
        const char *refname_nons = strip_namespace(refname);
-
-       if (o->type == OBJ_NONE) {
-               o->type = sha1_object_info(sha1, NULL);
-               if (o->type < 0)
-                   die("git upload-pack: cannot find object %s:", sha1_to_hex(sha1));
-       }
+       unsigned char peeled[20];
 
        if (capabilities)
                packet_write(1, "%s %s%c%s%s agent=%s\n",
@@ -747,11 +742,8 @@ static int send_ref(const char *refname, const unsigned char *sha1, int flag, vo
                o->flags |= OUR_REF;
                nr_our_refs++;
        }
-       if (o->type == OBJ_TAG) {
-               o = deref_tag_noverify(o);
-               if (o)
-                       packet_write(1, "%s %s^{}\n", sha1_to_hex(o->sha1), refname_nons);
-       }
+       if (!peel_ref(refname, peeled))
+               packet_write(1, "%s %s^{}\n", sha1_to_hex(peeled), refname_nons);
        return 0;
 }