aboutsummaryrefslogtreecommitdiff
path: root/refs
diff options
context:
space:
mode:
Diffstat (limited to 'refs')
-rw-r--r--refs/files-backend.c17
-rw-r--r--refs/packed-backend.c5
-rw-r--r--refs/packed-backend.h1
-rw-r--r--refs/refs-internal.h14
-rw-r--r--refs/reftable-backend.c24
5 files changed, 46 insertions, 15 deletions
diff --git a/refs/files-backend.c b/refs/files-backend.c
index d3f6423261..9cde3ba724 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -106,19 +106,24 @@ static void clear_loose_ref_cache(struct files_ref_store *refs)
* set of caches.
*/
static struct ref_store *files_ref_store_init(struct repository *repo,
+ const char *payload,
const char *gitdir,
unsigned int flags)
{
struct files_ref_store *refs = xcalloc(1, sizeof(*refs));
struct ref_store *ref_store = (struct ref_store *)refs;
- struct strbuf sb = STRBUF_INIT;
+ struct strbuf ref_common_dir = STRBUF_INIT;
+ struct strbuf refdir = STRBUF_INIT;
+ bool is_worktree;
+
+ refs_compute_filesystem_location(gitdir, payload, &is_worktree, &refdir,
+ &ref_common_dir);
- base_ref_store_init(ref_store, repo, gitdir, &refs_be_files);
+ base_ref_store_init(ref_store, repo, refdir.buf, &refs_be_files);
refs->store_flags = flags;
- get_common_dir_noenv(&sb, gitdir);
- refs->gitcommondir = strbuf_detach(&sb, NULL);
+ refs->gitcommondir = strbuf_detach(&ref_common_dir, NULL);
refs->packed_ref_store =
- packed_ref_store_init(repo, refs->gitcommondir, flags);
+ packed_ref_store_init(repo, NULL, refs->gitcommondir, flags);
refs->log_all_ref_updates = repo_settings_get_log_all_ref_updates(repo);
repo_config_get_bool(repo, "core.prefersymlinkrefs", &refs->prefer_symlink_refs);
@@ -126,6 +131,8 @@ static struct ref_store *files_ref_store_init(struct repository *repo,
chdir_notify_reparent("files-backend $GIT_COMMONDIR",
&refs->gitcommondir);
+ strbuf_release(&refdir);
+
return ref_store;
}
diff --git a/refs/packed-backend.c b/refs/packed-backend.c
index 4ea0c12299..e7bb9f10f9 100644
--- a/refs/packed-backend.c
+++ b/refs/packed-backend.c
@@ -211,7 +211,12 @@ static size_t snapshot_hexsz(const struct snapshot *snapshot)
return snapshot->refs->base.repo->hash_algo->hexsz;
}
+/*
+ * Since packed-refs is only stored in the common dir, don't parse the
+ * payload and rely on the files-backend to set 'gitdir' correctly.
+ */
struct ref_store *packed_ref_store_init(struct repository *repo,
+ const char *payload UNUSED,
const char *gitdir,
unsigned int store_flags)
{
diff --git a/refs/packed-backend.h b/refs/packed-backend.h
index 9481d5e7c2..2c2377a356 100644
--- a/refs/packed-backend.h
+++ b/refs/packed-backend.h
@@ -14,6 +14,7 @@ struct ref_transaction;
*/
struct ref_store *packed_ref_store_init(struct repository *repo,
+ const char *payload,
const char *gitdir,
unsigned int store_flags);
diff --git a/refs/refs-internal.h b/refs/refs-internal.h
index c7d2a6e50b..4fb8fdb872 100644
--- a/refs/refs-internal.h
+++ b/refs/refs-internal.h
@@ -389,6 +389,7 @@ struct ref_store;
* the ref_store and to record the ref_store for later lookup.
*/
typedef struct ref_store *ref_store_init_fn(struct repository *repo,
+ const char *payload,
const char *gitdir,
unsigned int flags);
/*
@@ -666,4 +667,17 @@ enum ref_transaction_error refs_verify_refnames_available(struct ref_store *refs
unsigned int initial_transaction,
struct strbuf *err);
+/*
+ * Given a gitdir and the reference storage payload provided, retrieve the
+ * 'refdir' and 'ref_common_dir'. The former is where references should be
+ * stored for the current worktree, the latter is the common reference
+ * directory if working with a linked worktree. If working with the main
+ * worktree, both values will be the same.
+ *
+ * This is used by backends that store references in the repository directly.
+ */
+void refs_compute_filesystem_location(const char *gitdir, const char *payload,
+ bool *is_worktree, struct strbuf *refdir,
+ struct strbuf *ref_common_dir);
+
#endif /* REFS_REFS_INTERNAL_H */
diff --git a/refs/reftable-backend.c b/refs/reftable-backend.c
index 6ce7f9bb8e..0e220d6bb5 100644
--- a/refs/reftable-backend.c
+++ b/refs/reftable-backend.c
@@ -372,18 +372,24 @@ static int reftable_be_fsync(int fd)
}
static struct ref_store *reftable_be_init(struct repository *repo,
+ const char *payload,
const char *gitdir,
unsigned int store_flags)
{
struct reftable_ref_store *refs = xcalloc(1, sizeof(*refs));
+ struct strbuf ref_common_dir = STRBUF_INIT;
+ struct strbuf refdir = STRBUF_INIT;
struct strbuf path = STRBUF_INIT;
- int is_worktree;
+ bool is_worktree;
mode_t mask;
mask = umask(0);
umask(mask);
- base_ref_store_init(&refs->base, repo, gitdir, &refs_be_reftable);
+ refs_compute_filesystem_location(gitdir, payload, &is_worktree, &refdir,
+ &ref_common_dir);
+
+ base_ref_store_init(&refs->base, repo, refdir.buf, &refs_be_reftable);
strmap_init(&refs->worktree_backends);
refs->store_flags = store_flags;
refs->log_all_ref_updates = repo_settings_get_log_all_ref_updates(repo);
@@ -419,14 +425,11 @@ static struct ref_store *reftable_be_init(struct repository *repo,
/*
* Set up the main reftable stack that is hosted in GIT_COMMON_DIR.
* This stack contains both the shared and the main worktree refs.
- *
- * Note that we don't try to resolve the path in case we have a
- * worktree because `get_common_dir_noenv()` already does it for us.
*/
- is_worktree = get_common_dir_noenv(&path, gitdir);
+ strbuf_addbuf(&path, &ref_common_dir);
if (!is_worktree) {
strbuf_reset(&path);
- strbuf_realpath(&path, gitdir, 0);
+ strbuf_realpath(&path, ref_common_dir.buf, 0);
}
strbuf_addstr(&path, "/reftable");
refs->err = reftable_backend_init(&refs->main_backend, path.buf,
@@ -443,10 +446,9 @@ static struct ref_store *reftable_be_init(struct repository *repo,
* do it efficiently.
*/
if (is_worktree) {
- strbuf_reset(&path);
- strbuf_addf(&path, "%s/reftable", gitdir);
+ strbuf_addstr(&refdir, "/reftable");
- refs->err = reftable_backend_init(&refs->worktree_backend, path.buf,
+ refs->err = reftable_backend_init(&refs->worktree_backend, refdir.buf,
&refs->write_options);
if (refs->err)
goto done;
@@ -456,6 +458,8 @@ static struct ref_store *reftable_be_init(struct repository *repo,
done:
assert(refs->err != REFTABLE_API_ERROR);
+ strbuf_release(&ref_common_dir);
+ strbuf_release(&refdir);
strbuf_release(&path);
return &refs->base;
}