From f6e75467ca83f116e96525c33d9b669e47f310fd Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Sun, 4 Sep 2016 18:08:07 +0200 Subject: resolve_gitlink_ref(): eliminate temporary variable Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- refs/files-backend.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'refs/files-backend.c') diff --git a/refs/files-backend.c b/refs/files-backend.c index a9ca003bae..d56fc15163 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -1387,7 +1387,7 @@ static int resolve_gitlink_ref_recursive(struct ref_cache *refs, int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *sha1) { - int len = strlen(path), retval; + int len = strlen(path); struct strbuf submodule = STRBUF_INIT; struct ref_cache *refs; @@ -1404,8 +1404,7 @@ int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *sh } strbuf_release(&submodule); - retval = resolve_gitlink_ref_recursive(refs, refname, sha1, 0); - return retval; + return resolve_gitlink_ref_recursive(refs, refname, sha1, 0); } /* -- cgit v1.2.1 From 65a0a8e5facb42f41561a96af209016954878b63 Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Sun, 4 Sep 2016 18:08:09 +0200 Subject: refs: rename struct ref_cache to files_ref_store The greater goal of this patch series is to develop the concept of a reference store, which is a place that references, their values, and their reflogs are stored, and to virtualize the reference interface so that different types of ref_stores can be implemented. We will then, for example, use ref_store instances to access submodule references and worktree references. Currently, we keep a ref_cache for each submodule that has had its references iterated over. It is a far cry from a ref_store, but they are stored the way we will want to store ref_stores, and ref_stores will eventually have to hold the reference caches. So let's treat ref_caches as embryo ref_stores, and build them out from there. As the first step, simply rename `ref_cache` to `files_ref_store`, and rename some functions and attributes correspondingly. Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- refs/files-backend.c | 126 +++++++++++++++++++++++++-------------------------- 1 file changed, 63 insertions(+), 63 deletions(-) (limited to 'refs/files-backend.c') diff --git a/refs/files-backend.c b/refs/files-backend.c index d56fc15163..c229b56bd5 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -39,7 +39,7 @@ struct ref_value { struct object_id peeled; }; -struct ref_cache; +struct files_ref_store; /* * Information used (along with the information in ref_entry) to @@ -78,8 +78,8 @@ struct ref_dir { */ int sorted; - /* A pointer to the ref_cache that contains this ref_dir. */ - struct ref_cache *ref_cache; + /* A pointer to the files_ref_store that contains this ref_dir. */ + struct files_ref_store *ref_store; struct ref_entry **entries; }; @@ -161,7 +161,7 @@ struct ref_entry { static void read_loose_refs(const char *dirname, struct ref_dir *dir); static int search_ref_dir(struct ref_dir *dir, const char *refname, size_t len); -static struct ref_entry *create_dir_entry(struct ref_cache *ref_cache, +static struct ref_entry *create_dir_entry(struct files_ref_store *ref_store, const char *dirname, size_t len, int incomplete); static void add_entry_to_dir(struct ref_dir *dir, struct ref_entry *entry); @@ -183,7 +183,7 @@ static struct ref_dir *get_ref_dir(struct ref_entry *entry) int pos = search_ref_dir(dir, "refs/bisect/", 12); if (pos < 0) { struct ref_entry *child_entry; - child_entry = create_dir_entry(dir->ref_cache, + child_entry = create_dir_entry(dir->ref_store, "refs/bisect/", 12, 1); add_entry_to_dir(dir, child_entry); @@ -261,13 +261,13 @@ static void clear_ref_dir(struct ref_dir *dir) * dirname is the name of the directory with a trailing slash (e.g., * "refs/heads/") or "" for the top-level directory. */ -static struct ref_entry *create_dir_entry(struct ref_cache *ref_cache, +static struct ref_entry *create_dir_entry(struct files_ref_store *ref_store, const char *dirname, size_t len, int incomplete) { struct ref_entry *direntry; FLEX_ALLOC_MEM(direntry, name, dirname, len); - direntry->u.subdir.ref_cache = ref_cache; + direntry->u.subdir.ref_store = ref_store; direntry->flag = REF_DIR | (incomplete ? REF_INCOMPLETE : 0); return direntry; } @@ -343,7 +343,7 @@ static struct ref_dir *search_for_subdir(struct ref_dir *dir, * therefore, create an empty record for it but mark * the record complete. */ - entry = create_dir_entry(dir->ref_cache, subdirname, len, 0); + entry = create_dir_entry(dir->ref_store, subdirname, len, 0); add_entry_to_dir(dir, entry); } else { entry = dir->entries[entry_index]; @@ -887,9 +887,9 @@ struct packed_ref_cache { /* * Count of references to the data structure in this instance, - * including the pointer from ref_cache::packed if any. The - * data will not be freed as long as the reference count is - * nonzero. + * including the pointer from files_ref_store::packed if any. + * The data will not be freed as long as the reference count + * is nonzero. */ unsigned int referrers; @@ -910,17 +910,17 @@ struct packed_ref_cache { * Future: need to be in "struct repository" * when doing a full libification. */ -static struct ref_cache { - struct ref_cache *next; +static struct files_ref_store { + struct files_ref_store *next; struct ref_entry *loose; struct packed_ref_cache *packed; /* - * The submodule name, or "" for the main repo. We allocate - * length 1 rather than FLEX_ARRAY so that the main ref_cache - * is initialized correctly. + * The submodule name, or "" for the main repo. We allocate + * length 1 rather than FLEX_ARRAY so that the main + * files_ref_store is initialized correctly. */ char name[1]; -} ref_cache, *submodule_ref_caches; +} ref_store, *submodule_ref_stores; /* Lock used for the main packed-refs file: */ static struct lock_file packlock; @@ -949,7 +949,7 @@ static int release_packed_ref_cache(struct packed_ref_cache *packed_refs) } } -static void clear_packed_ref_cache(struct ref_cache *refs) +static void clear_packed_ref_cache(struct files_ref_store *refs) { if (refs->packed) { struct packed_ref_cache *packed_refs = refs->packed; @@ -961,7 +961,7 @@ static void clear_packed_ref_cache(struct ref_cache *refs) } } -static void clear_loose_ref_cache(struct ref_cache *refs) +static void clear_loose_ref_cache(struct files_ref_store *refs) { if (refs->loose) { free_ref_entry(refs->loose); @@ -973,32 +973,32 @@ static void clear_loose_ref_cache(struct ref_cache *refs) * Create a new submodule ref cache and add it to the internal * set of caches. */ -static struct ref_cache *create_ref_cache(const char *submodule) +static struct files_ref_store *create_ref_store(const char *submodule) { - struct ref_cache *refs; + struct files_ref_store *refs; if (!submodule) submodule = ""; FLEX_ALLOC_STR(refs, name, submodule); - refs->next = submodule_ref_caches; - submodule_ref_caches = refs; + refs->next = submodule_ref_stores; + submodule_ref_stores = refs; return refs; } -static struct ref_cache *lookup_ref_cache(const char *submodule) +static struct files_ref_store *lookup_ref_store(const char *submodule) { - struct ref_cache *refs; + struct files_ref_store *refs; if (!submodule || !*submodule) - return &ref_cache; + return &ref_store; - for (refs = submodule_ref_caches; refs; refs = refs->next) + for (refs = submodule_ref_stores; refs; refs = refs->next) if (!strcmp(submodule, refs->name)) return refs; return NULL; } /* - * Return a pointer to a ref_cache for the specified submodule. For + * Return a pointer to a files_ref_store for the specified submodule. For * the main repository, use submodule==NULL; such a call cannot fail. * For a submodule, the submodule must exist and be a nonbare * repository, otherwise return NULL. @@ -1006,16 +1006,16 @@ static struct ref_cache *lookup_ref_cache(const char *submodule) * The returned structure will be allocated and initialized but not * necessarily populated; it should not be freed. */ -static struct ref_cache *get_ref_cache(const char *submodule) +static struct files_ref_store *get_ref_store(const char *submodule) { - struct ref_cache *refs = lookup_ref_cache(submodule); + struct files_ref_store *refs = lookup_ref_store(submodule); if (!refs) { struct strbuf submodule_sb = STRBUF_INIT; strbuf_addstr(&submodule_sb, submodule); if (is_nonbare_repository_dir(&submodule_sb)) - refs = create_ref_cache(submodule); + refs = create_ref_store(submodule); strbuf_release(&submodule_sb); } @@ -1151,10 +1151,10 @@ static void read_packed_refs(FILE *f, struct ref_dir *dir) } /* - * Get the packed_ref_cache for the specified ref_cache, creating it - * if necessary. + * Get the packed_ref_cache for the specified files_ref_store, + * creating it if necessary. */ -static struct packed_ref_cache *get_packed_ref_cache(struct ref_cache *refs) +static struct packed_ref_cache *get_packed_ref_cache(struct files_ref_store *refs) { char *packed_refs_file; @@ -1189,7 +1189,7 @@ static struct ref_dir *get_packed_ref_dir(struct packed_ref_cache *packed_ref_ca return get_ref_dir(packed_ref_cache->root); } -static struct ref_dir *get_packed_refs(struct ref_cache *refs) +static struct ref_dir *get_packed_refs(struct files_ref_store *refs) { return get_packed_ref_dir(get_packed_ref_cache(refs)); } @@ -1203,7 +1203,7 @@ static struct ref_dir *get_packed_refs(struct ref_cache *refs) static void add_packed_ref(const char *refname, const unsigned char *sha1) { struct packed_ref_cache *packed_ref_cache = - get_packed_ref_cache(&ref_cache); + get_packed_ref_cache(&ref_store); if (!packed_ref_cache->lock) die("internal error: packed refs not locked"); @@ -1218,7 +1218,7 @@ static void add_packed_ref(const char *refname, const unsigned char *sha1) */ static void read_loose_refs(const char *dirname, struct ref_dir *dir) { - struct ref_cache *refs = dir->ref_cache; + struct files_ref_store *refs = dir->ref_store; DIR *d; struct dirent *de; int dirnamelen = strlen(dirname); @@ -1306,7 +1306,7 @@ static void read_loose_refs(const char *dirname, struct ref_dir *dir) closedir(d); } -static struct ref_dir *get_loose_refs(struct ref_cache *refs) +static struct ref_dir *get_loose_refs(struct files_ref_store *refs) { if (!refs->loose) { /* @@ -1328,10 +1328,10 @@ static struct ref_dir *get_loose_refs(struct ref_cache *refs) /* * Called by resolve_gitlink_ref_recursive() after it failed to read - * from the loose refs in ref_cache refs. Find in the - * packed-refs file for the submodule. + * from the loose refs in refs. Find in the packed-refs file + * for the submodule. */ -static int resolve_gitlink_packed_ref(struct ref_cache *refs, +static int resolve_gitlink_packed_ref(struct files_ref_store *refs, const char *refname, unsigned char *sha1) { struct ref_entry *ref; @@ -1345,7 +1345,7 @@ static int resolve_gitlink_packed_ref(struct ref_cache *refs, return 0; } -static int resolve_gitlink_ref_recursive(struct ref_cache *refs, +static int resolve_gitlink_ref_recursive(struct files_ref_store *refs, const char *refname, unsigned char *sha1, int recursion) { @@ -1389,7 +1389,7 @@ int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *sh { int len = strlen(path); struct strbuf submodule = STRBUF_INIT; - struct ref_cache *refs; + struct files_ref_store *refs; while (len && path[len-1] == '/') len--; @@ -1397,7 +1397,7 @@ int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *sh return -1; strbuf_add(&submodule, path, len); - refs = get_ref_cache(submodule.buf); + refs = get_ref_store(submodule.buf); if (!refs) { strbuf_release(&submodule); return -1; @@ -1413,7 +1413,7 @@ int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *sh */ static struct ref_entry *get_packed_ref(const char *refname) { - return find_ref(get_packed_refs(&ref_cache), refname); + return find_ref(get_packed_refs(&ref_store), refname); } /* @@ -1745,7 +1745,7 @@ retry: REMOVE_DIR_EMPTY_ONLY)) { if (verify_refname_available_dir( refname, extras, skip, - get_loose_refs(&ref_cache), + get_loose_refs(&ref_store), err)) { /* * The error message set by @@ -1784,7 +1784,7 @@ retry: */ if (verify_refname_available_dir( refname, extras, skip, - get_packed_refs(&ref_cache), + get_packed_refs(&ref_store), err)) { goto error_return; } @@ -1942,7 +1942,7 @@ struct ref_iterator *files_ref_iterator_begin( const char *submodule, const char *prefix, unsigned int flags) { - struct ref_cache *refs = get_ref_cache(submodule); + struct files_ref_store *refs = get_ref_store(submodule); struct ref_dir *loose_dir, *packed_dir; struct ref_iterator *loose_iter, *packed_iter; struct files_ref_iterator *iter; @@ -2096,7 +2096,7 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname, if (remove_empty_directories(&ref_file)) { last_errno = errno; if (!verify_refname_available_dir(refname, extras, skip, - get_loose_refs(&ref_cache), err)) + get_loose_refs(&ref_store), err)) strbuf_addf(err, "there are still refs under '%s'", refname); goto error_return; @@ -2108,7 +2108,7 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname, last_errno = errno; if (last_errno != ENOTDIR || !verify_refname_available_dir(refname, extras, skip, - get_loose_refs(&ref_cache), err)) + get_loose_refs(&ref_store), err)) strbuf_addf(err, "unable to resolve reference '%s': %s", refname, strerror(last_errno)); @@ -2123,7 +2123,7 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname, */ if (is_null_oid(&lock->old_oid) && verify_refname_available_dir(refname, extras, skip, - get_packed_refs(&ref_cache), err)) { + get_packed_refs(&ref_store), err)) { last_errno = ENOTDIR; goto error_return; } @@ -2232,7 +2232,7 @@ static int lock_packed_refs(int flags) * this will automatically invalidate the cache and re-read * the packed-refs file. */ - packed_ref_cache = get_packed_ref_cache(&ref_cache); + packed_ref_cache = get_packed_ref_cache(&ref_store); packed_ref_cache->lock = &packlock; /* Increment the reference count to prevent it from being freed: */ acquire_packed_ref_cache(packed_ref_cache); @@ -2248,7 +2248,7 @@ static int lock_packed_refs(int flags) static int commit_packed_refs(void) { struct packed_ref_cache *packed_ref_cache = - get_packed_ref_cache(&ref_cache); + get_packed_ref_cache(&ref_store); int error = 0; int save_errno = 0; FILE *out; @@ -2282,14 +2282,14 @@ static int commit_packed_refs(void) static void rollback_packed_refs(void) { struct packed_ref_cache *packed_ref_cache = - get_packed_ref_cache(&ref_cache); + get_packed_ref_cache(&ref_store); if (!packed_ref_cache->lock) die("internal error: packed-refs not locked"); rollback_lock_file(packed_ref_cache->lock); packed_ref_cache->lock = NULL; release_packed_ref_cache(packed_ref_cache); - clear_packed_ref_cache(&ref_cache); + clear_packed_ref_cache(&ref_store); } struct ref_to_prune { @@ -2428,9 +2428,9 @@ int pack_refs(unsigned int flags) cbdata.flags = flags; lock_packed_refs(LOCK_DIE_ON_ERROR); - cbdata.packed_refs = get_packed_refs(&ref_cache); + cbdata.packed_refs = get_packed_refs(&ref_store); - do_for_each_entry_in_dir(get_loose_refs(&ref_cache), 0, + do_for_each_entry_in_dir(get_loose_refs(&ref_store), 0, pack_if_possible_fn, &cbdata); if (commit_packed_refs()) @@ -2471,7 +2471,7 @@ static int repack_without_refs(struct string_list *refnames, struct strbuf *err) unable_to_lock_message(git_path("packed-refs"), errno, err); return -1; } - packed = get_packed_refs(&ref_cache); + packed = get_packed_refs(&ref_store); /* Remove refnames from the cache */ for_each_string_list_item(refname, refnames) @@ -2616,8 +2616,8 @@ int verify_refname_available(const char *newname, const struct string_list *skip, struct strbuf *err) { - struct ref_dir *packed_refs = get_packed_refs(&ref_cache); - struct ref_dir *loose_refs = get_loose_refs(&ref_cache); + struct ref_dir *packed_refs = get_packed_refs(&ref_store); + struct ref_dir *loose_refs = get_loose_refs(&ref_store); if (verify_refname_available_dir(newname, extras, skip, packed_refs, err) || @@ -2968,7 +2968,7 @@ static int commit_ref_update(struct ref_lock *lock, const unsigned char *sha1, const char *logmsg, struct strbuf *err) { - clear_loose_ref_cache(&ref_cache); + clear_loose_ref_cache(&ref_store); if (log_ref_write(lock->ref_name, lock->old_oid.hash, sha1, logmsg, 0, err)) { char *old_msg = strbuf_detach(err, NULL); strbuf_addf(err, "cannot update the ref '%s': %s", @@ -3790,7 +3790,7 @@ int ref_transaction_commit(struct ref_transaction *transaction, } } if (update->flags & REF_NEEDS_COMMIT) { - clear_loose_ref_cache(&ref_cache); + clear_loose_ref_cache(&ref_store); if (commit_ref(lock)) { strbuf_addf(err, "couldn't set '%s'", lock->ref_name); unlock_ref(lock); @@ -3823,7 +3823,7 @@ int ref_transaction_commit(struct ref_transaction *transaction, } for_each_string_list_item(ref_to_delete, &refs_to_delete) unlink_or_warn(git_path("logs/%s", ref_to_delete->string)); - clear_loose_ref_cache(&ref_cache); + clear_loose_ref_cache(&ref_store); cleanup: transaction->state = REF_TRANSACTION_CLOSED; -- cgit v1.2.1 From 3dce444f178503bf3da13ade6f79c80d6964d175 Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Sun, 4 Sep 2016 18:08:10 +0200 Subject: refs: add a backend method structure Add a `struct ref_storage_be` to represent types of reference stores. In OO notation, this is the class, and will soon hold some class methods (e.g., a factory to create new ref_store instances) and will also serve as the vtable for ref_store instances of that type. As yet, the backends cannot do anything. Signed-off-by: Ronnie Sahlberg Signed-off-by: David Turner Signed-off-by: Junio C Hamano Signed-off-by: Jeff King Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- refs/files-backend.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'refs/files-backend.c') diff --git a/refs/files-backend.c b/refs/files-backend.c index c229b56bd5..0102491b13 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -4066,3 +4066,8 @@ int reflog_expire(const char *refname, const unsigned char *sha1, unlock_ref(lock); return -1; } + +struct ref_storage_be refs_be_files = { + NULL, + "files" +}; -- cgit v1.2.1 From 00eebe351c4b4626a7b8e0b2dc4b7a172f3fd8d9 Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Sun, 4 Sep 2016 18:08:11 +0200 Subject: refs: create a base class "ref_store" for files_ref_store We want ref_stores to be polymorphic, so invent a base class of which files_ref_store is a derived class. For now there is exactly one ref_store for the main repository and one for any submodules whose references have been accessed. Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- refs/files-backend.c | 177 ++++++++++++++++++++++++++++----------------------- 1 file changed, 99 insertions(+), 78 deletions(-) (limited to 'refs/files-backend.c') diff --git a/refs/files-backend.c b/refs/files-backend.c index 0102491b13..c31f9b6f3a 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -910,17 +910,11 @@ struct packed_ref_cache { * Future: need to be in "struct repository" * when doing a full libification. */ -static struct files_ref_store { - struct files_ref_store *next; +struct files_ref_store { + struct ref_store base; struct ref_entry *loose; struct packed_ref_cache *packed; - /* - * The submodule name, or "" for the main repo. We allocate - * length 1 rather than FLEX_ARRAY so that the main - * files_ref_store is initialized correctly. - */ - char name[1]; -} ref_store, *submodule_ref_stores; +}; /* Lock used for the main packed-refs file: */ static struct lock_file packlock; @@ -973,53 +967,50 @@ static void clear_loose_ref_cache(struct files_ref_store *refs) * Create a new submodule ref cache and add it to the internal * set of caches. */ -static struct files_ref_store *create_ref_store(const char *submodule) +static struct ref_store *files_ref_store_create(const char *submodule) { - struct files_ref_store *refs; - if (!submodule) - submodule = ""; - FLEX_ALLOC_STR(refs, name, submodule); - refs->next = submodule_ref_stores; - submodule_ref_stores = refs; - return refs; + struct files_ref_store *refs = xcalloc(1, sizeof(*refs)); + struct ref_store *ref_store = (struct ref_store *)refs; + + base_ref_store_init(ref_store, &refs_be_files, submodule); + + return ref_store; } -static struct files_ref_store *lookup_ref_store(const char *submodule) +/* + * Downcast ref_store to files_ref_store. Die if ref_store is not a + * files_ref_store. If submodule_allowed is not true, then also die if + * files_ref_store is for a submodule (i.e., not for the main + * repository). caller is used in any necessary error messages. + */ +static struct files_ref_store *files_downcast( + struct ref_store *ref_store, int submodule_allowed, + const char *caller) { - struct files_ref_store *refs; + if (ref_store->be != &refs_be_files) + die("BUG: ref_store is type \"%s\" not \"files\" in %s", + ref_store->be->name, caller); - if (!submodule || !*submodule) - return &ref_store; + if (!submodule_allowed) + assert_main_repository(ref_store, caller); - for (refs = submodule_ref_stores; refs; refs = refs->next) - if (!strcmp(submodule, refs->name)) - return refs; - return NULL; + return (struct files_ref_store *)ref_store; } /* - * Return a pointer to a files_ref_store for the specified submodule. For - * the main repository, use submodule==NULL; such a call cannot fail. - * For a submodule, the submodule must exist and be a nonbare - * repository, otherwise return NULL. - * - * The returned structure will be allocated and initialized but not - * necessarily populated; it should not be freed. + * Return a pointer to the reference store for the specified + * submodule. For the main repository, use submodule==NULL; such a + * call cannot fail. For a submodule, the submodule must exist and be + * a nonbare repository, otherwise return NULL. Verify that the + * reference store is a files_ref_store, and cast it to that type + * before returning it. */ -static struct files_ref_store *get_ref_store(const char *submodule) +static struct files_ref_store *get_files_ref_store(const char *submodule, + const char *caller) { - struct files_ref_store *refs = lookup_ref_store(submodule); + struct ref_store *refs = get_ref_store(submodule); - if (!refs) { - struct strbuf submodule_sb = STRBUF_INIT; - - strbuf_addstr(&submodule_sb, submodule); - if (is_nonbare_repository_dir(&submodule_sb)) - refs = create_ref_store(submodule); - strbuf_release(&submodule_sb); - } - - return refs; + return refs ? files_downcast(refs, 1, caller) : NULL; } /* The length of a peeled reference line in packed-refs, including EOL: */ @@ -1158,8 +1149,9 @@ static struct packed_ref_cache *get_packed_ref_cache(struct files_ref_store *ref { char *packed_refs_file; - if (*refs->name) - packed_refs_file = git_pathdup_submodule(refs->name, "packed-refs"); + if (*refs->base.submodule) + packed_refs_file = git_pathdup_submodule(refs->base.submodule, + "packed-refs"); else packed_refs_file = git_pathdup("packed-refs"); @@ -1202,8 +1194,9 @@ static struct ref_dir *get_packed_refs(struct files_ref_store *refs) */ static void add_packed_ref(const char *refname, const unsigned char *sha1) { - struct packed_ref_cache *packed_ref_cache = - get_packed_ref_cache(&ref_store); + struct files_ref_store *refs = + get_files_ref_store(NULL, "add_packed_ref"); + struct packed_ref_cache *packed_ref_cache = get_packed_ref_cache(refs); if (!packed_ref_cache->lock) die("internal error: packed refs not locked"); @@ -1226,8 +1219,8 @@ static void read_loose_refs(const char *dirname, struct ref_dir *dir) struct strbuf path = STRBUF_INIT; size_t path_baselen; - if (*refs->name) - strbuf_git_path_submodule(&path, refs->name, "%s", dirname); + if (*refs->base.submodule) + strbuf_git_path_submodule(&path, refs->base.submodule, "%s", dirname); else strbuf_git_path(&path, "%s", dirname); path_baselen = path.len; @@ -1262,10 +1255,10 @@ static void read_loose_refs(const char *dirname, struct ref_dir *dir) } else { int read_ok; - if (*refs->name) { + if (*refs->base.submodule) { hashclr(sha1); flag = 0; - read_ok = !resolve_gitlink_ref(refs->name, + read_ok = !resolve_gitlink_ref(refs->base.submodule, refname.buf, sha1); } else { read_ok = !read_ref_full(refname.buf, @@ -1355,8 +1348,8 @@ static int resolve_gitlink_ref_recursive(struct files_ref_store *refs, if (recursion > SYMREF_MAXDEPTH || strlen(refname) > MAXREFLEN) return -1; - path = *refs->name - ? git_pathdup_submodule(refs->name, "%s", refname) + path = *refs->base.submodule + ? git_pathdup_submodule(refs->base.submodule, "%s", refname) : git_pathdup("%s", refname); fd = open(path, O_RDONLY); free(path); @@ -1397,7 +1390,7 @@ int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *sh return -1; strbuf_add(&submodule, path, len); - refs = get_ref_store(submodule.buf); + refs = get_files_ref_store(submodule.buf, "resolve_gitlink_ref"); if (!refs) { strbuf_release(&submodule); return -1; @@ -1413,7 +1406,10 @@ int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *sh */ static struct ref_entry *get_packed_ref(const char *refname) { - return find_ref(get_packed_refs(&ref_store), refname); + struct files_ref_store *refs = + get_files_ref_store(NULL, "get_packed_ref"); + + return find_ref(get_packed_refs(refs), refname); } /* @@ -1613,6 +1609,8 @@ static int lock_raw_ref(const char *refname, int mustexist, unsigned int *type, struct strbuf *err) { + struct files_ref_store *refs = + get_files_ref_store(NULL, "lock_raw_ref"); struct ref_lock *lock; struct strbuf ref_file = STRBUF_INIT; int attempts_remaining = 3; @@ -1745,7 +1743,7 @@ retry: REMOVE_DIR_EMPTY_ONLY)) { if (verify_refname_available_dir( refname, extras, skip, - get_loose_refs(&ref_store), + get_loose_refs(refs), err)) { /* * The error message set by @@ -1784,7 +1782,7 @@ retry: */ if (verify_refname_available_dir( refname, extras, skip, - get_packed_refs(&ref_store), + get_packed_refs(refs), err)) { goto error_return; } @@ -1942,7 +1940,8 @@ struct ref_iterator *files_ref_iterator_begin( const char *submodule, const char *prefix, unsigned int flags) { - struct files_ref_store *refs = get_ref_store(submodule); + struct files_ref_store *refs = + get_files_ref_store(submodule, "ref_iterator_begin"); struct ref_dir *loose_dir, *packed_dir; struct ref_iterator *loose_iter, *packed_iter; struct files_ref_iterator *iter; @@ -2065,6 +2064,8 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname, unsigned int flags, int *type, struct strbuf *err) { + struct files_ref_store *refs = + get_files_ref_store(NULL, "lock_ref_sha1_basic"); struct strbuf ref_file = STRBUF_INIT; struct ref_lock *lock; int last_errno = 0; @@ -2095,8 +2096,9 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname, */ if (remove_empty_directories(&ref_file)) { last_errno = errno; - if (!verify_refname_available_dir(refname, extras, skip, - get_loose_refs(&ref_store), err)) + if (!verify_refname_available_dir( + refname, extras, skip, + get_loose_refs(refs), err)) strbuf_addf(err, "there are still refs under '%s'", refname); goto error_return; @@ -2107,8 +2109,9 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname, if (!resolved) { last_errno = errno; if (last_errno != ENOTDIR || - !verify_refname_available_dir(refname, extras, skip, - get_loose_refs(&ref_store), err)) + !verify_refname_available_dir( + refname, extras, skip, + get_loose_refs(refs), err)) strbuf_addf(err, "unable to resolve reference '%s': %s", refname, strerror(last_errno)); @@ -2123,7 +2126,8 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname, */ if (is_null_oid(&lock->old_oid) && verify_refname_available_dir(refname, extras, skip, - get_packed_refs(&ref_store), err)) { + get_packed_refs(refs), + err)) { last_errno = ENOTDIR; goto error_return; } @@ -2212,9 +2216,10 @@ static int write_packed_entry_fn(struct ref_entry *entry, void *cb_data) */ static int lock_packed_refs(int flags) { + struct files_ref_store *refs = + get_files_ref_store(NULL, "lock_packed_refs"); static int timeout_configured = 0; static int timeout_value = 1000; - struct packed_ref_cache *packed_ref_cache; if (!timeout_configured) { @@ -2232,7 +2237,7 @@ static int lock_packed_refs(int flags) * this will automatically invalidate the cache and re-read * the packed-refs file. */ - packed_ref_cache = get_packed_ref_cache(&ref_store); + packed_ref_cache = get_packed_ref_cache(refs); packed_ref_cache->lock = &packlock; /* Increment the reference count to prevent it from being freed: */ acquire_packed_ref_cache(packed_ref_cache); @@ -2247,8 +2252,10 @@ static int lock_packed_refs(int flags) */ static int commit_packed_refs(void) { + struct files_ref_store *refs = + get_files_ref_store(NULL, "commit_packed_refs"); struct packed_ref_cache *packed_ref_cache = - get_packed_ref_cache(&ref_store); + get_packed_ref_cache(refs); int error = 0; int save_errno = 0; FILE *out; @@ -2281,15 +2288,17 @@ static int commit_packed_refs(void) */ static void rollback_packed_refs(void) { + struct files_ref_store *refs = + get_files_ref_store(NULL, "rollback_packed_refs"); struct packed_ref_cache *packed_ref_cache = - get_packed_ref_cache(&ref_store); + get_packed_ref_cache(refs); if (!packed_ref_cache->lock) die("internal error: packed-refs not locked"); rollback_lock_file(packed_ref_cache->lock); packed_ref_cache->lock = NULL; release_packed_ref_cache(packed_ref_cache); - clear_packed_ref_cache(&ref_store); + clear_packed_ref_cache(refs); } struct ref_to_prune { @@ -2422,15 +2431,17 @@ static void prune_refs(struct ref_to_prune *r) int pack_refs(unsigned int flags) { + struct files_ref_store *refs = + get_files_ref_store(NULL, "pack_refs"); struct pack_refs_cb_data cbdata; memset(&cbdata, 0, sizeof(cbdata)); cbdata.flags = flags; lock_packed_refs(LOCK_DIE_ON_ERROR); - cbdata.packed_refs = get_packed_refs(&ref_store); + cbdata.packed_refs = get_packed_refs(refs); - do_for_each_entry_in_dir(get_loose_refs(&ref_store), 0, + do_for_each_entry_in_dir(get_loose_refs(refs), 0, pack_if_possible_fn, &cbdata); if (commit_packed_refs()) @@ -2449,6 +2460,8 @@ int pack_refs(unsigned int flags) */ static int repack_without_refs(struct string_list *refnames, struct strbuf *err) { + struct files_ref_store *refs = + get_files_ref_store(NULL, "repack_without_refs"); struct ref_dir *packed; struct string_list_item *refname; int ret, needs_repacking = 0, removed = 0; @@ -2471,7 +2484,7 @@ static int repack_without_refs(struct string_list *refnames, struct strbuf *err) unable_to_lock_message(git_path("packed-refs"), errno, err); return -1; } - packed = get_packed_refs(&ref_store); + packed = get_packed_refs(refs); /* Remove refnames from the cache */ for_each_string_list_item(refname, refnames) @@ -2616,8 +2629,10 @@ int verify_refname_available(const char *newname, const struct string_list *skip, struct strbuf *err) { - struct ref_dir *packed_refs = get_packed_refs(&ref_store); - struct ref_dir *loose_refs = get_loose_refs(&ref_store); + struct files_ref_store *refs = + get_files_ref_store(NULL, "verify_refname_available"); + struct ref_dir *packed_refs = get_packed_refs(refs); + struct ref_dir *loose_refs = get_loose_refs(refs); if (verify_refname_available_dir(newname, extras, skip, packed_refs, err) || @@ -2968,7 +2983,10 @@ static int commit_ref_update(struct ref_lock *lock, const unsigned char *sha1, const char *logmsg, struct strbuf *err) { - clear_loose_ref_cache(&ref_store); + struct files_ref_store *refs = + get_files_ref_store(NULL, "commit_ref_update"); + + clear_loose_ref_cache(refs); if (log_ref_write(lock->ref_name, lock->old_oid.hash, sha1, logmsg, 0, err)) { char *old_msg = strbuf_detach(err, NULL); strbuf_addf(err, "cannot update the ref '%s': %s", @@ -3684,6 +3702,8 @@ static int lock_ref_for_update(struct ref_update *update, int ref_transaction_commit(struct ref_transaction *transaction, struct strbuf *err) { + struct files_ref_store *refs = + get_files_ref_store(NULL, "ref_transaction_commit"); int ret = 0, i; struct string_list refs_to_delete = STRING_LIST_INIT_NODUP; struct string_list_item *ref_to_delete; @@ -3790,7 +3810,7 @@ int ref_transaction_commit(struct ref_transaction *transaction, } } if (update->flags & REF_NEEDS_COMMIT) { - clear_loose_ref_cache(&ref_store); + clear_loose_ref_cache(refs); if (commit_ref(lock)) { strbuf_addf(err, "couldn't set '%s'", lock->ref_name); unlock_ref(lock); @@ -3823,7 +3843,7 @@ int ref_transaction_commit(struct ref_transaction *transaction, } for_each_string_list_item(ref_to_delete, &refs_to_delete) unlink_or_warn(git_path("logs/%s", ref_to_delete->string)); - clear_loose_ref_cache(&ref_store); + clear_loose_ref_cache(refs); cleanup: transaction->state = REF_TRANSACTION_CLOSED; @@ -4069,5 +4089,6 @@ int reflog_expire(const char *refname, const unsigned char *sha1, struct ref_storage_be refs_be_files = { NULL, - "files" + "files", + files_ref_store_create }; -- cgit v1.2.1 From d99825ab73bbe2ae21e3056ffc1b594800a87cd7 Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Sun, 4 Sep 2016 18:08:12 +0200 Subject: add_packed_ref(): add a files_ref_store argument Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- refs/files-backend.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'refs/files-backend.c') diff --git a/refs/files-backend.c b/refs/files-backend.c index c31f9b6f3a..08340755d7 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -1192,10 +1192,9 @@ static struct ref_dir *get_packed_refs(struct files_ref_store *refs) * lock_packed_refs()). To actually write the packed-refs file, call * commit_packed_refs(). */ -static void add_packed_ref(const char *refname, const unsigned char *sha1) +static void add_packed_ref(struct files_ref_store *refs, + const char *refname, const unsigned char *sha1) { - struct files_ref_store *refs = - get_files_ref_store(NULL, "add_packed_ref"); struct packed_ref_cache *packed_ref_cache = get_packed_ref_cache(refs); if (!packed_ref_cache->lock) @@ -3869,6 +3868,8 @@ static int ref_present(const char *refname, int initial_ref_transaction_commit(struct ref_transaction *transaction, struct strbuf *err) { + struct files_ref_store *refs = + get_files_ref_store(NULL, "initial_ref_transaction_commit"); int ret = 0, i; struct string_list affected_refnames = STRING_LIST_INIT_NODUP; @@ -3928,7 +3929,7 @@ int initial_ref_transaction_commit(struct ref_transaction *transaction, if ((update->flags & REF_HAVE_NEW) && !is_null_sha1(update->new_sha1)) - add_packed_ref(update->refname, update->new_sha1); + add_packed_ref(refs, update->refname, update->new_sha1); } if (commit_packed_refs()) { -- cgit v1.2.1 From f0d21efc3536b369e4a95d78628c19a941381be3 Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Sun, 4 Sep 2016 18:08:13 +0200 Subject: get_packed_ref(): add a files_ref_store argument Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- refs/files-backend.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'refs/files-backend.c') diff --git a/refs/files-backend.c b/refs/files-backend.c index 08340755d7..16d5b9f14b 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -1403,11 +1403,9 @@ int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *sh * Return the ref_entry for the given refname from the packed * references. If it does not exist, return NULL. */ -static struct ref_entry *get_packed_ref(const char *refname) +static struct ref_entry *get_packed_ref(struct files_ref_store *refs, + const char *refname) { - struct files_ref_store *refs = - get_files_ref_store(NULL, "get_packed_ref"); - return find_ref(get_packed_refs(refs), refname); } @@ -1418,13 +1416,16 @@ static int resolve_missing_loose_ref(const char *refname, unsigned char *sha1, unsigned int *flags) { + struct files_ref_store *refs = + get_files_ref_store(NULL, "resolve_missing_loose_ref"); + struct ref_entry *entry; /* * The loose reference file does not exist; check for a packed * reference. */ - entry = get_packed_ref(refname); + entry = get_packed_ref(refs, refname); if (entry) { hashcpy(sha1, entry->u.value.oid.hash); *flags |= REF_ISPACKED; @@ -1836,6 +1837,7 @@ static enum peel_status peel_entry(struct ref_entry *entry, int repeel) int peel_ref(const char *refname, unsigned char *sha1) { + struct files_ref_store *refs = get_files_ref_store(NULL, "peel_ref"); int flag; unsigned char base[20]; @@ -1860,7 +1862,7 @@ int peel_ref(const char *refname, unsigned char *sha1) * have REF_KNOWS_PEELED. */ if (flag & REF_ISPACKED) { - struct ref_entry *r = get_packed_ref(refname); + struct ref_entry *r = get_packed_ref(refs, refname); if (r) { if (peel_entry(r, 0)) return -1; @@ -2469,7 +2471,7 @@ static int repack_without_refs(struct string_list *refnames, struct strbuf *err) /* Look for a packed ref */ for_each_string_list_item(refname, refnames) { - if (get_packed_ref(refname->string)) { + if (get_packed_ref(refs, refname->string)) { needs_repacking = 1; break; } -- cgit v1.2.1 From 4308651c3cbef316d070e3dbbbf5e53d56a56548 Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Sun, 4 Sep 2016 18:08:14 +0200 Subject: resolve_missing_loose_ref(): add a files_ref_store argument Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- refs/files-backend.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'refs/files-backend.c') diff --git a/refs/files-backend.c b/refs/files-backend.c index 16d5b9f14b..9c81af900c 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -1412,13 +1412,11 @@ static struct ref_entry *get_packed_ref(struct files_ref_store *refs, /* * A loose ref file doesn't exist; check for a packed ref. */ -static int resolve_missing_loose_ref(const char *refname, +static int resolve_missing_loose_ref(struct files_ref_store *refs, + const char *refname, unsigned char *sha1, unsigned int *flags) { - struct files_ref_store *refs = - get_files_ref_store(NULL, "resolve_missing_loose_ref"); - struct ref_entry *entry; /* @@ -1438,6 +1436,8 @@ static int resolve_missing_loose_ref(const char *refname, int read_raw_ref(const char *refname, unsigned char *sha1, struct strbuf *referent, unsigned int *type) { + struct files_ref_store *refs = + get_files_ref_store(NULL, "read_raw_ref"); struct strbuf sb_contents = STRBUF_INIT; struct strbuf sb_path = STRBUF_INIT; const char *path; @@ -1466,7 +1466,7 @@ stat_ref: if (lstat(path, &st) < 0) { if (errno != ENOENT) goto out; - if (resolve_missing_loose_ref(refname, sha1, type)) { + if (resolve_missing_loose_ref(refs, refname, sha1, type)) { errno = ENOENT; goto out; } @@ -1500,7 +1500,7 @@ stat_ref: * ref is supposed to be, there could still be a * packed ref: */ - if (resolve_missing_loose_ref(refname, sha1, type)) { + if (resolve_missing_loose_ref(refs, refname, sha1, type)) { errno = EISDIR; goto out; } -- cgit v1.2.1 From 49c0df6a68c6c02a75e306c34e4e9d2bfa645892 Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Sun, 4 Sep 2016 18:08:15 +0200 Subject: {lock,commit,rollback}_packed_refs(): add files_ref_store arguments These functions currently only work in the main repository, so add an assert_main_repository() check to each function. Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- refs/files-backend.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'refs/files-backend.c') diff --git a/refs/files-backend.c b/refs/files-backend.c index 9c81af900c..17404413cc 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -2215,14 +2215,14 @@ static int write_packed_entry_fn(struct ref_entry *entry, void *cb_data) * hold_lock_file_for_update(). Return 0 on success. On errors, set * errno appropriately and return a nonzero value. */ -static int lock_packed_refs(int flags) +static int lock_packed_refs(struct files_ref_store *refs, int flags) { - struct files_ref_store *refs = - get_files_ref_store(NULL, "lock_packed_refs"); static int timeout_configured = 0; static int timeout_value = 1000; struct packed_ref_cache *packed_ref_cache; + assert_main_repository(&refs->base, "lock_packed_refs"); + if (!timeout_configured) { git_config_get_int("core.packedrefstimeout", &timeout_value); timeout_configured = 1; @@ -2251,16 +2251,16 @@ static int lock_packed_refs(int flags) * lock_packed_refs()). Return zero on success. On errors, set errno * and return a nonzero value */ -static int commit_packed_refs(void) +static int commit_packed_refs(struct files_ref_store *refs) { - struct files_ref_store *refs = - get_files_ref_store(NULL, "commit_packed_refs"); struct packed_ref_cache *packed_ref_cache = get_packed_ref_cache(refs); int error = 0; int save_errno = 0; FILE *out; + assert_main_repository(&refs->base, "commit_packed_refs"); + if (!packed_ref_cache->lock) die("internal error: packed-refs not locked"); @@ -2287,13 +2287,13 @@ static int commit_packed_refs(void) * in-memory packed reference cache. (The packed-refs file will be * read anew if it is needed again after this function is called.) */ -static void rollback_packed_refs(void) +static void rollback_packed_refs(struct files_ref_store *refs) { - struct files_ref_store *refs = - get_files_ref_store(NULL, "rollback_packed_refs"); struct packed_ref_cache *packed_ref_cache = get_packed_ref_cache(refs); + assert_main_repository(&refs->base, "rollback_packed_refs"); + if (!packed_ref_cache->lock) die("internal error: packed-refs not locked"); rollback_lock_file(packed_ref_cache->lock); @@ -2439,13 +2439,13 @@ int pack_refs(unsigned int flags) memset(&cbdata, 0, sizeof(cbdata)); cbdata.flags = flags; - lock_packed_refs(LOCK_DIE_ON_ERROR); + lock_packed_refs(refs, LOCK_DIE_ON_ERROR); cbdata.packed_refs = get_packed_refs(refs); do_for_each_entry_in_dir(get_loose_refs(refs), 0, pack_if_possible_fn, &cbdata); - if (commit_packed_refs()) + if (commit_packed_refs(refs)) die_errno("unable to overwrite old ref-pack file"); prune_refs(cbdata.ref_to_prune); @@ -2481,7 +2481,7 @@ static int repack_without_refs(struct string_list *refnames, struct strbuf *err) if (!needs_repacking) return 0; /* no refname exists in packed refs */ - if (lock_packed_refs(0)) { + if (lock_packed_refs(refs, 0)) { unable_to_lock_message(git_path("packed-refs"), errno, err); return -1; } @@ -2496,12 +2496,12 @@ static int repack_without_refs(struct string_list *refnames, struct strbuf *err) * All packed entries disappeared while we were * acquiring the lock. */ - rollback_packed_refs(); + rollback_packed_refs(refs); return 0; } /* Write what remains */ - ret = commit_packed_refs(); + ret = commit_packed_refs(refs); if (ret) strbuf_addf(err, "unable to overwrite old ref-pack file: %s", strerror(errno)); @@ -3919,7 +3919,7 @@ int initial_ref_transaction_commit(struct ref_transaction *transaction, } } - if (lock_packed_refs(0)) { + if (lock_packed_refs(refs, 0)) { strbuf_addf(err, "unable to lock packed-refs file: %s", strerror(errno)); ret = TRANSACTION_GENERIC_ERROR; @@ -3934,7 +3934,7 @@ int initial_ref_transaction_commit(struct ref_transaction *transaction, add_packed_ref(refs, update->refname, update->new_sha1); } - if (commit_packed_refs()) { + if (commit_packed_refs(refs)) { strbuf_addf(err, "unable to commit packed-refs file: %s", strerror(errno)); ret = TRANSACTION_GENERIC_ERROR; -- cgit v1.2.1 From 127b42a18618538438b811a29cd95e79c646eb70 Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Sun, 4 Sep 2016 18:08:16 +0200 Subject: refs: add a transaction_commit() method Signed-off-by: Ronnie Sahlberg Signed-off-by: David Turner Signed-off-by: Junio C Hamano Signed-off-by: Jeff King Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- refs/files-backend.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'refs/files-backend.c') diff --git a/refs/files-backend.c b/refs/files-backend.c index 17404413cc..2d847f57e4 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -3700,11 +3700,12 @@ static int lock_ref_for_update(struct ref_update *update, return 0; } -int ref_transaction_commit(struct ref_transaction *transaction, - struct strbuf *err) +static int files_transaction_commit(struct ref_store *ref_store, + struct ref_transaction *transaction, + struct strbuf *err) { struct files_ref_store *refs = - get_files_ref_store(NULL, "ref_transaction_commit"); + files_downcast(ref_store, 0, "ref_transaction_commit"); int ret = 0, i; struct string_list refs_to_delete = STRING_LIST_INIT_NODUP; struct string_list_item *ref_to_delete; @@ -4093,5 +4094,6 @@ int reflog_expire(const char *refname, const unsigned char *sha1, struct ref_storage_be refs_be_files = { NULL, "files", - files_ref_store_create + files_ref_store_create, + files_transaction_commit }; -- cgit v1.2.1 From 6356c658e424dbd45b278f164b0c36a2062a1bcb Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Sun, 4 Sep 2016 18:08:17 +0200 Subject: refs: reorder definitions Move resolve_gitlink_ref() and related functions lower in the file to avoid the need for forward declarations in the next step. Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- refs/files-backend.c | 166 +++++++++++++++++++++++++-------------------------- 1 file changed, 83 insertions(+), 83 deletions(-) (limited to 'refs/files-backend.c') diff --git a/refs/files-backend.c b/refs/files-backend.c index 2d847f57e4..748e5cb076 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -1316,89 +1316,6 @@ static struct ref_dir *get_loose_refs(struct files_ref_store *refs) return get_ref_dir(refs->loose); } -#define MAXREFLEN (1024) - -/* - * Called by resolve_gitlink_ref_recursive() after it failed to read - * from the loose refs in refs. Find in the packed-refs file - * for the submodule. - */ -static int resolve_gitlink_packed_ref(struct files_ref_store *refs, - const char *refname, unsigned char *sha1) -{ - struct ref_entry *ref; - struct ref_dir *dir = get_packed_refs(refs); - - ref = find_ref(dir, refname); - if (ref == NULL) - return -1; - - hashcpy(sha1, ref->u.value.oid.hash); - return 0; -} - -static int resolve_gitlink_ref_recursive(struct files_ref_store *refs, - const char *refname, unsigned char *sha1, - int recursion) -{ - int fd, len; - char buffer[128], *p; - char *path; - - if (recursion > SYMREF_MAXDEPTH || strlen(refname) > MAXREFLEN) - return -1; - path = *refs->base.submodule - ? git_pathdup_submodule(refs->base.submodule, "%s", refname) - : git_pathdup("%s", refname); - fd = open(path, O_RDONLY); - free(path); - if (fd < 0) - return resolve_gitlink_packed_ref(refs, refname, sha1); - - len = read(fd, buffer, sizeof(buffer)-1); - close(fd); - if (len < 0) - return -1; - while (len && isspace(buffer[len-1])) - len--; - buffer[len] = 0; - - /* Was it a detached head or an old-fashioned symlink? */ - if (!get_sha1_hex(buffer, sha1)) - return 0; - - /* Symref? */ - if (strncmp(buffer, "ref:", 4)) - return -1; - p = buffer + 4; - while (isspace(*p)) - p++; - - return resolve_gitlink_ref_recursive(refs, p, sha1, recursion+1); -} - -int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *sha1) -{ - int len = strlen(path); - struct strbuf submodule = STRBUF_INIT; - struct files_ref_store *refs; - - while (len && path[len-1] == '/') - len--; - if (!len) - return -1; - - strbuf_add(&submodule, path, len); - refs = get_files_ref_store(submodule.buf, "resolve_gitlink_ref"); - if (!refs) { - strbuf_release(&submodule); - return -1; - } - strbuf_release(&submodule); - - return resolve_gitlink_ref_recursive(refs, refname, sha1, 0); -} - /* * Return the ref_entry for the given refname from the packed * references. If it does not exist, return NULL. @@ -1572,6 +1489,89 @@ static void unlock_ref(struct ref_lock *lock) free(lock); } +#define MAXREFLEN (1024) + +/* + * Called by resolve_gitlink_ref_recursive() after it failed to read + * from the loose refs in refs. Find in the packed-refs file + * for the submodule. + */ +static int resolve_gitlink_packed_ref(struct files_ref_store *refs, + const char *refname, unsigned char *sha1) +{ + struct ref_entry *ref; + struct ref_dir *dir = get_packed_refs(refs); + + ref = find_ref(dir, refname); + if (ref == NULL) + return -1; + + hashcpy(sha1, ref->u.value.oid.hash); + return 0; +} + +static int resolve_gitlink_ref_recursive(struct files_ref_store *refs, + const char *refname, unsigned char *sha1, + int recursion) +{ + int fd, len; + char buffer[128], *p; + char *path; + + if (recursion > SYMREF_MAXDEPTH || strlen(refname) > MAXREFLEN) + return -1; + path = *refs->base.submodule + ? git_pathdup_submodule(refs->base.submodule, "%s", refname) + : git_pathdup("%s", refname); + fd = open(path, O_RDONLY); + free(path); + if (fd < 0) + return resolve_gitlink_packed_ref(refs, refname, sha1); + + len = read(fd, buffer, sizeof(buffer)-1); + close(fd); + if (len < 0) + return -1; + while (len && isspace(buffer[len-1])) + len--; + buffer[len] = 0; + + /* Was it a detached head or an old-fashioned symlink? */ + if (!get_sha1_hex(buffer, sha1)) + return 0; + + /* Symref? */ + if (strncmp(buffer, "ref:", 4)) + return -1; + p = buffer + 4; + while (isspace(*p)) + p++; + + return resolve_gitlink_ref_recursive(refs, p, sha1, recursion+1); +} + +int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *sha1) +{ + int len = strlen(path); + struct strbuf submodule = STRBUF_INIT; + struct files_ref_store *refs; + + while (len && path[len-1] == '/') + len--; + if (!len) + return -1; + + strbuf_add(&submodule, path, len); + refs = get_files_ref_store(submodule.buf, "resolve_gitlink_ref"); + if (!refs) { + strbuf_release(&submodule); + return -1; + } + strbuf_release(&submodule); + + return resolve_gitlink_ref_recursive(refs, refname, sha1, 0); +} + /* * Lock refname, without following symrefs, and set *lock_p to point * at a newly-allocated lock object. Fill in lock->old_oid, referent, -- cgit v1.2.1 From 611118d06ebba572424fa39473869eee1a1238fb Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Sun, 4 Sep 2016 18:08:18 +0200 Subject: resolve_packed_ref(): rename function from resolve_missing_loose_ref() Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- refs/files-backend.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'refs/files-backend.c') diff --git a/refs/files-backend.c b/refs/files-backend.c index 748e5cb076..924bdda193 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -1329,10 +1329,9 @@ static struct ref_entry *get_packed_ref(struct files_ref_store *refs, /* * A loose ref file doesn't exist; check for a packed ref. */ -static int resolve_missing_loose_ref(struct files_ref_store *refs, - const char *refname, - unsigned char *sha1, - unsigned int *flags) +static int resolve_packed_ref(struct files_ref_store *refs, + const char *refname, + unsigned char *sha1, unsigned int *flags) { struct ref_entry *entry; @@ -1383,7 +1382,7 @@ stat_ref: if (lstat(path, &st) < 0) { if (errno != ENOENT) goto out; - if (resolve_missing_loose_ref(refs, refname, sha1, type)) { + if (resolve_packed_ref(refs, refname, sha1, type)) { errno = ENOENT; goto out; } @@ -1417,7 +1416,7 @@ stat_ref: * ref is supposed to be, there could still be a * packed ref: */ - if (resolve_missing_loose_ref(refs, refname, sha1, type)) { + if (resolve_packed_ref(refs, refname, sha1, type)) { errno = EISDIR; goto out; } -- cgit v1.2.1 From b9180c9d5d13366e228130eb0d2f1451f2e4dfd6 Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Sun, 4 Sep 2016 18:08:19 +0200 Subject: resolve_gitlink_packed_ref(): remove function Now that resolve_packed_ref() can work with an arbitrary files_ref_store, there is no need to have a separate resolve_gitlink_packed_ref() function. Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- refs/files-backend.c | 26 +++++--------------------- 1 file changed, 5 insertions(+), 21 deletions(-) (limited to 'refs/files-backend.c') diff --git a/refs/files-backend.c b/refs/files-backend.c index 924bdda193..5a76f893e1 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -1490,25 +1490,6 @@ static void unlock_ref(struct ref_lock *lock) #define MAXREFLEN (1024) -/* - * Called by resolve_gitlink_ref_recursive() after it failed to read - * from the loose refs in refs. Find in the packed-refs file - * for the submodule. - */ -static int resolve_gitlink_packed_ref(struct files_ref_store *refs, - const char *refname, unsigned char *sha1) -{ - struct ref_entry *ref; - struct ref_dir *dir = get_packed_refs(refs); - - ref = find_ref(dir, refname); - if (ref == NULL) - return -1; - - hashcpy(sha1, ref->u.value.oid.hash); - return 0; -} - static int resolve_gitlink_ref_recursive(struct files_ref_store *refs, const char *refname, unsigned char *sha1, int recursion) @@ -1524,8 +1505,11 @@ static int resolve_gitlink_ref_recursive(struct files_ref_store *refs, : git_pathdup("%s", refname); fd = open(path, O_RDONLY); free(path); - if (fd < 0) - return resolve_gitlink_packed_ref(refs, refname, sha1); + if (fd < 0) { + unsigned int flags; + + return resolve_packed_ref(refs, refname, sha1, &flags); + } len = read(fd, buffer, sizeof(buffer)-1); close(fd); -- cgit v1.2.1 From 34c7ad8ffc79c64d7f2261e6bcf6efd3adb16e7e Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Sun, 4 Sep 2016 18:08:20 +0200 Subject: read_raw_ref(): take a (struct ref_store *) argument And make the function work for submodules. Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- refs/files-backend.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'refs/files-backend.c') diff --git a/refs/files-backend.c b/refs/files-backend.c index 5a76f893e1..a743da4c1e 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -1349,11 +1349,12 @@ static int resolve_packed_ref(struct files_ref_store *refs, return -1; } -int read_raw_ref(const char *refname, unsigned char *sha1, +int read_raw_ref(struct ref_store *ref_store, + const char *refname, unsigned char *sha1, struct strbuf *referent, unsigned int *type) { struct files_ref_store *refs = - get_files_ref_store(NULL, "read_raw_ref"); + files_downcast(ref_store, 1, "read_raw_ref"); struct strbuf sb_contents = STRBUF_INIT; struct strbuf sb_path = STRBUF_INIT; const char *path; @@ -1365,7 +1366,12 @@ int read_raw_ref(const char *refname, unsigned char *sha1, *type = 0; strbuf_reset(&sb_path); - strbuf_git_path(&sb_path, "%s", refname); + + if (*refs->base.submodule) + strbuf_git_path_submodule(&sb_path, refs->base.submodule, "%s", refname); + else + strbuf_git_path(&sb_path, "%s", refname); + path = sb_path.buf; stat_ref: @@ -1592,8 +1598,9 @@ static int lock_raw_ref(const char *refname, int mustexist, unsigned int *type, struct strbuf *err) { + struct ref_store *ref_store = get_ref_store(NULL); struct files_ref_store *refs = - get_files_ref_store(NULL, "lock_raw_ref"); + files_downcast(ref_store, 0, "lock_raw_ref"); struct ref_lock *lock; struct strbuf ref_file = STRBUF_INIT; int attempts_remaining = 3; @@ -1683,7 +1690,8 @@ retry: * fear that its value will change. */ - if (read_raw_ref(refname, lock->old_oid.hash, referent, type)) { + if (read_raw_ref(ref_store, refname, + lock->old_oid.hash, referent, type)) { if (errno == ENOENT) { if (mustexist) { /* Garden variety missing reference. */ -- cgit v1.2.1 From 424dcc7683a37d1f14aa0dd485300001cb854f6c Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Sun, 4 Sep 2016 18:08:22 +0200 Subject: resolve_gitlink_ref(): implement using resolve_ref_recursively() resolve_ref_recursively() can handle references in arbitrary files reference stores, so use it to resolve "gitlink" (i.e., submodule) references. Aside from removing redundant code, this allows submodule lookups to benefit from the much more robust code that we use for reading non-submodule references. And, since the code is now agnostic about reference backends, it will work for any future references backend (so move its definition to refs.c). Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- refs/files-backend.c | 67 ---------------------------------------------------- 1 file changed, 67 deletions(-) (limited to 'refs/files-backend.c') diff --git a/refs/files-backend.c b/refs/files-backend.c index a743da4c1e..979cee884a 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -1494,73 +1494,6 @@ static void unlock_ref(struct ref_lock *lock) free(lock); } -#define MAXREFLEN (1024) - -static int resolve_gitlink_ref_recursive(struct files_ref_store *refs, - const char *refname, unsigned char *sha1, - int recursion) -{ - int fd, len; - char buffer[128], *p; - char *path; - - if (recursion > SYMREF_MAXDEPTH || strlen(refname) > MAXREFLEN) - return -1; - path = *refs->base.submodule - ? git_pathdup_submodule(refs->base.submodule, "%s", refname) - : git_pathdup("%s", refname); - fd = open(path, O_RDONLY); - free(path); - if (fd < 0) { - unsigned int flags; - - return resolve_packed_ref(refs, refname, sha1, &flags); - } - - len = read(fd, buffer, sizeof(buffer)-1); - close(fd); - if (len < 0) - return -1; - while (len && isspace(buffer[len-1])) - len--; - buffer[len] = 0; - - /* Was it a detached head or an old-fashioned symlink? */ - if (!get_sha1_hex(buffer, sha1)) - return 0; - - /* Symref? */ - if (strncmp(buffer, "ref:", 4)) - return -1; - p = buffer + 4; - while (isspace(*p)) - p++; - - return resolve_gitlink_ref_recursive(refs, p, sha1, recursion+1); -} - -int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *sha1) -{ - int len = strlen(path); - struct strbuf submodule = STRBUF_INIT; - struct files_ref_store *refs; - - while (len && path[len-1] == '/') - len--; - if (!len) - return -1; - - strbuf_add(&submodule, path, len); - refs = get_files_ref_store(submodule.buf, "resolve_gitlink_ref"); - if (!refs) { - strbuf_release(&submodule); - return -1; - } - strbuf_release(&submodule); - - return resolve_gitlink_ref_recursive(refs, refname, sha1, 0); -} - /* * Lock refname, without following symrefs, and set *lock_p to point * at a newly-allocated lock object. Fill in lock->old_oid, referent, -- cgit v1.2.1 From e1e33b722c50c26546335fd5a709f89726c2ea2a Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Sun, 4 Sep 2016 18:08:25 +0200 Subject: refs: make read_raw_ref() virtual Reference backends will be able to customize this function to implement reference reading. Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- refs/files-backend.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'refs/files-backend.c') diff --git a/refs/files-backend.c b/refs/files-backend.c index 979cee884a..9cf2f82f74 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -1349,9 +1349,9 @@ static int resolve_packed_ref(struct files_ref_store *refs, return -1; } -int read_raw_ref(struct ref_store *ref_store, - const char *refname, unsigned char *sha1, - struct strbuf *referent, unsigned int *type) +static int files_read_raw_ref(struct ref_store *ref_store, + const char *refname, unsigned char *sha1, + struct strbuf *referent, unsigned int *type) { struct files_ref_store *refs = files_downcast(ref_store, 1, "read_raw_ref"); @@ -1623,8 +1623,8 @@ retry: * fear that its value will change. */ - if (read_raw_ref(ref_store, refname, - lock->old_oid.hash, referent, type)) { + if (files_read_raw_ref(ref_store, refname, + lock->old_oid.hash, referent, type)) { if (errno == ENOENT) { if (mustexist) { /* Garden variety missing reference. */ @@ -4019,5 +4019,7 @@ struct ref_storage_be refs_be_files = { NULL, "files", files_ref_store_create, - files_transaction_commit + files_transaction_commit, + + files_read_raw_ref }; -- cgit v1.2.1 From 62665823d2ddbe69abdac4a9db399769c3e278b4 Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Sun, 4 Sep 2016 18:08:26 +0200 Subject: refs: make verify_refname_available() virtual Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- refs/files-backend.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'refs/files-backend.c') diff --git a/refs/files-backend.c b/refs/files-backend.c index 9cf2f82f74..44eef1cec7 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -2549,13 +2549,14 @@ out: return ret; } -int verify_refname_available(const char *newname, - const struct string_list *extras, - const struct string_list *skip, - struct strbuf *err) +static int files_verify_refname_available(struct ref_store *ref_store, + const char *newname, + const struct string_list *extras, + const struct string_list *skip, + struct strbuf *err) { struct files_ref_store *refs = - get_files_ref_store(NULL, "verify_refname_available"); + files_downcast(ref_store, 1, "verify_refname_available"); struct ref_dir *packed_refs = get_packed_refs(refs); struct ref_dir *loose_refs = get_loose_refs(refs); @@ -4021,5 +4022,6 @@ struct ref_storage_be refs_be_files = { files_ref_store_create, files_transaction_commit, - files_read_raw_ref + files_read_raw_ref, + files_verify_refname_available }; -- cgit v1.2.1 From 8231527e1510127a5611a2e2f9660e6aef1c981e Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Sun, 4 Sep 2016 18:08:27 +0200 Subject: refs: make pack_refs() virtual Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- refs/files-backend.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'refs/files-backend.c') diff --git a/refs/files-backend.c b/refs/files-backend.c index 44eef1cec7..5ba2804a86 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -2354,10 +2354,10 @@ static void prune_refs(struct ref_to_prune *r) } } -int pack_refs(unsigned int flags) +static int files_pack_refs(struct ref_store *ref_store, unsigned int flags) { struct files_ref_store *refs = - get_files_ref_store(NULL, "pack_refs"); + files_downcast(ref_store, 0, "pack_refs"); struct pack_refs_cb_data cbdata; memset(&cbdata, 0, sizeof(cbdata)); @@ -4022,6 +4022,8 @@ struct ref_storage_be refs_be_files = { files_ref_store_create, files_transaction_commit, + files_pack_refs, + files_read_raw_ref, files_verify_refname_available }; -- cgit v1.2.1 From 284689ba0ff7506d581bcee7481a2621492135ef Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Sun, 4 Sep 2016 18:08:28 +0200 Subject: refs: make create_symref() virtual Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- refs/files-backend.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'refs/files-backend.c') diff --git a/refs/files-backend.c b/refs/files-backend.c index 5ba2804a86..fc67cc6ec7 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -3011,12 +3011,16 @@ static int create_symref_locked(struct ref_lock *lock, const char *refname, return 0; } -int create_symref(const char *refname, const char *target, const char *logmsg) +static int files_create_symref(struct ref_store *ref_store, + const char *refname, const char *target, + const char *logmsg) { struct strbuf err = STRBUF_INIT; struct ref_lock *lock; int ret; + files_downcast(ref_store, 0, "create_symref"); + lock = lock_ref_sha1_basic(refname, NULL, NULL, NULL, REF_NODEREF, NULL, &err); if (!lock) { @@ -4023,6 +4027,7 @@ struct ref_storage_be refs_be_files = { files_transaction_commit, files_pack_refs, + files_create_symref, files_read_raw_ref, files_verify_refname_available -- cgit v1.2.1 From bd427cf27f561174fa8fa14e2c8c321d2df82c47 Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Sun, 4 Sep 2016 18:08:29 +0200 Subject: refs: make peel_ref() virtual For now it only supports the main reference store. Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- refs/files-backend.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'refs/files-backend.c') diff --git a/refs/files-backend.c b/refs/files-backend.c index fc67cc6ec7..af3ad83fe5 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -1759,9 +1759,10 @@ static enum peel_status peel_entry(struct ref_entry *entry, int repeel) return status; } -int peel_ref(const char *refname, unsigned char *sha1) +static int files_peel_ref(struct ref_store *ref_store, + const char *refname, unsigned char *sha1) { - struct files_ref_store *refs = get_files_ref_store(NULL, "peel_ref"); + struct files_ref_store *refs = files_downcast(ref_store, 0, "peel_ref"); int flag; unsigned char base[20]; @@ -4027,6 +4028,7 @@ struct ref_storage_be refs_be_files = { files_transaction_commit, files_pack_refs, + files_peel_ref, files_create_symref, files_read_raw_ref, -- cgit v1.2.1 From 0a95ac5f630c01ba8a50b72cae9e067cb256cb0f Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Sun, 4 Sep 2016 18:08:30 +0200 Subject: repack_without_refs(): add a files_ref_store argument Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- refs/files-backend.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'refs/files-backend.c') diff --git a/refs/files-backend.c b/refs/files-backend.c index af3ad83fe5..af711f6f3d 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -2384,14 +2384,14 @@ static int files_pack_refs(struct ref_store *ref_store, unsigned int flags) * * The refs in 'refnames' needn't be sorted. `err` must not be NULL. */ -static int repack_without_refs(struct string_list *refnames, struct strbuf *err) +static int repack_without_refs(struct files_ref_store *refs, + struct string_list *refnames, struct strbuf *err) { - struct files_ref_store *refs = - get_files_ref_store(NULL, "repack_without_refs"); struct ref_dir *packed; struct string_list_item *refname; int ret, needs_repacking = 0, removed = 0; + assert_main_repository(&refs->base, "repack_without_refs"); assert(err); /* Look for a packed ref */ @@ -2453,13 +2453,15 @@ static int delete_ref_loose(struct ref_lock *lock, int flag, struct strbuf *err) int delete_refs(struct string_list *refnames, unsigned int flags) { + struct files_ref_store *refs = + get_files_ref_store(NULL, "delete_refs"); struct strbuf err = STRBUF_INIT; int i, result = 0; if (!refnames->nr) return 0; - result = repack_without_refs(refnames, &err); + result = repack_without_refs(refs, refnames, &err); if (result) { /* * If we failed to rewrite the packed-refs file, then @@ -3769,7 +3771,7 @@ static int files_transaction_commit(struct ref_store *ref_store, } } - if (repack_without_refs(&refs_to_delete, err)) { + if (repack_without_refs(refs, &refs_to_delete, err)) { ret = TRANSACTION_GENERIC_ERROR; goto cleanup; } -- cgit v1.2.1 From f7b0a987b564b356ffcf7eb62fa33b200cbd5b87 Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Sun, 4 Sep 2016 18:08:31 +0200 Subject: lock_raw_ref(): add a files_ref_store argument Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- refs/files-backend.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'refs/files-backend.c') diff --git a/refs/files-backend.c b/refs/files-backend.c index af711f6f3d..4f4ab0fd09 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -1523,7 +1523,8 @@ static void unlock_ref(struct ref_lock *lock) * avoided, namely if we were successfully able to read the ref * - Generate informative error messages in the case of failure */ -static int lock_raw_ref(const char *refname, int mustexist, +static int lock_raw_ref(struct files_ref_store *refs, + const char *refname, int mustexist, const struct string_list *extras, const struct string_list *skip, struct ref_lock **lock_p, @@ -1531,15 +1532,14 @@ static int lock_raw_ref(const char *refname, int mustexist, unsigned int *type, struct strbuf *err) { - struct ref_store *ref_store = get_ref_store(NULL); - struct files_ref_store *refs = - files_downcast(ref_store, 0, "lock_raw_ref"); struct ref_lock *lock; struct strbuf ref_file = STRBUF_INIT; int attempts_remaining = 3; int ret = TRANSACTION_GENERIC_ERROR; assert(err); + assert_main_repository(&refs->base, "lock_raw_ref"); + *type = 0; /* First lock the file so it can't change out from under us. */ @@ -1623,7 +1623,7 @@ retry: * fear that its value will change. */ - if (files_read_raw_ref(ref_store, refname, + if (files_read_raw_ref(&refs->base, refname, lock->old_oid.hash, referent, type)) { if (errno == ENOENT) { if (mustexist) { @@ -3486,6 +3486,8 @@ static int lock_ref_for_update(struct ref_update *update, struct string_list *affected_refnames, struct strbuf *err) { + struct files_ref_store *refs = + get_files_ref_store(NULL, "lock_ref_for_update"); struct strbuf referent = STRBUF_INIT; int mustexist = (update->flags & REF_HAVE_OLD) && !is_null_sha1(update->old_sha1); @@ -3502,7 +3504,7 @@ static int lock_ref_for_update(struct ref_update *update, return ret; } - ret = lock_raw_ref(update->refname, mustexist, + ret = lock_raw_ref(refs, update->refname, mustexist, affected_refnames, NULL, &update->lock, &referent, &update->type, err); -- cgit v1.2.1 From f18a7892500d494b96c992084951fa85dec4abc2 Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Sun, 4 Sep 2016 18:08:32 +0200 Subject: commit_ref_update(): add a files_ref_store argument Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- refs/files-backend.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'refs/files-backend.c') diff --git a/refs/files-backend.c b/refs/files-backend.c index 4f4ab0fd09..82d9148b82 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -2574,12 +2574,14 @@ static int files_verify_refname_available(struct ref_store *ref_store, static int write_ref_to_lockfile(struct ref_lock *lock, const unsigned char *sha1, struct strbuf *err); -static int commit_ref_update(struct ref_lock *lock, +static int commit_ref_update(struct files_ref_store *refs, + struct ref_lock *lock, const unsigned char *sha1, const char *logmsg, struct strbuf *err); int rename_ref(const char *oldrefname, const char *newrefname, const char *logmsg) { + struct files_ref_store *refs = get_files_ref_store(NULL, "rename_ref"); unsigned char sha1[20], orig_sha1[20]; int flag = 0, logmoved = 0; struct ref_lock *lock; @@ -2652,7 +2654,7 @@ int rename_ref(const char *oldrefname, const char *newrefname, const char *logms hashcpy(lock->old_oid.hash, orig_sha1); if (write_ref_to_lockfile(lock, orig_sha1, &err) || - commit_ref_update(lock, orig_sha1, logmsg, &err)) { + commit_ref_update(refs, lock, orig_sha1, logmsg, &err)) { error("unable to write current sha1 into %s: %s", newrefname, err.buf); strbuf_release(&err); goto rollback; @@ -2672,7 +2674,7 @@ int rename_ref(const char *oldrefname, const char *newrefname, const char *logms flag = log_all_ref_updates; log_all_ref_updates = 0; if (write_ref_to_lockfile(lock, orig_sha1, &err) || - commit_ref_update(lock, orig_sha1, NULL, &err)) { + commit_ref_update(refs, lock, orig_sha1, NULL, &err)) { error("unable to write current sha1 into %s: %s", oldrefname, err.buf); strbuf_release(&err); } @@ -2908,12 +2910,12 @@ static int write_ref_to_lockfile(struct ref_lock *lock, * to the loose reference lockfile. Also update the reflogs if * necessary, using the specified lockmsg (which can be NULL). */ -static int commit_ref_update(struct ref_lock *lock, +static int commit_ref_update(struct files_ref_store *refs, + struct ref_lock *lock, const unsigned char *sha1, const char *logmsg, struct strbuf *err) { - struct files_ref_store *refs = - get_files_ref_store(NULL, "commit_ref_update"); + assert_main_repository(&refs->base, "commit_ref_update"); clear_loose_ref_cache(refs); if (log_ref_write(lock->ref_name, lock->old_oid.hash, sha1, logmsg, 0, err)) { -- cgit v1.2.1 From b3bbbc5c245b2599f3b53122f2bb57a054027413 Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Sun, 4 Sep 2016 18:08:33 +0200 Subject: lock_ref_for_update(): add a files_ref_store argument Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- refs/files-backend.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'refs/files-backend.c') diff --git a/refs/files-backend.c b/refs/files-backend.c index 82d9148b82..7e869ba037 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -3482,20 +3482,21 @@ static const char *original_update_refname(struct ref_update *update) * - If it is an update of head_ref, add a corresponding REF_LOG_ONLY * update of HEAD. */ -static int lock_ref_for_update(struct ref_update *update, +static int lock_ref_for_update(struct files_ref_store *refs, + struct ref_update *update, struct ref_transaction *transaction, const char *head_ref, struct string_list *affected_refnames, struct strbuf *err) { - struct files_ref_store *refs = - get_files_ref_store(NULL, "lock_ref_for_update"); struct strbuf referent = STRBUF_INIT; int mustexist = (update->flags & REF_HAVE_OLD) && !is_null_sha1(update->old_sha1); int ret; struct ref_lock *lock; + assert_main_repository(&refs->base, "lock_ref_for_update"); + if ((update->flags & REF_HAVE_NEW) && is_null_sha1(update->new_sha1)) update->flags |= REF_DELETING; @@ -3720,8 +3721,8 @@ static int files_transaction_commit(struct ref_store *ref_store, for (i = 0; i < transaction->nr; i++) { struct ref_update *update = transaction->updates[i]; - ret = lock_ref_for_update(update, transaction, head_ref, - &affected_refnames, err); + ret = lock_ref_for_update(refs, update, transaction, + head_ref, &affected_refnames, err); if (ret) goto cleanup; } -- cgit v1.2.1 From 7eb27cdfe67f07bcfcd7781bed8110e8ae70d001 Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Sun, 4 Sep 2016 18:08:34 +0200 Subject: lock_ref_sha1_basic(): add a files_ref_store argument Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- refs/files-backend.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'refs/files-backend.c') diff --git a/refs/files-backend.c b/refs/files-backend.c index 7e869ba037..396647b396 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -1983,15 +1983,14 @@ static int remove_empty_directories(struct strbuf *path) * Locks a ref returning the lock on success and NULL on failure. * On failure errno is set to something meaningful. */ -static struct ref_lock *lock_ref_sha1_basic(const char *refname, +static struct ref_lock *lock_ref_sha1_basic(struct files_ref_store *refs, + const char *refname, const unsigned char *old_sha1, const struct string_list *extras, const struct string_list *skip, unsigned int flags, int *type, struct strbuf *err) { - struct files_ref_store *refs = - get_files_ref_store(NULL, "lock_ref_sha1_basic"); struct strbuf ref_file = STRBUF_INIT; struct ref_lock *lock; int last_errno = 0; @@ -2001,6 +2000,7 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname, int attempts_remaining = 3; int resolved; + assert_main_repository(&refs->base, "lock_ref_sha1_basic"); assert(err); lock = xcalloc(1, sizeof(struct ref_lock)); @@ -2644,8 +2644,8 @@ int rename_ref(const char *oldrefname, const char *newrefname, const char *logms logmoved = log; - lock = lock_ref_sha1_basic(newrefname, NULL, NULL, NULL, REF_NODEREF, - NULL, &err); + lock = lock_ref_sha1_basic(refs, newrefname, NULL, NULL, NULL, + REF_NODEREF, NULL, &err); if (!lock) { error("unable to rename '%s' to '%s': %s", oldrefname, newrefname, err.buf); strbuf_release(&err); @@ -2663,8 +2663,8 @@ int rename_ref(const char *oldrefname, const char *newrefname, const char *logms return 0; rollback: - lock = lock_ref_sha1_basic(oldrefname, NULL, NULL, NULL, REF_NODEREF, - NULL, &err); + lock = lock_ref_sha1_basic(refs, oldrefname, NULL, NULL, NULL, + REF_NODEREF, NULL, &err); if (!lock) { error("unable to lock %s for rollback: %s", oldrefname, err.buf); strbuf_release(&err); @@ -3020,13 +3020,14 @@ static int files_create_symref(struct ref_store *ref_store, const char *refname, const char *target, const char *logmsg) { + struct files_ref_store *refs = + files_downcast(ref_store, 0, "create_symref"); struct strbuf err = STRBUF_INIT; struct ref_lock *lock; int ret; - files_downcast(ref_store, 0, "create_symref"); - - lock = lock_ref_sha1_basic(refname, NULL, NULL, NULL, REF_NODEREF, NULL, + lock = lock_ref_sha1_basic(refs, refname, NULL, + NULL, NULL, REF_NODEREF, NULL, &err); if (!lock) { error("%s", err.buf); @@ -3929,6 +3930,8 @@ int reflog_expire(const char *refname, const unsigned char *sha1, reflog_expiry_cleanup_fn cleanup_fn, void *policy_cb_data) { + struct files_ref_store *refs = + get_files_ref_store(NULL, "reflog_expire"); static struct lock_file reflog_lock; struct expire_reflog_cb cb; struct ref_lock *lock; @@ -3947,7 +3950,8 @@ int reflog_expire(const char *refname, const unsigned char *sha1, * reference itself, plus we might need to update the * reference if --updateref was specified: */ - lock = lock_ref_sha1_basic(refname, sha1, NULL, NULL, REF_NODEREF, + lock = lock_ref_sha1_basic(refs, refname, sha1, + NULL, NULL, REF_NODEREF, &type, &err); if (!lock) { error("cannot lock ref '%s': %s", refname, err.buf); -- cgit v1.2.1 From fcc42ea0c92e357da40f7cbc598152e2f8dfe083 Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Sun, 4 Sep 2016 18:08:35 +0200 Subject: split_symref_update(): add a files_ref_store argument Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- refs/files-backend.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'refs/files-backend.c') diff --git a/refs/files-backend.c b/refs/files-backend.c index 396647b396..9607fbd17a 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -3401,7 +3401,8 @@ static int split_head_update(struct ref_update *update, * Note that the new update will itself be subject to splitting when * the iteration gets to it. */ -static int split_symref_update(struct ref_update *update, +static int split_symref_update(struct files_ref_store *refs, + struct ref_update *update, const char *referent, struct ref_transaction *transaction, struct string_list *affected_refnames, @@ -3562,7 +3563,8 @@ static int lock_ref_for_update(struct files_ref_store *refs, * of processing the split-off update, so we * don't have to do it here. */ - ret = split_symref_update(update, referent.buf, transaction, + ret = split_symref_update(refs, update, + referent.buf, transaction, affected_refnames, err); if (ret) return ret; -- cgit v1.2.1 From 37b6f6d5f41c493bc083b5ee4c54519f8dd6d46c Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Sun, 4 Sep 2016 18:08:36 +0200 Subject: files_ref_iterator_begin(): take a ref_store argument Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- refs/files-backend.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'refs/files-backend.c') diff --git a/refs/files-backend.c b/refs/files-backend.c index 9607fbd17a..4918469f34 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -1863,11 +1863,11 @@ static struct ref_iterator_vtable files_ref_iterator_vtable = { }; struct ref_iterator *files_ref_iterator_begin( - const char *submodule, + struct ref_store *ref_store, const char *prefix, unsigned int flags) { struct files_ref_store *refs = - get_files_ref_store(submodule, "ref_iterator_begin"); + files_downcast(ref_store, 1, "ref_iterator_begin"); struct ref_dir *loose_dir, *packed_dir; struct ref_iterator *loose_iter, *packed_iter; struct files_ref_iterator *iter; -- cgit v1.2.1 From 1a769003c19c106063f4bf474b0d7ef56be8df25 Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Sun, 4 Sep 2016 18:08:37 +0200 Subject: refs: add method iterator_begin Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- refs/files-backend.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'refs/files-backend.c') diff --git a/refs/files-backend.c b/refs/files-backend.c index 4918469f34..2cda511352 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -1862,7 +1862,7 @@ static struct ref_iterator_vtable files_ref_iterator_vtable = { files_ref_iterator_abort }; -struct ref_iterator *files_ref_iterator_begin( +static struct ref_iterator *files_ref_iterator_begin( struct ref_store *ref_store, const char *prefix, unsigned int flags) { @@ -4044,6 +4044,7 @@ struct ref_storage_be refs_be_files = { files_peel_ref, files_create_symref, + files_ref_iterator_begin, files_read_raw_ref, files_verify_refname_available }; -- cgit v1.2.1 From e3688bd6cf159f6026a6bca7a6f53d0a22fe21a2 Mon Sep 17 00:00:00 2001 From: David Turner Date: Sun, 4 Sep 2016 18:08:38 +0200 Subject: refs: add methods for reflog In the file-based backend, the reflog piggybacks on the ref lock. Since other backends won't have the same sort of ref lock, ref backends must also handle reflogs. Signed-off-by: Ronnie Sahlberg Signed-off-by: David Turner Signed-off-by: Junio C Hamano Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- refs/files-backend.c | 70 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 50 insertions(+), 20 deletions(-) (limited to 'refs/files-backend.c') diff --git a/refs/files-backend.c b/refs/files-backend.c index 2cda511352..336d432572 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -2777,11 +2777,16 @@ static int log_ref_setup(const char *refname, struct strbuf *logfile, struct str } -int safe_create_reflog(const char *refname, int force_create, struct strbuf *err) +static int files_create_reflog(struct ref_store *ref_store, + const char *refname, int force_create, + struct strbuf *err) { int ret; struct strbuf sb = STRBUF_INIT; + /* Check validity (but we don't need the result): */ + files_downcast(ref_store, 0, "create_reflog"); + ret = log_ref_setup(refname, &sb, err, force_create); strbuf_release(&sb); return ret; @@ -3075,16 +3080,24 @@ int set_worktree_head_symref(const char *gitdir, const char *target) return ret; } -int reflog_exists(const char *refname) +static int files_reflog_exists(struct ref_store *ref_store, + const char *refname) { struct stat st; + /* Check validity (but we don't need the result): */ + files_downcast(ref_store, 0, "reflog_exists"); + return !lstat(git_path("logs/%s", refname), &st) && S_ISREG(st.st_mode); } -int delete_reflog(const char *refname) +static int files_delete_reflog(struct ref_store *ref_store, + const char *refname) { + /* Check validity (but we don't need the result): */ + files_downcast(ref_store, 0, "delete_reflog"); + return remove_path(git_path("logs/%s", refname)); } @@ -3127,13 +3140,19 @@ static char *find_beginning_of_line(char *bob, char *scan) return scan; } -int for_each_reflog_ent_reverse(const char *refname, each_reflog_ent_fn fn, void *cb_data) +static int files_for_each_reflog_ent_reverse(struct ref_store *ref_store, + const char *refname, + each_reflog_ent_fn fn, + void *cb_data) { struct strbuf sb = STRBUF_INIT; FILE *logfp; long pos; int ret = 0, at_tail = 1; + /* Check validity (but we don't need the result): */ + files_downcast(ref_store, 0, "for_each_reflog_ent_reverse"); + logfp = fopen(git_path("logs/%s", refname), "r"); if (!logfp) return -1; @@ -3229,12 +3248,17 @@ int for_each_reflog_ent_reverse(const char *refname, each_reflog_ent_fn fn, void return ret; } -int for_each_reflog_ent(const char *refname, each_reflog_ent_fn fn, void *cb_data) +static int files_for_each_reflog_ent(struct ref_store *ref_store, + const char *refname, + each_reflog_ent_fn fn, void *cb_data) { FILE *logfp; struct strbuf sb = STRBUF_INIT; int ret = 0; + /* Check validity (but we don't need the result): */ + files_downcast(ref_store, 0, "for_each_reflog_ent"); + logfp = fopen(git_path("logs/%s", refname), "r"); if (!logfp) return -1; @@ -3313,22 +3337,19 @@ static struct ref_iterator_vtable files_reflog_iterator_vtable = { files_reflog_iterator_abort }; -struct ref_iterator *files_reflog_iterator_begin(void) +static struct ref_iterator *files_reflog_iterator_begin(struct ref_store *ref_store) { struct files_reflog_iterator *iter = xcalloc(1, sizeof(*iter)); struct ref_iterator *ref_iterator = &iter->base; + /* Check validity (but we don't need the result): */ + files_downcast(ref_store, 0, "reflog_iterator_begin"); + base_ref_iterator_init(ref_iterator, &files_reflog_iterator_vtable); iter->dir_iterator = dir_iterator_begin(git_path("logs")); return ref_iterator; } -int for_each_reflog(each_ref_fn fn, void *cb_data) -{ - return do_for_each_ref_iterator(files_reflog_iterator_begin(), - fn, cb_data); -} - static int ref_update_reject_duplicates(struct string_list *refnames, struct strbuf *err) { @@ -3925,15 +3946,16 @@ static int expire_reflog_ent(unsigned char *osha1, unsigned char *nsha1, return 0; } -int reflog_expire(const char *refname, const unsigned char *sha1, - unsigned int flags, - reflog_expiry_prepare_fn prepare_fn, - reflog_expiry_should_prune_fn should_prune_fn, - reflog_expiry_cleanup_fn cleanup_fn, - void *policy_cb_data) +static int files_reflog_expire(struct ref_store *ref_store, + const char *refname, const unsigned char *sha1, + unsigned int flags, + reflog_expiry_prepare_fn prepare_fn, + reflog_expiry_should_prune_fn should_prune_fn, + reflog_expiry_cleanup_fn cleanup_fn, + void *policy_cb_data) { struct files_ref_store *refs = - get_files_ref_store(NULL, "reflog_expire"); + files_downcast(ref_store, 0, "reflog_expire"); static struct lock_file reflog_lock; struct expire_reflog_cb cb; struct ref_lock *lock; @@ -4046,5 +4068,13 @@ struct ref_storage_be refs_be_files = { files_ref_iterator_begin, files_read_raw_ref, - files_verify_refname_available + files_verify_refname_available, + + files_reflog_iterator_begin, + files_for_each_reflog_ent, + files_for_each_reflog_ent_reverse, + files_reflog_exists, + files_create_reflog, + files_delete_reflog, + files_reflog_expire }; -- cgit v1.2.1 From fc6814637d2e756029b45cb5fd952359bfec6f88 Mon Sep 17 00:00:00 2001 From: David Turner Date: Sun, 4 Sep 2016 18:08:39 +0200 Subject: refs: add method for initial ref transaction commit Signed-off-by: Ronnie Sahlberg Signed-off-by: David Turner Signed-off-by: Junio C Hamano Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- refs/files-backend.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'refs/files-backend.c') diff --git a/refs/files-backend.c b/refs/files-backend.c index 336d432572..0a511bf5a4 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -3829,11 +3829,12 @@ static int ref_present(const char *refname, return string_list_has_string(affected_refnames, refname); } -int initial_ref_transaction_commit(struct ref_transaction *transaction, - struct strbuf *err) +static int files_initial_transaction_commit(struct ref_store *ref_store, + struct ref_transaction *transaction, + struct strbuf *err) { struct files_ref_store *refs = - get_files_ref_store(NULL, "initial_ref_transaction_commit"); + files_downcast(ref_store, 0, "initial_ref_transaction_commit"); int ret = 0, i; struct string_list affected_refnames = STRING_LIST_INIT_NODUP; @@ -4061,6 +4062,7 @@ struct ref_storage_be refs_be_files = { "files", files_ref_store_create, files_transaction_commit, + files_initial_transaction_commit, files_pack_refs, files_peel_ref, -- cgit v1.2.1 From a27dcf89b6867577bb714e181dd181cd1a1e6512 Mon Sep 17 00:00:00 2001 From: David Turner Date: Sun, 4 Sep 2016 18:08:40 +0200 Subject: refs: make delete_refs() virtual In the file-based backend, delete_refs has some special optimization to deal with packed refs. In other backends, we might be able to make ref deletion faster by putting all deletions into a single transaction. So we need a special backend function for this. Signed-off-by: David Turner Signed-off-by: Junio C Hamano Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- refs/files-backend.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'refs/files-backend.c') diff --git a/refs/files-backend.c b/refs/files-backend.c index 0a511bf5a4..33ec530384 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -2451,10 +2451,11 @@ static int delete_ref_loose(struct ref_lock *lock, int flag, struct strbuf *err) return 0; } -int delete_refs(struct string_list *refnames, unsigned int flags) +static int files_delete_refs(struct ref_store *ref_store, + struct string_list *refnames, unsigned int flags) { struct files_ref_store *refs = - get_files_ref_store(NULL, "delete_refs"); + files_downcast(ref_store, 0, "delete_refs"); struct strbuf err = STRBUF_INIT; int i, result = 0; @@ -4067,6 +4068,7 @@ struct ref_storage_be refs_be_files = { files_pack_refs, files_peel_ref, files_create_symref, + files_delete_refs, files_ref_iterator_begin, files_read_raw_ref, -- cgit v1.2.1 From 6fb5acfd8f7102f53dedc887233313f233a65932 Mon Sep 17 00:00:00 2001 From: David Turner Date: Sun, 4 Sep 2016 18:08:41 +0200 Subject: 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 Signed-off-by: Junio C Hamano Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- refs/files-backend.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'refs/files-backend.c') diff --git a/refs/files-backend.c b/refs/files-backend.c index 33ec530384..40e789611c 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -4058,10 +4058,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, -- cgit v1.2.1 From 9b6b40d93a4c93d36225533ddc6717841b07d09d Mon Sep 17 00:00:00 2001 From: David Turner Date: Sun, 4 Sep 2016 18:08:42 +0200 Subject: refs: add method to rename refs This removes the last caller of function get_files_ref_store(), so remove it. Signed-off-by: David Turner Signed-off-by: Junio C Hamano Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- refs/files-backend.c | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) (limited to 'refs/files-backend.c') diff --git a/refs/files-backend.c b/refs/files-backend.c index 40e789611c..f61101a799 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -997,22 +997,6 @@ static struct files_ref_store *files_downcast( return (struct files_ref_store *)ref_store; } -/* - * Return a pointer to the reference store for the specified - * submodule. For the main repository, use submodule==NULL; such a - * call cannot fail. For a submodule, the submodule must exist and be - * a nonbare repository, otherwise return NULL. Verify that the - * reference store is a files_ref_store, and cast it to that type - * before returning it. - */ -static struct files_ref_store *get_files_ref_store(const char *submodule, - const char *caller) -{ - struct ref_store *refs = get_ref_store(submodule); - - return refs ? files_downcast(refs, 1, caller) : NULL; -} - /* The length of a peeled reference line in packed-refs, including EOL: */ #define PEELED_LINE_LENGTH 42 @@ -2580,9 +2564,12 @@ static int commit_ref_update(struct files_ref_store *refs, const unsigned char *sha1, const char *logmsg, struct strbuf *err); -int rename_ref(const char *oldrefname, const char *newrefname, const char *logmsg) +static int files_rename_ref(struct ref_store *ref_store, + const char *oldrefname, const char *newrefname, + const char *logmsg) { - struct files_ref_store *refs = get_files_ref_store(NULL, "rename_ref"); + struct files_ref_store *refs = + files_downcast(ref_store, 0, "rename_ref"); unsigned char sha1[20], orig_sha1[20]; int flag = 0, logmoved = 0; struct ref_lock *lock; @@ -4087,6 +4074,7 @@ struct ref_storage_be refs_be_files = { files_peel_ref, files_create_symref, files_delete_refs, + files_rename_ref, files_ref_iterator_begin, files_read_raw_ref, -- cgit v1.2.1 From 7d618264394a17e6ecd83d9412ac9ddb4609a2e5 Mon Sep 17 00:00:00 2001 From: David Turner Date: Sun, 4 Sep 2016 18:08:43 +0200 Subject: refs: make lock generic Instead of including a files-backend-specific struct ref_lock, change the generic ref_update struct to include a void pointer that backends can use for their own arbitrary data. Signed-off-by: David Turner Signed-off-by: Junio C Hamano Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- refs/files-backend.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'refs/files-backend.c') diff --git a/refs/files-backend.c b/refs/files-backend.c index f61101a799..82b3ac0dbc 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -3520,9 +3520,8 @@ static int lock_ref_for_update(struct files_ref_store *refs, ret = lock_raw_ref(refs, update->refname, mustexist, affected_refnames, NULL, - &update->lock, &referent, + &lock, &referent, &update->type, err); - if (ret) { char *reason; @@ -3533,7 +3532,7 @@ static int lock_ref_for_update(struct files_ref_store *refs, return ret; } - lock = update->lock; + update->backend_data = lock; if (update->type & REF_ISSYMREF) { if (update->flags & REF_NODEREF) { @@ -3589,7 +3588,8 @@ static int lock_ref_for_update(struct files_ref_store *refs, for (parent_update = update->parent_update; parent_update; parent_update = parent_update->parent_update) { - oidcpy(&parent_update->lock->old_oid, &lock->old_oid); + struct ref_lock *parent_lock = parent_update->backend_data; + oidcpy(&parent_lock->old_oid, &lock->old_oid); } if ((update->flags & REF_HAVE_OLD) && @@ -3624,7 +3624,7 @@ static int lock_ref_for_update(struct files_ref_store *refs, * The lock was freed upon failure of * write_ref_to_lockfile(): */ - update->lock = NULL; + update->backend_data = NULL; strbuf_addf(err, "cannot update the ref '%s': %s", update->refname, write_err); @@ -3742,7 +3742,7 @@ static int files_transaction_commit(struct ref_store *ref_store, /* Perform updates first so live commits remain referenced */ for (i = 0; i < transaction->nr; i++) { struct ref_update *update = transaction->updates[i]; - struct ref_lock *lock = update->lock; + struct ref_lock *lock = update->backend_data; if (update->flags & REF_NEEDS_COMMIT || update->flags & REF_LOG_ONLY) { @@ -3755,7 +3755,7 @@ static int files_transaction_commit(struct ref_store *ref_store, lock->ref_name, old_msg); free(old_msg); unlock_ref(lock); - update->lock = NULL; + update->backend_data = NULL; ret = TRANSACTION_GENERIC_ERROR; goto cleanup; } @@ -3765,7 +3765,7 @@ static int files_transaction_commit(struct ref_store *ref_store, if (commit_ref(lock)) { strbuf_addf(err, "couldn't set '%s'", lock->ref_name); unlock_ref(lock); - update->lock = NULL; + update->backend_data = NULL; ret = TRANSACTION_GENERIC_ERROR; goto cleanup; } @@ -3774,17 +3774,18 @@ static int files_transaction_commit(struct ref_store *ref_store, /* Perform deletes now that updates are safely completed */ for (i = 0; i < transaction->nr; i++) { struct ref_update *update = transaction->updates[i]; + struct ref_lock *lock = update->backend_data; if (update->flags & REF_DELETING && !(update->flags & REF_LOG_ONLY)) { - if (delete_ref_loose(update->lock, update->type, err)) { + if (delete_ref_loose(lock, update->type, err)) { ret = TRANSACTION_GENERIC_ERROR; goto cleanup; } if (!(update->flags & REF_ISPRUNING)) string_list_append(&refs_to_delete, - update->lock->ref_name); + lock->ref_name); } } @@ -3800,8 +3801,8 @@ cleanup: transaction->state = REF_TRANSACTION_CLOSED; for (i = 0; i < transaction->nr; i++) - if (transaction->updates[i]->lock) - unlock_ref(transaction->updates[i]->lock); + if (transaction->updates[i]->backend_data) + unlock_ref(transaction->updates[i]->backend_data); string_list_clear(&refs_to_delete, 0); free(head_ref); string_list_clear(&affected_refnames, 0); -- cgit v1.2.1 From 0c09ec07d1e617be5f2d7b5c937b60e77a30ede2 Mon Sep 17 00:00:00 2001 From: David Turner Date: Sun, 4 Sep 2016 18:08:44 +0200 Subject: refs: implement iteration over only per-worktree refs Alternate refs backends might still use files to store per-worktree refs. So provide a way to iterate over only the per-worktree references in a ref_store. The other backend can set up a files ref_store and iterate using the new DO_FOR_EACH_PER_WORKTREE_ONLY flag when iterating. Signed-off-by: David Turner Signed-off-by: Junio C Hamano Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- refs/files-backend.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'refs/files-backend.c') diff --git a/refs/files-backend.c b/refs/files-backend.c index 82b3ac0dbc..47710fcf28 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -1798,6 +1798,10 @@ static int files_ref_iterator_advance(struct ref_iterator *ref_iterator) int ok; while ((ok = ref_iterator_advance(iter->iter0)) == ITER_OK) { + if (iter->flags & DO_FOR_EACH_PER_WORKTREE_ONLY && + ref_type(iter->iter0->refname) != REF_TYPE_PER_WORKTREE) + continue; + if (!(iter->flags & DO_FOR_EACH_INCLUDE_BROKEN) && !ref_resolves_to_object(iter->iter0->refname, iter->iter0->oid, -- cgit v1.2.1