files-backend: replace submodule_allowed check in files_downcast()

files-backend.c is unlearning submodules. Instead of having a specific check for submodules to see what operation is allowed, files backend now takes a set of flags at init. Each operation will check if the required flags is present before performing. For now we have four flags: read, write and odb access. Main ref store has all flags, obviously, while submodule stores are read-only and have access to odb (*). The "main" flag stays because many functions in the backend calls frontend ones without a ref store, so these functions always target the main ref store. Ideally the flag should be gone after ref-store-aware api is in place and used by backends. (*) Submodule code needs for_each_ref. Try take REF_STORE_ODB flag out. At least t3404 would fail. The "have access to odb" in submodule is a bit hacky since we don't know from he whether add_submodule_odb() has been called. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Nguyễn Thái Ngọc Duy committed Mar 26, 2017 at 09:42 UTC 9e7ec634a130535982e9bc63d65c2fe8c076a662
3 files changed +73 -37
refs.c
+11 -4
@@ -1416,7 +1416,8 @@ static struct ref_store *lookup_submodule_ref_store(const char *submodule)
1416 * Create, record, and return a ref_store instance for the specified
1417 * gitdir.
1418 */
1419 -static struct ref_store *ref_store_init(const char *gitdir)
1419 +static struct ref_store *ref_store_init(const char *gitdir,
1420 + unsigned int flags)
1421 {
1422 const char *be_name = "files";
1423 struct ref_storage_be *be = find_ref_storage_backend(be_name);
@@ -1425,7 +1426,7 @@ static struct ref_store *ref_store_init(const char *gitdir)
1426 if (!be)
1427 die("BUG: reference backend %s is unknown", be_name);
1428
1428 - refs = be->init(gitdir);
1429 + refs = be->init(gitdir, flags);
1430 return refs;
1431 }
1432
@@ -1434,7 +1435,11 @@ struct ref_store *get_main_ref_store(void)
1435 if (main_ref_store)
1436 return main_ref_store;
1437
1437 - main_ref_store = ref_store_init(get_git_dir());
1438 + main_ref_store = ref_store_init(get_git_dir(),
1439 + (REF_STORE_READ |
1440 + REF_STORE_WRITE |
1441 + REF_STORE_ODB |
1442 + REF_STORE_MAIN));
1443 return main_ref_store;
1444 }
1445
@@ -1481,7 +1486,9 @@ struct ref_store *get_ref_store(const char *submodule)
1486 return NULL;
1487 }
1488
1484 - refs = ref_store_init(submodule_sb.buf);
1489 + /* assume that add_submodule_odb() has been called */
1490 + refs = ref_store_init(submodule_sb.buf,
1491 + REF_STORE_READ | REF_STORE_ODB);
1492 register_submodule_ref_store(refs, submodule);
1493
1494 strbuf_release(&submodule_sb);
refs/files-backend.c
+54 -32
@@ -916,6 +916,7 @@ struct packed_ref_cache {
916 */
917 struct files_ref_store {
918 struct ref_store base;
919 + unsigned int store_flags;
920
921 char *gitdir;
922 char *gitcommondir;
@@ -976,13 +977,15 @@ static void clear_loose_ref_cache(struct files_ref_store *refs)
977 * Create a new submodule ref cache and add it to the internal
978 * set of caches.
979 */
979 -static struct ref_store *files_ref_store_create(const char *gitdir)
980 +static struct ref_store *files_ref_store_create(const char *gitdir,
981 + unsigned int flags)
982 {
983 struct files_ref_store *refs = xcalloc(1, sizeof(*refs));
984 struct ref_store *ref_store = (struct ref_store *)refs;
985 struct strbuf sb = STRBUF_INIT;
986
987 base_ref_store_init(ref_store, &refs_be_files);
988 + refs->store_flags = flags;
989
990 refs->gitdir = xstrdup(gitdir);
991 get_common_dir_noenv(&sb, gitdir);
@@ -994,24 +997,27 @@ static struct ref_store *files_ref_store_create(const char *gitdir)
997 }
998
999 /*
997 - * Die if refs is for a submodule (i.e., not for the main repository).
998 - * caller is used in any necessary error messages.
1000 + * Die if refs is not the main ref store. caller is used in any
1001 + * necessary error messages.
1002 */
1003 static void files_assert_main_repository(struct files_ref_store *refs,
1004 const char *caller)
1005 {
1003 - /* This function is to be fixed up in the next patch */
1006 + if (refs->store_flags & REF_STORE_MAIN)
1007 + return;
1008 +
1009 + die("BUG: operation %s only allowed for main ref store", caller);
1010 }
1011
1012 /*
1013 * Downcast ref_store to files_ref_store. Die if ref_store is not a
1008 - * files_ref_store. If submodule_allowed is not true, then also die if
1009 - * files_ref_store is for a submodule (i.e., not for the main
1010 - * repository). caller is used in any necessary error messages.
1014 + * files_ref_store. required_flags is compared with ref_store's
1015 + * store_flags to ensure the ref_store has all required capabilities.
1016 + * "caller" is used in any necessary error messages.
1017 */
1012 -static struct files_ref_store *files_downcast(
1013 - struct ref_store *ref_store, int submodule_allowed,
1014 - const char *caller)
1018 +static struct files_ref_store *files_downcast(struct ref_store *ref_store,
1019 + unsigned int required_flags,
1020 + const char *caller)
1021 {
1022 struct files_ref_store *refs;
1023
@@ -1021,8 +1027,9 @@ static struct files_ref_store *files_downcast(
1027
1028 refs = (struct files_ref_store *)ref_store;
1029
1024 - if (!submodule_allowed)
1025 - files_assert_main_repository(refs, caller);
1030 + if ((refs->store_flags & required_flags) != required_flags)
1031 + die("BUG: operation %s requires abilities 0x%x, but only have 0x%x",
1032 + caller, required_flags, refs->store_flags);
1033
1034 return refs;
1035 }
@@ -1398,7 +1405,7 @@ static int files_read_raw_ref(struct ref_store *ref_store,
1405 struct strbuf *referent, unsigned int *type)
1406 {
1407 struct files_ref_store *refs =
1401 - files_downcast(ref_store, 1, "read_raw_ref");
1408 + files_downcast(ref_store, REF_STORE_READ, "read_raw_ref");
1409 struct strbuf sb_contents = STRBUF_INIT;
1410 struct strbuf sb_path = STRBUF_INIT;
1411 const char *path;
@@ -1815,10 +1822,14 @@ static enum peel_status peel_entry(struct ref_entry *entry, int repeel)
1822 static int files_peel_ref(struct ref_store *ref_store,
1823 const char *refname, unsigned char *sha1)
1824 {
1818 - struct files_ref_store *refs = files_downcast(ref_store, 0, "peel_ref");
1825 + struct files_ref_store *refs =
1826 + files_downcast(ref_store, REF_STORE_READ | REF_STORE_ODB,
1827 + "peel_ref");
1828 int flag;
1829 unsigned char base[20];
1830
1831 + files_assert_main_repository(refs, "peel_ref");
1832 +
1833 if (current_ref_iter && current_ref_iter->refname == refname) {
1834 struct object_id peeled;
1835
@@ -1923,8 +1934,7 @@ static struct ref_iterator *files_ref_iterator_begin(
1934 struct ref_store *ref_store,
1935 const char *prefix, unsigned int flags)
1936 {
1926 - struct files_ref_store *refs =
1927 - files_downcast(ref_store, 1, "ref_iterator_begin");
1937 + struct files_ref_store *refs;
1938 struct ref_dir *loose_dir, *packed_dir;
1939 struct ref_iterator *loose_iter, *packed_iter;
1940 struct files_ref_iterator *iter;
@@ -1935,6 +1945,10 @@ static struct ref_iterator *files_ref_iterator_begin(
1945 if (ref_paranoia)
1946 flags |= DO_FOR_EACH_INCLUDE_BROKEN;
1947
1948 + refs = files_downcast(ref_store,
1949 + REF_STORE_READ | (ref_paranoia ? 0 : REF_STORE_ODB),
1950 + "ref_iterator_begin");
1951 +
1952 iter = xcalloc(1, sizeof(*iter));
1953 ref_iterator = &iter->base;
1954 base_ref_iterator_init(ref_iterator, &files_ref_iterator_vtable);
@@ -2415,7 +2429,8 @@ static void prune_refs(struct ref_to_prune *r)
2429 static int files_pack_refs(struct ref_store *ref_store, unsigned int flags)
2430 {
2431 struct files_ref_store *refs =
2418 - files_downcast(ref_store, 0, "pack_refs");
2432 + files_downcast(ref_store, REF_STORE_WRITE | REF_STORE_ODB,
2433 + "pack_refs");
2434 struct pack_refs_cb_data cbdata;
2435
2436 memset(&cbdata, 0, sizeof(cbdata));
@@ -2494,7 +2509,7 @@ static int files_delete_refs(struct ref_store *ref_store,
2509 struct string_list *refnames, unsigned int flags)
2510 {
2511 struct files_ref_store *refs =
2497 - files_downcast(ref_store, 0, "delete_refs");
2512 + files_downcast(ref_store, REF_STORE_WRITE, "delete_refs");
2513 struct strbuf err = STRBUF_INIT;
2514 int i, result = 0;
2515
@@ -2598,7 +2613,7 @@ static int files_verify_refname_available(struct ref_store *ref_store,
2613 struct strbuf *err)
2614 {
2615 struct files_ref_store *refs =
2601 - files_downcast(ref_store, 1, "verify_refname_available");
2616 + files_downcast(ref_store, REF_STORE_READ, "verify_refname_available");
2617 struct ref_dir *packed_refs = get_packed_refs(refs);
2618 struct ref_dir *loose_refs = get_loose_refs(refs);
2619
@@ -2623,7 +2638,7 @@ static int files_rename_ref(struct ref_store *ref_store,
2638 const char *logmsg)
2639 {
2640 struct files_ref_store *refs =
2626 - files_downcast(ref_store, 0, "rename_ref");
2641 + files_downcast(ref_store, REF_STORE_WRITE, "rename_ref");
2642 unsigned char sha1[20], orig_sha1[20];
2643 int flag = 0, logmoved = 0;
2644 struct ref_lock *lock;
@@ -2873,7 +2888,7 @@ static int files_create_reflog(struct ref_store *ref_store,
2888 struct strbuf *err)
2889 {
2890 struct files_ref_store *refs =
2876 - files_downcast(ref_store, 0, "create_reflog");
2891 + files_downcast(ref_store, REF_STORE_WRITE, "create_reflog");
2892 int fd;
2893
2894 if (log_ref_setup(refs, refname, force_create, &fd, err))
@@ -3117,7 +3132,7 @@ static int files_create_symref(struct ref_store *ref_store,
3132 const char *logmsg)
3133 {
3134 struct files_ref_store *refs =
3120 - files_downcast(ref_store, 0, "create_symref");
3135 + files_downcast(ref_store, REF_STORE_WRITE, "create_symref");
3136 struct strbuf err = STRBUF_INIT;
3137 struct ref_lock *lock;
3138 int ret;
@@ -3143,7 +3158,9 @@ int set_worktree_head_symref(const char *gitdir, const char *target, const char
3158 * backends. This function needs to die.
3159 */
3160 struct files_ref_store *refs =
3146 - files_downcast(get_main_ref_store(), 0, "set_head_symref");
3161 + files_downcast(get_main_ref_store(),
3162 + REF_STORE_WRITE,
3163 + "set_head_symref");
3164
3165 static struct lock_file head_lock;
3166 struct ref_lock *lock;
@@ -3182,7 +3199,7 @@ static int files_reflog_exists(struct ref_store *ref_store,
3199 const char *refname)
3200 {
3201 struct files_ref_store *refs =
3185 - files_downcast(ref_store, 0, "reflog_exists");
3202 + files_downcast(ref_store, REF_STORE_READ, "reflog_exists");
3203 struct strbuf sb = STRBUF_INIT;
3204 struct stat st;
3205 int ret;
@@ -3197,7 +3214,7 @@ static int files_delete_reflog(struct ref_store *ref_store,
3214 const char *refname)
3215 {
3216 struct files_ref_store *refs =
3200 - files_downcast(ref_store, 0, "delete_reflog");
3217 + files_downcast(ref_store, REF_STORE_WRITE, "delete_reflog");
3218 struct strbuf sb = STRBUF_INIT;
3219 int ret;
3220
@@ -3253,7 +3270,8 @@ static int files_for_each_reflog_ent_reverse(struct ref_store *ref_store,
3270 void *cb_data)
3271 {
3272 struct files_ref_store *refs =
3256 - files_downcast(ref_store, 0, "for_each_reflog_ent_reverse");
3273 + files_downcast(ref_store, REF_STORE_READ,
3274 + "for_each_reflog_ent_reverse");
3275 struct strbuf sb = STRBUF_INIT;
3276 FILE *logfp;
3277 long pos;
@@ -3361,7 +3379,8 @@ static int files_for_each_reflog_ent(struct ref_store *ref_store,
3379 each_reflog_ent_fn fn, void *cb_data)
3380 {
3381 struct files_ref_store *refs =
3364 - files_downcast(ref_store, 0, "for_each_reflog_ent");
3382 + files_downcast(ref_store, REF_STORE_READ,
3383 + "for_each_reflog_ent");
3384 FILE *logfp;
3385 struct strbuf sb = STRBUF_INIT;
3386 int ret = 0;
@@ -3449,7 +3468,8 @@ static struct ref_iterator_vtable files_reflog_iterator_vtable = {
3468 static struct ref_iterator *files_reflog_iterator_begin(struct ref_store *ref_store)
3469 {
3470 struct files_ref_store *refs =
3452 - files_downcast(ref_store, 0, "reflog_iterator_begin");
3471 + files_downcast(ref_store, REF_STORE_READ,
3472 + "reflog_iterator_begin");
3473 struct files_reflog_iterator *iter = xcalloc(1, sizeof(*iter));
3474 struct ref_iterator *ref_iterator = &iter->base;
3475 struct strbuf sb = STRBUF_INIT;
@@ -3787,7 +3807,8 @@ static int files_transaction_commit(struct ref_store *ref_store,
3807 struct strbuf *err)
3808 {
3809 struct files_ref_store *refs =
3790 - files_downcast(ref_store, 0, "ref_transaction_commit");
3810 + files_downcast(ref_store, REF_STORE_WRITE,
3811 + "ref_transaction_commit");
3812 int ret = 0, i;
3813 struct string_list refs_to_delete = STRING_LIST_INIT_NODUP;
3814 struct string_list_item *ref_to_delete;
@@ -3992,7 +4013,8 @@ static int files_initial_transaction_commit(struct ref_store *ref_store,
4013 struct strbuf *err)
4014 {
4015 struct files_ref_store *refs =
3995 - files_downcast(ref_store, 0, "initial_ref_transaction_commit");
4016 + files_downcast(ref_store, REF_STORE_WRITE,
4017 + "initial_ref_transaction_commit");
4018 int ret = 0, i;
4019 struct string_list affected_refnames = STRING_LIST_INIT_NODUP;
4020
@@ -4114,7 +4136,7 @@ static int files_reflog_expire(struct ref_store *ref_store,
4136 void *policy_cb_data)
4137 {
4138 struct files_ref_store *refs =
4117 - files_downcast(ref_store, 0, "reflog_expire");
4139 + files_downcast(ref_store, REF_STORE_WRITE, "reflog_expire");
4140 static struct lock_file reflog_lock;
4141 struct expire_reflog_cb cb;
4142 struct ref_lock *lock;
@@ -4220,7 +4242,7 @@ static int files_reflog_expire(struct ref_store *ref_store,
4242 static int files_init_db(struct ref_store *ref_store, struct strbuf *err)
4243 {
4244 struct files_ref_store *refs =
4223 - files_downcast(ref_store, 0, "init_db");
4245 + files_downcast(ref_store, REF_STORE_WRITE, "init_db");
4246 struct strbuf sb = STRBUF_INIT;
4247
4248 /*
refs/refs-internal.h
+8 -1
@@ -481,12 +481,19 @@ struct ref_store;
481
482 /* refs backends */
483
484 +/* ref_store_init flags */
485 +#define REF_STORE_READ (1 << 0)
486 +#define REF_STORE_WRITE (1 << 1) /* can perform update operations */
487 +#define REF_STORE_ODB (1 << 2) /* has access to object database */
488 +#define REF_STORE_MAIN (1 << 3)
489 +
490 /*
491 * Initialize the ref_store for the specified gitdir. These functions
492 * should call base_ref_store_init() to initialize the shared part of
493 * the ref_store and to record the ref_store for later lookup.
494 */
489 -typedef struct ref_store *ref_store_init_fn(const char *gitdir);
495 +typedef struct ref_store *ref_store_init_fn(const char *gitdir,
496 + unsigned int flags);
497
498 typedef int ref_init_db_fn(struct ref_store *refs, struct strbuf *err);
499