xdiff: PATIENCE/HISTOGRAM are not independent option bits
[gitweb.git] / pack-refs.c
index 2c76fb181f64e10c65517224b0c09cb648db81ac..23bbd00e3e542e844fce08156c5c1073e6437d43 100644 (file)
@@ -60,14 +60,46 @@ static int handle_one_ref(const char *path, const unsigned char *sha1,
        return 0;
 }
 
+/*
+ * Remove empty parents, but spare refs/ and immediate subdirs.
+ * Note: munges *name.
+ */
+static void try_remove_empty_parents(char *name)
+{
+       char *p, *q;
+       int i;
+       p = name;
+       for (i = 0; i < 2; i++) { /* refs/{heads,tags,...}/ */
+               while (*p && *p != '/')
+                       p++;
+               /* tolerate duplicate slashes; see check_refname_format() */
+               while (*p == '/')
+                       p++;
+       }
+       for (q = p; *q; q++)
+               ;
+       while (1) {
+               while (q > p && *q != '/')
+                       q--;
+               while (q > p && *(q-1) == '/')
+                       q--;
+               if (q == p)
+                       break;
+               *q = '\0';
+               if (rmdir(git_path("%s", name)))
+                       break;
+       }
+}
+
 /* make sure nobody touched the ref, and unlink */
 static void prune_ref(struct ref_to_prune *r)
 {
        struct ref_lock *lock = lock_ref_sha1(r->name + 5, r->sha1);
 
        if (lock) {
-               unlink(git_path("%s", r->name));
+               unlink_or_warn(git_path("%s", r->name));
                unlock_ref(lock);
+               try_remove_empty_parents(r->name);
        }
 }
 
@@ -93,8 +125,7 @@ int pack_refs(unsigned int flags)
                                       LOCK_DIE_ON_ERROR);
        cbdata.refs_file = fdopen(fd, "w");
        if (!cbdata.refs_file)
-               die("unable to create ref-pack file structure (%s)",
-                   strerror(errno));
+               die_errno("unable to create ref-pack file structure");
 
        /* perhaps other traits later as well */
        fprintf(cbdata.refs_file, "# pack-refs with: peeled \n");
@@ -103,7 +134,7 @@ int pack_refs(unsigned int flags)
        if (ferror(cbdata.refs_file))
                die("failed to write ref-pack file");
        if (fflush(cbdata.refs_file) || fsync(fd) || fclose(cbdata.refs_file))
-               die("failed to write ref-pack file (%s)", strerror(errno));
+               die_errno("failed to write ref-pack file");
        /*
         * Since the lock file was fdopen()'ed and then fclose()'ed above,
         * assign -1 to the lock file descriptor so that commit_lock_file()
@@ -111,7 +142,7 @@ int pack_refs(unsigned int flags)
         */
        packed.fd = -1;
        if (commit_lock_file(&packed) < 0)
-               die("unable to overwrite old ref-pack file (%s)", strerror(errno));
+               die_errno("unable to overwrite old ref-pack file");
        if (cbdata.flags & PACK_REFS_PRUNE)
                prune_refs(cbdata.ref_to_prune);
        return 0;