diff options
Diffstat (limited to 'refs')
-rw-r--r-- | refs/debug.c | 81 | ||||
-rw-r--r-- | refs/files-backend.c | 96 | ||||
-rw-r--r-- | refs/iterator.c | 18 | ||||
-rw-r--r-- | refs/packed-backend.c | 130 | ||||
-rw-r--r-- | refs/ref-cache.c | 6 | ||||
-rw-r--r-- | refs/refs-internal.h | 16 |
6 files changed, 173 insertions, 174 deletions
diff --git a/refs/debug.c b/refs/debug.c index 2b0771ca53..eed8bc94b0 100644 --- a/refs/debug.c +++ b/refs/debug.c @@ -220,8 +220,9 @@ static int debug_ref_iterator_abort(struct ref_iterator *ref_iterator) } static struct ref_iterator_vtable debug_ref_iterator_vtable = { - debug_ref_iterator_advance, debug_ref_iterator_peel, - debug_ref_iterator_abort + .advance = debug_ref_iterator_advance, + .peel = debug_ref_iterator_peel, + .abort = debug_ref_iterator_abort, }; static struct ref_iterator * @@ -261,6 +262,24 @@ static int debug_read_raw_ref(struct ref_store *ref_store, const char *refname, return res; } +static int debug_read_symbolic_ref(struct ref_store *ref_store, const char *refname, + struct strbuf *referent) +{ + struct debug_ref_store *drefs = (struct debug_ref_store *)ref_store; + struct ref_store *refs = drefs->refs; + int res; + + res = refs->be->read_symbolic_ref(refs, refname, referent); + if (!res) + trace_printf_key(&trace_refs, "read_symbolic_ref: %s: (%s)\n", + refname, referent->buf); + else + trace_printf_key(&trace_refs, + "read_symbolic_ref: %s: %d\n", refname, res); + return res; + +} + static struct ref_iterator * debug_reflog_iterator_begin(struct ref_store *ref_store) { @@ -418,29 +437,37 @@ static int debug_reflog_expire(struct ref_store *ref_store, const char *refname, } struct ref_storage_be refs_be_debug = { - NULL, - "debug", - NULL, - debug_init_db, - debug_transaction_prepare, - debug_transaction_finish, - debug_transaction_abort, - debug_initial_transaction_commit, - - debug_pack_refs, - debug_create_symref, - debug_delete_refs, - debug_rename_ref, - debug_copy_ref, - - debug_ref_iterator_begin, - debug_read_raw_ref, - - debug_reflog_iterator_begin, - debug_for_each_reflog_ent, - debug_for_each_reflog_ent_reverse, - debug_reflog_exists, - debug_create_reflog, - debug_delete_reflog, - debug_reflog_expire, + .next = NULL, + .name = "debug", + .init = NULL, + .init_db = debug_init_db, + + /* + * None of these should be NULL. If the "files" backend (in + * "struct ref_storage_be refs_be_files" in files-backend.c) + * has a function we should also have a wrapper for it here. + * Test the output with "GIT_TRACE_REFS=1". + */ + .transaction_prepare = debug_transaction_prepare, + .transaction_finish = debug_transaction_finish, + .transaction_abort = debug_transaction_abort, + .initial_transaction_commit = debug_initial_transaction_commit, + + .pack_refs = debug_pack_refs, + .create_symref = debug_create_symref, + .delete_refs = debug_delete_refs, + .rename_ref = debug_rename_ref, + .copy_ref = debug_copy_ref, + + .iterator_begin = debug_ref_iterator_begin, + .read_raw_ref = debug_read_raw_ref, + .read_symbolic_ref = debug_read_symbolic_ref, + + .reflog_iterator_begin = debug_reflog_iterator_begin, + .for_each_reflog_ent = debug_for_each_reflog_ent, + .for_each_reflog_ent_reverse = debug_for_each_reflog_ent_reverse, + .reflog_exists = debug_reflog_exists, + .create_reflog = debug_create_reflog, + .delete_reflog = debug_delete_reflog, + .reflog_expire = debug_reflog_expire, }; diff --git a/refs/files-backend.c b/refs/files-backend.c index f59589d6cc..95acab78ee 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -338,9 +338,9 @@ static struct ref_cache *get_loose_ref_cache(struct files_ref_store *refs) return refs->loose; } -static int files_read_raw_ref(struct ref_store *ref_store, const char *refname, - struct object_id *oid, struct strbuf *referent, - unsigned int *type, int *failure_errno) +static int read_ref_internal(struct ref_store *ref_store, const char *refname, + struct object_id *oid, struct strbuf *referent, + unsigned int *type, int *failure_errno, int skip_packed_refs) { struct files_ref_store *refs = files_downcast(ref_store, REF_STORE_READ, "read_raw_ref"); @@ -381,7 +381,7 @@ stat_ref: if (lstat(path, &st) < 0) { int ignore_errno; myerr = errno; - if (myerr != ENOENT) + if (myerr != ENOENT || skip_packed_refs) goto out; if (refs_read_raw_ref(refs->packed_ref_store, refname, oid, referent, type, &ignore_errno)) { @@ -425,7 +425,8 @@ stat_ref: * ref is supposed to be, there could still be a * packed ref: */ - if (refs_read_raw_ref(refs->packed_ref_store, refname, oid, + if (skip_packed_refs || + refs_read_raw_ref(refs->packed_ref_store, refname, oid, referent, type, &ignore_errno)) { myerr = EISDIR; goto out; @@ -470,6 +471,27 @@ out: return ret; } +static int files_read_raw_ref(struct ref_store *ref_store, const char *refname, + struct object_id *oid, struct strbuf *referent, + unsigned int *type, int *failure_errno) +{ + return read_ref_internal(ref_store, refname, oid, referent, type, failure_errno, 0); +} + +static int files_read_symbolic_ref(struct ref_store *ref_store, const char *refname, + struct strbuf *referent) +{ + struct object_id oid; + int failure_errno, ret; + unsigned int type; + + ret = read_ref_internal(ref_store, refname, &oid, referent, &type, &failure_errno, 1); + if (ret) + return ret; + + return !(type & REF_ISSYMREF); +} + int parse_loose_ref_contents(const char *buf, struct object_id *oid, struct strbuf *referent, unsigned int *type, int *failure_errno) @@ -800,9 +822,9 @@ static int files_ref_iterator_abort(struct ref_iterator *ref_iterator) } static struct ref_iterator_vtable files_ref_iterator_vtable = { - files_ref_iterator_advance, - files_ref_iterator_peel, - files_ref_iterator_abort + .advance = files_ref_iterator_advance, + .peel = files_ref_iterator_peel, + .abort = files_ref_iterator_abort, }; static struct ref_iterator *files_ref_iterator_begin( @@ -1787,6 +1809,7 @@ static int write_ref_to_lockfile(struct ref_lock *lock, fd = get_lock_file_fd(&lock->lk); if (write_in_full(fd, oid_to_hex(oid), the_hash_algo->hexsz) < 0 || write_in_full(fd, &term, 1) < 0 || + fsync_component(FSYNC_COMPONENT_REFERENCE, get_lock_file_fd(&lock->lk)) < 0 || close_ref_gently(lock) < 0) { strbuf_addf(err, "couldn't write '%s'", get_lock_file_path(&lock->lk)); @@ -2209,9 +2232,9 @@ static int files_reflog_iterator_abort(struct ref_iterator *ref_iterator) } static struct ref_iterator_vtable files_reflog_iterator_vtable = { - files_reflog_iterator_advance, - files_reflog_iterator_peel, - files_reflog_iterator_abort + .advance = files_reflog_iterator_advance, + .peel = files_reflog_iterator_peel, + .abort = files_reflog_iterator_abort, }; static struct ref_iterator *reflog_iterator_begin(struct ref_store *ref_store, @@ -3269,29 +3292,30 @@ static int files_init_db(struct ref_store *ref_store, struct strbuf *err) } struct ref_storage_be refs_be_files = { - NULL, - "files", - files_ref_store_create, - files_init_db, - files_transaction_prepare, - files_transaction_finish, - files_transaction_abort, - files_initial_transaction_commit, - - files_pack_refs, - files_create_symref, - files_delete_refs, - files_rename_ref, - files_copy_ref, - - files_ref_iterator_begin, - files_read_raw_ref, - - 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 + .next = NULL, + .name = "files", + .init = files_ref_store_create, + .init_db = files_init_db, + .transaction_prepare = files_transaction_prepare, + .transaction_finish = files_transaction_finish, + .transaction_abort = files_transaction_abort, + .initial_transaction_commit = files_initial_transaction_commit, + + .pack_refs = files_pack_refs, + .create_symref = files_create_symref, + .delete_refs = files_delete_refs, + .rename_ref = files_rename_ref, + .copy_ref = files_copy_ref, + + .iterator_begin = files_ref_iterator_begin, + .read_raw_ref = files_read_raw_ref, + .read_symbolic_ref = files_read_symbolic_ref, + + .reflog_iterator_begin = files_reflog_iterator_begin, + .for_each_reflog_ent = files_for_each_reflog_ent, + .for_each_reflog_ent_reverse = files_for_each_reflog_ent_reverse, + .reflog_exists = files_reflog_exists, + .create_reflog = files_create_reflog, + .delete_reflog = files_delete_reflog, + .reflog_expire = files_reflog_expire }; diff --git a/refs/iterator.c b/refs/iterator.c index a89d132d4f..b2e56bae1c 100644 --- a/refs/iterator.c +++ b/refs/iterator.c @@ -64,9 +64,9 @@ static int empty_ref_iterator_abort(struct ref_iterator *ref_iterator) } static struct ref_iterator_vtable empty_ref_iterator_vtable = { - empty_ref_iterator_advance, - empty_ref_iterator_peel, - empty_ref_iterator_abort + .advance = empty_ref_iterator_advance, + .peel = empty_ref_iterator_peel, + .abort = empty_ref_iterator_abort, }; struct ref_iterator *empty_ref_iterator_begin(void) @@ -201,9 +201,9 @@ static int merge_ref_iterator_abort(struct ref_iterator *ref_iterator) } static struct ref_iterator_vtable merge_ref_iterator_vtable = { - merge_ref_iterator_advance, - merge_ref_iterator_peel, - merge_ref_iterator_abort + .advance = merge_ref_iterator_advance, + .peel = merge_ref_iterator_peel, + .abort = merge_ref_iterator_abort, }; struct ref_iterator *merge_ref_iterator_begin( @@ -378,9 +378,9 @@ static int prefix_ref_iterator_abort(struct ref_iterator *ref_iterator) } static struct ref_iterator_vtable prefix_ref_iterator_vtable = { - prefix_ref_iterator_advance, - prefix_ref_iterator_peel, - prefix_ref_iterator_abort + .advance = prefix_ref_iterator_advance, + .peel = prefix_ref_iterator_peel, + .abort = prefix_ref_iterator_abort, }; struct ref_iterator *prefix_ref_iterator_begin(struct ref_iterator *iter0, diff --git a/refs/packed-backend.c b/refs/packed-backend.c index 27dd8c3922..66c4574c99 100644 --- a/refs/packed-backend.c +++ b/refs/packed-backend.c @@ -911,9 +911,9 @@ static int packed_ref_iterator_abort(struct ref_iterator *ref_iterator) } static struct ref_iterator_vtable packed_ref_iterator_vtable = { - packed_ref_iterator_advance, - packed_ref_iterator_peel, - packed_ref_iterator_abort + .advance = packed_ref_iterator_advance, + .peel = packed_ref_iterator_peel, + .abort = packed_ref_iterator_abort }; static struct ref_iterator *packed_ref_iterator_begin( @@ -1262,7 +1262,8 @@ static int write_with_updates(struct packed_ref_store *refs, goto error; } - if (close_tempfile_gently(refs->tempfile)) { + if (fsync_component(FSYNC_COMPONENT_REFERENCE, get_tempfile_fd(refs->tempfile)) || + close_tempfile_gently(refs->tempfile)) { strbuf_addf(err, "error closing file %s: %s", get_tempfile_path(refs->tempfile), strerror(errno)); @@ -1591,105 +1592,36 @@ static int packed_pack_refs(struct ref_store *ref_store, unsigned int flags) return 0; } -static int packed_create_symref(struct ref_store *ref_store, - const char *refname, const char *target, - const char *logmsg) -{ - BUG("packed reference store does not support symrefs"); -} - -static int packed_rename_ref(struct ref_store *ref_store, - const char *oldrefname, const char *newrefname, - const char *logmsg) -{ - BUG("packed reference store does not support renaming references"); -} - -static int packed_copy_ref(struct ref_store *ref_store, - const char *oldrefname, const char *newrefname, - const char *logmsg) -{ - BUG("packed reference store does not support copying references"); -} - static struct ref_iterator *packed_reflog_iterator_begin(struct ref_store *ref_store) { return empty_ref_iterator_begin(); } -static int packed_for_each_reflog_ent(struct ref_store *ref_store, - const char *refname, - each_reflog_ent_fn fn, void *cb_data) -{ - BUG("packed reference store does not support reflogs"); - return 0; -} - -static int packed_for_each_reflog_ent_reverse(struct ref_store *ref_store, - const char *refname, - each_reflog_ent_fn fn, - void *cb_data) -{ - BUG("packed reference store does not support reflogs"); - return 0; -} - -static int packed_reflog_exists(struct ref_store *ref_store, - const char *refname) -{ - BUG("packed reference store does not support reflogs"); - return 0; -} - -static int packed_create_reflog(struct ref_store *ref_store, - const char *refname, struct strbuf *err) -{ - BUG("packed reference store does not support reflogs"); -} - -static int packed_delete_reflog(struct ref_store *ref_store, - const char *refname) -{ - BUG("packed reference store does not support reflogs"); - return 0; -} - -static int packed_reflog_expire(struct ref_store *ref_store, - const char *refname, - 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) -{ - BUG("packed reference store does not support reflogs"); - return 0; -} - struct ref_storage_be refs_be_packed = { - NULL, - "packed", - packed_ref_store_create, - packed_init_db, - packed_transaction_prepare, - packed_transaction_finish, - packed_transaction_abort, - packed_initial_transaction_commit, - - packed_pack_refs, - packed_create_symref, - packed_delete_refs, - packed_rename_ref, - packed_copy_ref, - - packed_ref_iterator_begin, - packed_read_raw_ref, - - packed_reflog_iterator_begin, - packed_for_each_reflog_ent, - packed_for_each_reflog_ent_reverse, - packed_reflog_exists, - packed_create_reflog, - packed_delete_reflog, - packed_reflog_expire + .next = NULL, + .name = "packed", + .init = packed_ref_store_create, + .init_db = packed_init_db, + .transaction_prepare = packed_transaction_prepare, + .transaction_finish = packed_transaction_finish, + .transaction_abort = packed_transaction_abort, + .initial_transaction_commit = packed_initial_transaction_commit, + + .pack_refs = packed_pack_refs, + .create_symref = NULL, + .delete_refs = packed_delete_refs, + .rename_ref = NULL, + .copy_ref = NULL, + + .iterator_begin = packed_ref_iterator_begin, + .read_raw_ref = packed_read_raw_ref, + .read_symbolic_ref = NULL, + + .reflog_iterator_begin = packed_reflog_iterator_begin, + .for_each_reflog_ent = NULL, + .for_each_reflog_ent_reverse = NULL, + .reflog_exists = NULL, + .create_reflog = NULL, + .delete_reflog = NULL, + .reflog_expire = NULL, }; diff --git a/refs/ref-cache.c b/refs/ref-cache.c index be4aa5e098..3080ef944d 100644 --- a/refs/ref-cache.c +++ b/refs/ref-cache.c @@ -456,9 +456,9 @@ static int cache_ref_iterator_abort(struct ref_iterator *ref_iterator) } static struct ref_iterator_vtable cache_ref_iterator_vtable = { - cache_ref_iterator_advance, - cache_ref_iterator_peel, - cache_ref_iterator_abort + .advance = cache_ref_iterator_advance, + .peel = cache_ref_iterator_peel, + .abort = cache_ref_iterator_abort }; struct ref_iterator *cache_ref_iterator_begin(struct ref_cache *cache, diff --git a/refs/refs-internal.h b/refs/refs-internal.h index 6e15db3ca4..001ef15835 100644 --- a/refs/refs-internal.h +++ b/refs/refs-internal.h @@ -649,6 +649,21 @@ typedef int read_raw_ref_fn(struct ref_store *ref_store, const char *refname, struct object_id *oid, struct strbuf *referent, unsigned int *type, int *failure_errno); +/* + * Read a symbolic reference from the specified reference store. This function + * is optional: if not implemented by a backend, then `read_raw_ref_fn` is used + * to read the symbolcic reference instead. It is intended to be implemented + * only in case the backend can optimize the reading of symbolic references. + * + * Return 0 on success, or -1 on failure. `referent` will be set to the target + * of the symbolic reference on success. This function explicitly does not + * distinguish between error cases and the reference not being a symbolic + * reference to allow backends to optimize this operation in case symbolic and + * non-symbolic references are treated differently. + */ +typedef int read_symbolic_ref_fn(struct ref_store *ref_store, const char *refname, + struct strbuf *referent); + struct ref_storage_be { struct ref_storage_be *next; const char *name; @@ -668,6 +683,7 @@ struct ref_storage_be { ref_iterator_begin_fn *iterator_begin; read_raw_ref_fn *read_raw_ref; + read_symbolic_ref_fn *read_symbolic_ref; reflog_iterator_begin_fn *reflog_iterator_begin; for_each_reflog_ent_fn *for_each_reflog_ent; |