resolve_gitlink_ref_recursive(): change to work with struct ref_cache
[gitweb.git] / refs.c
diff --git a/refs.c b/refs.c
index c62c682def18027993c1dbc9f26100311c92400b..ba7a8b020b64db9699de8a201f6898c9c3a639e5 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -298,14 +298,14 @@ static struct ref_array *get_packed_refs(struct ref_cache *refs)
        return &refs->packed;
 }
 
-static void get_ref_dir(const char *submodule, const char *base,
+static void get_ref_dir(struct ref_cache *refs, const char *base,
                        struct ref_array *array)
 {
        DIR *dir;
        const char *path;
 
-       if (*submodule)
-               path = git_path_submodule(submodule, "%s", base);
+       if (*refs->name)
+               path = git_path_submodule(refs->name, "%s", base);
        else
                path = git_path("%s", base);
 
@@ -336,19 +336,19 @@ static void get_ref_dir(const char *submodule, const char *base,
                        if (has_extension(de->d_name, ".lock"))
                                continue;
                        memcpy(refname + baselen, de->d_name, namelen+1);
-                       refdir = submodule
-                               ? git_path_submodule(submodule, "%s", refname)
+                       refdir = *refs->name
+                               ? git_path_submodule(refs->name, "%s", refname)
                                : git_path("%s", refname);
                        if (stat(refdir, &st) < 0)
                                continue;
                        if (S_ISDIR(st.st_mode)) {
-                               get_ref_dir(submodule, refname, array);
+                               get_ref_dir(refs, refname, array);
                                continue;
                        }
-                       if (submodule) {
+                       if (*refs->name) {
                                hashclr(sha1);
                                flag = 0;
-                               if (resolve_gitlink_ref(submodule, refname, sha1) < 0) {
+                               if (resolve_gitlink_ref(refs->name, refname, sha1) < 0) {
                                        hashclr(sha1);
                                        flag |= REF_ISBROKEN;
                                }
@@ -400,7 +400,7 @@ void warn_dangling_symref(FILE *fp, const char *msg_fmt, const char *refname)
 static struct ref_array *get_loose_refs(struct ref_cache *refs)
 {
        if (!refs->did_loose) {
-               get_ref_dir(refs->name, "refs", &refs->loose);
+               get_ref_dir(refs, "refs", &refs->loose);
                sort_ref_array(&refs->loose);
                refs->did_loose = 1;
        }
@@ -413,42 +413,39 @@ static struct ref_array *get_loose_refs(struct ref_cache *refs)
 
 /*
  * Called by resolve_gitlink_ref_recursive() after it failed to read
- * from "name", which is "module/.git/<refname>". Find <refname> in
- * the packed-refs file for the submodule.
+ * from the loose refs in ref_cache refs. Find <refname> in the
+ * packed-refs file for the submodule.
  */
-static int resolve_gitlink_packed_ref(char *name, int pathlen,
+static int resolve_gitlink_packed_ref(struct ref_cache *refs,
                                      const char *refname, unsigned char *sha1)
 {
-       int retval = -1;
        struct ref_entry *ref;
-       struct ref_array *array;
+       struct ref_array *array = get_packed_refs(refs);
 
-       /* being defensive: resolve_gitlink_ref() did this for us */
-       if (pathlen < 6 || memcmp(name + pathlen - 6, "/.git/", 6))
-               die("Oops");
-       name[pathlen - 6] = '\0'; /* make it path to the submodule */
-       array = get_packed_refs(get_ref_cache(name));
        ref = search_ref_array(array, refname);
-       if (ref != NULL) {
-               memcpy(sha1, ref->sha1, 20);
-               retval = 0;
-       }
-       return retval;
+       if (ref == NULL)
+               return -1;
+
+       memcpy(sha1, ref->sha1, 20);
+       return 0;
 }
 
-static int resolve_gitlink_ref_recursive(char *name, int pathlen,
+static int resolve_gitlink_ref_recursive(struct ref_cache *refs,
                                         const char *refname, unsigned char *sha1,
                                         int recursion)
 {
-       int fd, len = strlen(refname);
+       int fd, len;
        char buffer[128], *p;
+       char *path;
 
-       if (recursion > MAXDEPTH || len > MAXREFLEN)
+       if (recursion > MAXDEPTH || strlen(refname) > MAXREFLEN)
                return -1;
-       memcpy(name + pathlen, refname, len+1);
-       fd = open(name, O_RDONLY);
+       path = *refs->name
+               ? git_path_submodule(refs->name, "%s", refname)
+               : git_path("%s", refname);
+       fd = open(path, O_RDONLY);
        if (fd < 0)
-               return resolve_gitlink_packed_ref(name, pathlen, refname, sha1);
+               return resolve_gitlink_packed_ref(refs, refname, sha1);
 
        len = read(fd, buffer, sizeof(buffer)-1);
        close(fd);
@@ -469,35 +466,24 @@ static int resolve_gitlink_ref_recursive(char *name, int pathlen,
        while (isspace(*p))
                p++;
 
-       return resolve_gitlink_ref_recursive(name, pathlen, p, sha1, recursion+1);
+       return resolve_gitlink_ref_recursive(refs, p, sha1, recursion+1);
 }
 
 int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *sha1)
 {
        int len = strlen(path), retval;
-       char *gitdir;
-       const char *tmp;
+       char *submodule;
+       struct ref_cache *refs;
 
        while (len && path[len-1] == '/')
                len--;
        if (!len)
                return -1;
-       gitdir = xmalloc(len + MAXREFLEN + 8);
-       memcpy(gitdir, path, len);
-       memcpy(gitdir + len, "/.git", 6);
-       len += 5;
-
-       tmp = read_gitfile(gitdir);
-       if (tmp) {
-               free(gitdir);
-               len = strlen(tmp);
-               gitdir = xmalloc(len + MAXREFLEN + 3);
-               memcpy(gitdir, tmp, len);
-       }
-       gitdir[len] = '/';
-       gitdir[++len] = '\0';
-       retval = resolve_gitlink_ref_recursive(gitdir, len, refname, sha1, 0);
-       free(gitdir);
+       submodule = xstrndup(path, len);
+       refs = get_ref_cache(submodule);
+       free(submodule);
+
+       retval = resolve_gitlink_ref_recursive(refs, refname, sha1, 0);
        return retval;
 }