remote-curl.c: convert fetch_git() to use argv_array
[gitweb.git] / refs / files-backend.c
index 69c3ecfe1bc193da2721d5cebbfc65aea59139d0..b56976288819c87307c03e4e5abf9b9458d09970 100644 (file)
@@ -933,6 +933,10 @@ static void clear_loose_ref_cache(struct ref_cache *refs)
        }
 }
 
+/*
+ * Create a new submodule ref cache and add it to the internal
+ * set of caches.
+ */
 static struct ref_cache *create_ref_cache(const char *submodule)
 {
        int len;
@@ -942,16 +946,12 @@ static struct ref_cache *create_ref_cache(const char *submodule)
        len = strlen(submodule) + 1;
        refs = xcalloc(1, sizeof(struct ref_cache) + len);
        memcpy(refs->name, submodule, len);
+       refs->next = submodule_ref_caches;
+       submodule_ref_caches = refs;
        return refs;
 }
 
-/*
- * Return a pointer to a ref_cache for the specified submodule. For
- * the main repository, use submodule==NULL. The returned structure
- * will be allocated and initialized but not necessarily populated; it
- * should not be freed.
- */
-static struct ref_cache *get_ref_cache(const char *submodule)
+static struct ref_cache *lookup_ref_cache(const char *submodule)
 {
        struct ref_cache *refs;
 
@@ -961,10 +961,20 @@ static struct ref_cache *get_ref_cache(const char *submodule)
        for (refs = submodule_ref_caches; refs; refs = refs->next)
                if (!strcmp(submodule, refs->name))
                        return refs;
+       return NULL;
+}
 
-       refs = create_ref_cache(submodule);
-       refs->next = submodule_ref_caches;
-       submodule_ref_caches = refs;
+/*
+ * Return a pointer to a ref_cache for the specified submodule. For
+ * the main repository, use submodule==NULL. The returned structure
+ * will be allocated and initialized but not necessarily populated; it
+ * should not be freed.
+ */
+static struct ref_cache *get_ref_cache(const char *submodule)
+{
+       struct ref_cache *refs = lookup_ref_cache(submodule);
+       if (!refs)
+               refs = create_ref_cache(submodule);
        return refs;
 }
 
@@ -1336,16 +1346,24 @@ static int resolve_gitlink_ref_recursive(struct ref_cache *refs,
 int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *sha1)
 {
        int len = strlen(path), retval;
-       char *submodule;
+       struct strbuf submodule = STRBUF_INIT;
        struct ref_cache *refs;
 
        while (len && path[len-1] == '/')
                len--;
        if (!len)
                return -1;
-       submodule = xstrndup(path, len);
-       refs = get_ref_cache(submodule);
-       free(submodule);
+
+       strbuf_add(&submodule, path, len);
+       refs = lookup_ref_cache(submodule.buf);
+       if (!refs) {
+               if (!is_nonbare_repository_dir(&submodule)) {
+                       strbuf_release(&submodule);
+                       return -1;
+               }
+               refs = create_ref_cache(submodule.buf);
+       }
+       strbuf_release(&submodule);
 
        retval = resolve_gitlink_ref_recursive(refs, refname, sha1, 0);
        return retval;
@@ -1887,7 +1905,8 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
        const char *orig_refname = refname;
        struct ref_lock *lock;
        int last_errno = 0;
-       int type, lflags;
+       int type;
+       int lflags = 0;
        int mustexist = (old_sha1 && !is_null_sha1(old_sha1));
        int resolve_flags = 0;
        int attempts_remaining = 3;
@@ -1898,10 +1917,11 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
 
        if (mustexist)
                resolve_flags |= RESOLVE_REF_READING;
-       if (flags & REF_DELETING) {
+       if (flags & REF_DELETING)
                resolve_flags |= RESOLVE_REF_ALLOW_BAD_NAME;
-               if (flags & REF_NODEREF)
-                       resolve_flags |= RESOLVE_REF_NO_RECURSE;
+       if (flags & REF_NODEREF) {
+               resolve_flags |= RESOLVE_REF_NO_RECURSE;
+               lflags |= LOCK_NO_DEREF;
        }
 
        refname = resolve_ref_unsafe(refname, resolve_flags,
@@ -1937,6 +1957,10 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
 
                goto error_return;
        }
+
+       if (flags & REF_NODEREF)
+               refname = orig_refname;
+
        /*
         * If the ref did not exist and we are creating it, make sure
         * there is no existing packed ref whose name begins with our
@@ -1952,11 +1976,6 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
 
        lock->lk = xcalloc(1, sizeof(struct lock_file));
 
-       lflags = 0;
-       if (flags & REF_NODEREF) {
-               refname = orig_refname;
-               lflags |= LOCK_NO_DEREF;
-       }
        lock->ref_name = xstrdup(refname);
        lock->orig_ref_name = xstrdup(orig_refname);
        strbuf_git_path(&ref_file, "%s", refname);