refs: add methods to init refs db

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 <dturner@twopensource.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>

David Turner committed Sep 4, 2016 at 18:08 UTC 6fb5acfd8f7102f53dedc887233313f233a65932
5 files changed +42 -10
builtin/init-db.c
+11 -10
@@ -180,13 +180,7 @@ static int create_default_files(const char *template_path)
180 char junk[2];
181 int reinit;
182 int filemode;
183 -
184 - /*
185 - * Create .git/refs/{heads,tags}
186 - */
187 - safe_create_dir(git_path_buf(&buf, "refs"), 1);
188 - safe_create_dir(git_path_buf(&buf, "refs/heads"), 1);
189 - safe_create_dir(git_path_buf(&buf, "refs/tags"), 1);
183 + struct strbuf err = STRBUF_INIT;
184
185 /* Just look for `init.templatedir` */
186 git_config(git_init_db_config, NULL);
@@ -210,11 +204,18 @@ static int create_default_files(const char *template_path)
204 */
205 if (get_shared_repository()) {
206 adjust_shared_perm(get_git_dir());
213 - adjust_shared_perm(git_path_buf(&buf, "refs"));
214 - adjust_shared_perm(git_path_buf(&buf, "refs/heads"));
215 - adjust_shared_perm(git_path_buf(&buf, "refs/tags"));
207 }
208
209 + /*
210 + * We need to create a "refs" dir in any case so that older
211 + * versions of git can tell that this is a repository.
212 + */
213 + safe_create_dir(git_path("refs"), 1);
214 + adjust_shared_perm(git_path("refs"));
215 +
216 + if (refs_init_db(&err))
217 + die("failed to set up refs db: %s", err.buf);
218 +
219 /*
220 * Create the default symlink from ".git/HEAD" to the "master"
221 * branch, if it does not exist yet.
refs.c
+8
@@ -1292,6 +1292,14 @@ static const char *resolve_ref_recursively(struct ref_store *refs,
1292 return NULL;
1293 }
1294
1295 +/* backend functions */
1296 +int refs_init_db(struct strbuf *err)
1297 +{
1298 + struct ref_store *refs = get_ref_store(NULL);
1299 +
1300 + return refs->be->init_db(refs, err);
1301 +}
1302 +
1303 const char *resolve_ref_unsafe(const char *refname, int resolve_flags,
1304 unsigned char *sha1, int *flags)
1305 {
refs.h
+2
@@ -66,6 +66,8 @@ int ref_exists(const char *refname);
66
67 int is_branch(const char *refname);
68
69 +extern int refs_init_db(struct strbuf *err);
70 +
71 /*
72 * If refname is a non-symbolic reference that refers to a tag object,
73 * and the tag can be (recursively) dereferenced to a non-tag object,
refs/files-backend.c
+18
@@ -4058,10 +4058,28 @@ static int files_reflog_expire(struct ref_store *ref_store,
4058 return -1;
4059 }
4060
4061 +static int files_init_db(struct ref_store *ref_store, struct strbuf *err)
4062 +{
4063 + /* Check validity (but we don't need the result): */
4064 + files_downcast(ref_store, 0, "init_db");
4065 +
4066 + /*
4067 + * Create .git/refs/{heads,tags}
4068 + */
4069 + safe_create_dir(git_path("refs/heads"), 1);
4070 + safe_create_dir(git_path("refs/tags"), 1);
4071 + if (get_shared_repository()) {
4072 + adjust_shared_perm(git_path("refs/heads"));
4073 + adjust_shared_perm(git_path("refs/tags"));
4074 + }
4075 + return 0;
4076 +}
4077 +
4078 struct ref_storage_be refs_be_files = {
4079 NULL,
4080 "files",
4081 files_ref_store_create,
4082 + files_init_db,
4083 files_transaction_commit,
4084 files_initial_transaction_commit,
4085
refs/refs-internal.h
+3
@@ -479,6 +479,8 @@ struct ref_store;
479 */
480 typedef struct ref_store *ref_store_init_fn(const char *submodule);
481
482 +typedef int ref_init_db_fn(struct ref_store *refs, struct strbuf *err);
483 +
484 typedef int ref_transaction_commit_fn(struct ref_store *refs,
485 struct ref_transaction *transaction,
486 struct strbuf *err);
@@ -583,6 +585,7 @@ struct ref_storage_be {
585 struct ref_storage_be *next;
586 const char *name;
587 ref_store_init_fn *init;
588 + ref_init_db_fn *init_db;
589 ref_transaction_commit_fn *transaction_commit;
590 ref_transaction_commit_fn *initial_transaction_commit;
591