From: David Turner <dtur...@twopensource.com>

Alternate refs backends might not need the refs/heads directory and so
on, so we make ref db initialization part of the backend.

Signed-off-by: David Turner <dtur...@twopensource.com>
Signed-off-by: Junio C Hamano <gits...@pobox.com>
Signed-off-by: Michael Haggerty <mhag...@alum.mit.edu>
Signed-off-by: Junio C Hamano <gits...@pobox.com>
---
 builtin/init-db.c    | 21 +++++++++++----------
 refs.c               |  8 ++++++++
 refs.h               |  2 ++
 refs/files-backend.c | 18 ++++++++++++++++++
 refs/refs-internal.h |  3 +++
 5 files changed, 42 insertions(+), 10 deletions(-)

diff --git a/builtin/init-db.c b/builtin/init-db.c
index 3a45f0b..80192f6 100644
--- a/builtin/init-db.c
+++ b/builtin/init-db.c
@@ -180,13 +180,7 @@ static int create_default_files(const char *template_path)
        char junk[2];
        int reinit;
        int filemode;
-
-       /*
-        * Create .git/refs/{heads,tags}
-        */
-       safe_create_dir(git_path_buf(&buf, "refs"), 1);
-       safe_create_dir(git_path_buf(&buf, "refs/heads"), 1);
-       safe_create_dir(git_path_buf(&buf, "refs/tags"), 1);
+       struct strbuf err = STRBUF_INIT;
 
        /* Just look for `init.templatedir` */
        git_config(git_init_db_config, NULL);
@@ -210,12 +204,19 @@ static int create_default_files(const char *template_path)
         */
        if (get_shared_repository()) {
                adjust_shared_perm(get_git_dir());
-               adjust_shared_perm(git_path_buf(&buf, "refs"));
-               adjust_shared_perm(git_path_buf(&buf, "refs/heads"));
-               adjust_shared_perm(git_path_buf(&buf, "refs/tags"));
        }
 
        /*
+        * We need to create a "refs" dir in any case so that older
+        * versions of git can tell that this is a repository.
+        */
+       safe_create_dir(git_path("refs"), 1);
+       adjust_shared_perm(git_path("refs"));
+
+       if (refs_init_db(&err))
+               die("failed to set up refs db: %s", err.buf);
+
+       /*
         * Create the default symlink from ".git/HEAD" to the "master"
         * branch, if it does not exist yet.
         */
diff --git a/refs.c b/refs.c
index 6efa859..fcaf3ba 100644
--- a/refs.c
+++ b/refs.c
@@ -1292,6 +1292,14 @@ static const char *resolve_ref_recursively(struct 
ref_store *refs,
        return NULL;
 }
 
+/* backend functions */
+int refs_init_db(struct strbuf *err)
+{
+       struct ref_store *refs = get_ref_store(NULL);
+
+       return refs->be->init_db(refs, err);
+}
+
 const char *resolve_ref_unsafe(const char *refname, int resolve_flags,
                               unsigned char *sha1, int *flags)
 {
diff --git a/refs.h b/refs.h
index 17e8cfb..d42458c 100644
--- a/refs.h
+++ b/refs.h
@@ -66,6 +66,8 @@ int ref_exists(const char *refname);
 
 int is_branch(const char *refname);
 
+extern int refs_init_db(struct strbuf *err);
+
 /*
  * If refname is a non-symbolic reference that refers to a tag object,
  * and the tag can be (recursively) dereferenced to a non-tag object,
diff --git a/refs/files-backend.c b/refs/files-backend.c
index bcaa958..56397af 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -4068,10 +4068,28 @@ static int files_reflog_expire(struct ref_store 
*ref_store,
        return -1;
 }
 
+static int files_init_db(struct ref_store *ref_store, struct strbuf *err)
+{
+       /* Check validity (but we don't need the result): */
+       files_downcast(ref_store, 0, "init_db");
+
+       /*
+        * Create .git/refs/{heads,tags}
+        */
+       safe_create_dir(git_path("refs/heads"), 1);
+       safe_create_dir(git_path("refs/tags"), 1);
+       if (get_shared_repository()) {
+               adjust_shared_perm(git_path("refs/heads"));
+               adjust_shared_perm(git_path("refs/tags"));
+       }
+       return 0;
+}
+
 struct ref_storage_be refs_be_files = {
        NULL,
        "files",
        files_ref_store_create,
+       files_init_db,
        files_transaction_commit,
        files_initial_transaction_commit,
 
diff --git a/refs/refs-internal.h b/refs/refs-internal.h
index ade6501..b3a2095 100644
--- a/refs/refs-internal.h
+++ b/refs/refs-internal.h
@@ -479,6 +479,8 @@ struct ref_store;
  */
 typedef struct ref_store *ref_store_init_fn(const char *submodule);
 
+typedef int ref_init_db_fn(struct ref_store *refs, struct strbuf *err);
+
 typedef int ref_transaction_commit_fn(struct ref_store *refs,
                                      struct ref_transaction *transaction,
                                      struct strbuf *err);
@@ -583,6 +585,7 @@ struct ref_storage_be {
        struct ref_storage_be *next;
        const char *name;
        ref_store_init_fn *init;
+       ref_init_db_fn *init_db;
        ref_transaction_commit_fn *transaction_commit;
        ref_transaction_commit_fn *initial_transaction_commit;
 
-- 
2.9.3

Reply via email to