Subject: [PATCH 8/8] refs: adjust main repo paths when $CWD moves

From: Nguyễn Thái Ngọc Duy <[email-masked]>
Date: Wed, 28 Mar 2018 19:55:37 +0200

From: Duy Nguyen <[email-masked]>

Signed-off-by: Nguyễn Thái Ngọc Duy <[email-masked]>
---
 refs.c                | 10 ++++++++++
 refs/files-backend.c  | 15 +++++++++++++++
 refs/packed-backend.c | 12 ++++++++++++
 refs/refs-internal.h  |  4 ++++
 setup.c               |  1 +
 5 files changed, 42 insertions(+)

diff --git a/refs.c b/refs.c
index 8b7a77fe5e..2457a31d4d 100644
--- a/refs.c
+++ b/refs.c
@@ -1651,12 +1651,22 @@ static struct ref_store *ref_store_init(const char *gitdir,
 	return refs;
 }
 
+static void ref_store_adjust_paths(const char *old_cwd,
+				   const char *new_cwd,
+				   void *cb)
+{
+	struct ref_store *refs = cb;
+
+	refs->be->adjust_paths(refs, old_cwd, new_cwd);
+}
+
 struct ref_store *get_main_ref_store(void)
 {
 	if (main_ref_store)
 		return main_ref_store;
 
 	main_ref_store = ref_store_init(get_git_dir(), REF_STORE_ALL_CAPS);
+	add_cwd_update_callback(ref_store_adjust_paths, main_ref_store);
 	return main_ref_store;
 }
 
diff --git a/refs/files-backend.c b/refs/files-backend.c
index bec8e30e9e..d35a8db844 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -3092,6 +3092,20 @@ static int files_reflog_expire(struct ref_store *ref_store,
 	return -1;
 }
 
+static void files_adjust_paths(struct ref_store *ref_store,
+			       const char *old_cwd,
+			       const char *new_cwd)
+{
+	struct files_ref_store *refs =
+		files_downcast(ref_store, REF_STORE_WRITE,
+			       "files_adjust_paths");
+
+	setup_adjust_path("ref store's gitdir",
+			  &refs->gitdir, old_cwd, new_cwd);
+	setup_adjust_path("ref store's commondir",
+			  &refs->gitcommondir, old_cwd, new_cwd);
+}
+
 static int files_init_db(struct ref_store *ref_store, struct strbuf *err)
 {
 	struct files_ref_store *refs =
@@ -3117,6 +3131,7 @@ struct ref_storage_be refs_be_files = {
 	"files",
 	files_ref_store_create,
 	files_init_db,
+	files_adjust_paths,
 	files_transaction_prepare,
 	files_transaction_finish,
 	files_transaction_abort,
diff --git a/refs/packed-backend.c b/refs/packed-backend.c
index 65288c6472..764d1250a5 100644
--- a/refs/packed-backend.c
+++ b/refs/packed-backend.c
@@ -1047,6 +1047,17 @@ int packed_refs_is_locked(struct ref_store *ref_store)
 	return is_lock_file_locked(&refs->lock);
 }
 
+static void packed_adjust_paths(struct ref_store *ref_store,
+				const char *old_cwd,
+				const char *new_cwd)
+{
+	struct packed_ref_store *refs =
+		packed_downcast(ref_store, REF_STORE_WRITE,
+				"packed_adjust_paths");
+
+	setup_adjust_path("packed-refs", &refs->path, old_cwd, new_cwd);
+}
+
 /*
  * The packed-refs header line that we write out. Perhaps other traits
  * will be added later.
@@ -1632,6 +1643,7 @@ struct ref_storage_be refs_be_packed = {
 	"packed",
 	packed_ref_store_create,
 	packed_init_db,
+	packed_adjust_paths,
 	packed_transaction_prepare,
 	packed_transaction_finish,
 	packed_transaction_abort,
diff --git a/refs/refs-internal.h b/refs/refs-internal.h
index dd834314bd..73480543c0 100644
--- a/refs/refs-internal.h
+++ b/refs/refs-internal.h
@@ -505,6 +505,9 @@ struct ref_store;
  */
 typedef struct ref_store *ref_store_init_fn(const char *gitdir,
 					    unsigned int flags);
+typedef void ref_store_adjust_paths_fn(struct ref_store *refs,
+				       const char *old_cwd,
+				       const char *new_cwd);
 
 typedef int ref_init_db_fn(struct ref_store *refs, struct strbuf *err);
 
@@ -625,6 +628,7 @@ struct ref_storage_be {
 	const char *name;
 	ref_store_init_fn *init;
 	ref_init_db_fn *init_db;
+	ref_store_adjust_paths_fn *adjust_paths;
 
 	ref_transaction_prepare_fn *transaction_prepare;
 	ref_transaction_finish_fn *transaction_finish;
diff --git a/setup.c b/setup.c
index e364aea7e5..35e89a03e5 100644
--- a/setup.c
+++ b/setup.c
@@ -3,6 +3,7 @@
 #include "config.h"
 #include "dir.h"
 #include "string-list.h"
+#include "refs.h"
 
 static int inside_git_dir = -1;
 static int inside_work_tree = -1;
-- 
2.17.0.rc1.439.gca064e2955