refs: introduce get_worktree_ref_store()
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>
Mon, 24 Apr 2017 10:01:22 +0000 (17:01 +0700)
committerJunio C Hamano <gitster@pobox.com>
Tue, 25 Apr 2017 04:28:55 +0000 (21:28 -0700)
files-backend at this point is still aware of the per-repo/worktree
separation in refs, so it can handle a linked worktree.

Some refs operations are known not working when current files-backend is
used in a linked worktree (e.g. reflog). Tests will be written when
refs_* functions start to be called with worktree backend to verify that
they work as expected.

Note: accessing a worktree of a submodule remains unaddressed. Perhaps
after get_worktrees() can access submodule (or rather a new function
get_submodule_worktrees(), that lists worktrees of a submodule), we can
update this function to work with submodules as well.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
refs.c
refs.h
diff --git a/refs.c b/refs.c
index 6e6f0ec5be1d81acc12c0b51675e7661d35478c9..7972720256053a953c8c17db22b9dc323693a16c 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -10,6 +10,7 @@
 #include "object.h"
 #include "tag.h"
 #include "submodule.h"
+#include "worktree.h"
 
 /*
  * List of all available backends
@@ -1486,6 +1487,9 @@ static struct ref_store *main_ref_store;
 /* A hashmap of ref_stores, stored by submodule name: */
 static struct hashmap submodule_ref_stores;
 
+/* A hashmap of ref_stores, stored by worktree id: */
+static struct hashmap worktree_ref_stores;
+
 /*
  * Look up a ref store by name. If that ref_store hasn't been
  * registered yet, return NULL.
@@ -1586,6 +1590,32 @@ struct ref_store *get_submodule_ref_store(const char *submodule)
        return refs;
 }
 
+struct ref_store *get_worktree_ref_store(const struct worktree *wt)
+{
+       struct ref_store *refs;
+       const char *id;
+
+       if (wt->is_current)
+               return get_main_ref_store();
+
+       id = wt->id ? wt->id : "/";
+       refs = lookup_ref_store_map(&worktree_ref_stores, id);
+       if (refs)
+               return refs;
+
+       if (wt->id)
+               refs = ref_store_init(git_common_path("worktrees/%s", wt->id),
+                                     REF_STORE_ALL_CAPS);
+       else
+               refs = ref_store_init(get_git_common_dir(),
+                                     REF_STORE_ALL_CAPS);
+
+       if (refs)
+               register_ref_store_map(&worktree_ref_stores, "worktree",
+                                      refs, id);
+       return refs;
+}
+
 void base_ref_store_init(struct ref_store *refs,
                         const struct ref_storage_be *be)
 {
diff --git a/refs.h b/refs.h
index 49e97d7d5fdf1ce385ea8917bda00a4cce68561f..6df69a2adbed84a132161cc472d0353fb16f7445 100644 (file)
--- a/refs.h
+++ b/refs.h
@@ -5,6 +5,7 @@ struct object_id;
 struct ref_store;
 struct strbuf;
 struct string_list;
+struct worktree;
 
 /*
  * Resolve a reference, recursively following symbolic refererences.
@@ -655,5 +656,6 @@ struct ref_store *get_main_ref_store(void);
  * submodule==NULL.
  */
 struct ref_store *get_submodule_ref_store(const char *submodule);
+struct ref_store *get_worktree_ref_store(const struct worktree *wt);
 
 #endif /* REFS_H */