Merge branch 'jh/update-ref-d-through-symref'
authorJunio C Hamano <gitster@pobox.com>
Mon, 26 Nov 2012 02:44:17 +0000 (18:44 -0800)
committerJunio C Hamano <gitster@pobox.com>
Mon, 26 Nov 2012 02:44:17 +0000 (18:44 -0800)
"update-ref -d --deref SYM" to delete a ref through a symbolic ref
that points to it did not remove it correctly.

* jh/update-ref-d-through-symref:
Fix failure to delete a packed ref through a symref
t1400-update-ref: Add test verifying bug with symrefs in delete_ref()

1  2 
refs.c
diff --combined refs.c
index 726c53c540a94c6ac994aa768c1ffb355ca4538e,b4c57af998122f11a45823a92ffbe001975abaea..6cec1c8bdf70589a41c2ace4ba4f21f4035e4ed4
--- 1/refs.c
--- 2/refs.c
+++ b/refs.c
@@@ -1202,8 -1202,6 +1202,8 @@@ int peel_ref(const char *refname, unsig
        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;
                }
        }
  
  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;
@@@ -1762,24 -1753,32 +1762,24 @@@ int delete_ref(const char *refname, con
        struct ref_lock *lock;
        int err, i = 0, ret = 0, flag = 0;
  
 -      lock = lock_ref_sha1_basic(refname, sha1, 0, &flag);
 +      lock = lock_ref_sha1_basic(refname, sha1, delopt, &flag);
        if (!lock)
                return 1;
        if (!(flag & REF_ISPACKED) || flag & REF_ISSYMREF) {
                /* loose */
 -              const char *path;
 -
 -              if (!(delopt & REF_NODEREF)) {
 -                      i = strlen(lock->lk->filename) - 5; /* .lock */
 -                      lock->lk->filename[i] = 0;
 -                      path = lock->lk->filename;
 -              } else {
 -                      path = git_path("%s", refname);
 -              }
 -              err = unlink_or_warn(path);
 +              i = strlen(lock->lk->filename) - 5; /* .lock */
 +              lock->lk->filename[i] = 0;
 +              err = unlink_or_warn(lock->lk->filename);
                if (err && errno != ENOENT)
                        ret = 1;
  
 -              if (!(delopt & REF_NODEREF))
 -                      lock->lk->filename[i] = '.';
 +              lock->lk->filename[i] = '.';
        }
        /* removing the loose one could have resurrected an earlier
         * packed one.  Also, if it was not loose we need to repack
         * without it.
         */
-       ret |= repack_without_ref(refname);
+       ret |= repack_without_ref(lock->ref_name);
  
        unlink_or_warn(git_path("logs/%s", lock->ref_name));
        invalidate_ref_cache(NULL);