Allow the test suite to pass in a directory whose name contains spaces
[gitweb.git] / refs / ref-cache.c
index 7f247b9170fb131c33933222d12b0468f8f08011..6059362f1dd783977f21c36302b7aec3b18a7f38 100644 (file)
@@ -26,22 +26,6 @@ struct ref_dir *get_ref_dir(struct ref_entry *entry)
                        die("BUG: incomplete ref_store without fill_ref_dir function");
 
                dir->cache->fill_ref_dir(dir->cache->ref_store, dir, entry->name);
-
-               /*
-                * Manually add refs/bisect, which, being
-                * per-worktree, might not appear in the directory
-                * listing for refs/ in the main repo.
-                */
-               if (!strcmp(entry->name, "refs/")) {
-                       int pos = search_ref_dir(dir, "refs/bisect/", 12);
-                       if (pos < 0) {
-                               struct ref_entry *child_entry;
-                               child_entry = create_dir_entry(dir->cache,
-                                                              "refs/bisect/",
-                                                              12, 1);
-                               add_entry_to_dir(dir, child_entry);
-                       }
-               }
                entry->flag &= ~REF_INCOMPLETE;
        }
        return dir;
@@ -193,8 +177,17 @@ static struct ref_dir *search_for_subdir(struct ref_dir *dir,
        return get_ref_dir(entry);
 }
 
-struct ref_dir *find_containing_dir(struct ref_dir *dir,
-                                   const char *refname, int mkdir)
+/*
+ * If refname is a reference name, find the ref_dir within the dir
+ * tree that should hold refname. If refname is a directory name
+ * (i.e., it ends in '/'), then return that ref_dir itself. dir must
+ * represent the top-level directory and must already be complete.
+ * Sort ref_dirs and recurse into subdirectories as necessary. If
+ * mkdir is set, then create any missing directories; otherwise,
+ * return NULL if the desired directory cannot be found.
+ */
+static struct ref_dir *find_containing_dir(struct ref_dir *dir,
+                                          const char *refname, int mkdir)
 {
        const char *slash;
        for (slash = strchr(refname, '/'); slash; slash = strchr(slash + 1, '/')) {
@@ -323,28 +316,11 @@ static void sort_ref_dir(struct ref_dir *dir)
        dir->sorted = dir->nr = i;
 }
 
-int do_for_each_entry_in_dir(struct ref_dir *dir, int offset,
-                            each_ref_entry_fn fn, void *cb_data)
-{
-       int i;
-       assert(dir->sorted == dir->nr);
-       for (i = offset; i < dir->nr; i++) {
-               struct ref_entry *entry = dir->entries[i];
-               int retval;
-               if (entry->flag & REF_DIR) {
-                       struct ref_dir *subdir = get_ref_dir(entry);
-                       sort_ref_dir(subdir);
-                       retval = do_for_each_entry_in_dir(subdir, 0, fn, cb_data);
-               } else {
-                       retval = fn(entry, cb_data);
-               }
-               if (retval)
-                       return retval;
-       }
-       return 0;
-}
-
-void prime_ref_dir(struct ref_dir *dir)
+/*
+ * Load all of the refs from `dir` (recursively) into our in-memory
+ * cache.
+ */
+static void prime_ref_dir(struct ref_dir *dir)
 {
        /*
         * The hard work of loading loose refs is done by get_ref_dir(), so we
@@ -510,12 +486,25 @@ static struct ref_iterator_vtable cache_ref_iterator_vtable = {
        cache_ref_iterator_abort
 };
 
-struct ref_iterator *cache_ref_iterator_begin(struct ref_dir *dir)
+struct ref_iterator *cache_ref_iterator_begin(struct ref_cache *cache,
+                                             const char *prefix,
+                                             int prime_dir)
 {
+       struct ref_dir *dir;
        struct cache_ref_iterator *iter;
        struct ref_iterator *ref_iterator;
        struct cache_ref_iterator_level *level;
 
+       dir = get_ref_dir(cache->root);
+       if (prefix && *prefix)
+               dir = find_containing_dir(dir, prefix, 0);
+       if (!dir)
+               /* There's nothing to iterate over. */
+               return  empty_ref_iterator_begin();
+
+       if (prime_dir)
+               prime_ref_dir(dir);
+
        iter = xcalloc(1, sizeof(*iter));
        ref_iterator = &iter->base;
        base_ref_iterator_init(ref_iterator, &cache_ref_iterator_vtable);
@@ -526,5 +515,9 @@ struct ref_iterator *cache_ref_iterator_begin(struct ref_dir *dir)
        level->index = -1;
        level->dir = dir;
 
+       if (prefix && *prefix)
+               ref_iterator = prefix_ref_iterator_begin(ref_iterator,
+                                                        prefix, 0);
+
        return ref_iterator;
 }