commit_ref_update(): write error message to *err, not stderr
[gitweb.git] / refs / files-backend.c
index 1f38076411dc62b82792b677d95fe775effc79cd..2d3a8c669a5b04a7e70da881f70e04dc5ba96c5e 100644 (file)
@@ -1477,7 +1477,16 @@ int read_raw_ref(const char *refname, unsigned char *sha1,
 
        /* Is it a directory? */
        if (S_ISDIR(st.st_mode)) {
-               errno = EISDIR;
+               /*
+                * Even though there is a directory where the loose
+                * ref is supposed to be, there could still be a
+                * packed ref:
+                */
+               if (resolve_missing_loose_ref(refname, sha1, flags)) {
+                       errno = EISDIR;
+                       goto out;
+               }
+               ret = 0;
                goto out;
        }
 
@@ -2457,6 +2466,30 @@ static int close_ref(struct ref_lock *lock)
 
 static int commit_ref(struct ref_lock *lock)
 {
+       char *path = get_locked_file_path(lock->lk);
+       struct stat st;
+
+       if (!lstat(path, &st) && S_ISDIR(st.st_mode)) {
+               /*
+                * There is a directory at the path we want to rename
+                * the lockfile to. Hopefully it is empty; try to
+                * delete it.
+                */
+               size_t len = strlen(path);
+               struct strbuf sb_path = STRBUF_INIT;
+
+               strbuf_attach(&sb_path, path, len, len);
+
+               /*
+                * If this fails, commit_lock_file() will also fail
+                * and will report the problem.
+                */
+               remove_empty_directories(&sb_path);
+               strbuf_release(&sb_path);
+       } else {
+               free(path);
+       }
+
        if (commit_lock_file(lock->lk))
                return -1;
        return 0;
@@ -2686,7 +2719,7 @@ static int commit_ref_update(struct ref_lock *lock,
                }
        }
        if (commit_ref(lock)) {
-               error("Couldn't set %s", lock->ref_name);
+               strbuf_addf(err, "Couldn't set %s", lock->ref_name);
                unlock_ref(lock);
                return -1;
        }