From: Junio C Hamano Date: Tue, 28 Mar 2017 21:05:59 +0000 (-0700) Subject: Merge branch 'sg/skip-prefix-in-prettify-refname' X-Git-Tag: v2.13.0-rc0~55 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/f4948902923685134bc01292f2c97315eab6c82a?ds=inline;hp=-c Merge branch 'sg/skip-prefix-in-prettify-refname' Code cleanup. * sg/skip-prefix-in-prettify-refname: refs.c: use skip_prefix() in prettify_refname() --- f4948902923685134bc01292f2c97315eab6c82a diff --combined refs.c index e7606716dd,49a7e703d5..0272e332cc --- a/refs.c +++ b/refs.c @@@ -3,32 -3,12 +3,32 @@@ */ #include "cache.h" +#include "hashmap.h" #include "lockfile.h" #include "refs.h" #include "refs/refs-internal.h" #include "object.h" #include "tag.h" +/* + * List of all available backends + */ +static struct ref_storage_be *refs_backends = &refs_be_files; + +static struct ref_storage_be *find_ref_storage_backend(const char *name) +{ + struct ref_storage_be *be; + for (be = refs_backends; be; be = be->next) + if (!strcmp(be->name, name)) + return be; + return NULL; +} + +int ref_storage_backend_exists(const char *name) +{ + return find_ref_storage_backend(name) != NULL; +} + /* * How to handle various characters in refnames: * 0: An acceptable character for refs @@@ -366,11 -346,11 +366,11 @@@ int for_each_glob_ref(each_ref_fn fn, c const char *prettify_refname(const char *name) { - return name + ( - starts_with(name, "refs/heads/") ? 11 : - starts_with(name, "refs/tags/") ? 10 : - starts_with(name, "refs/remotes/") ? 13 : - 0); + if (skip_prefix(name, "refs/heads/", &name) || + skip_prefix(name, "refs/tags/", &name) || + skip_prefix(name, "refs/remotes/", &name)) + ; /* nothing */ + return name; } static const char *ref_rev_parse_rules[] = { @@@ -405,7 -385,7 +405,7 @@@ int refname_match(const char *abbrev_na static char *substitute_branch_name(const char **string, int *len) { struct strbuf buf = STRBUF_INIT; - int ret = interpret_branch_name(*string, *len, &buf); + int ret = interpret_branch_name(*string, *len, &buf, 0); if (ret == *len) { size_t size; @@@ -420,13 -400,6 +420,13 @@@ int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref) { char *last_branch = substitute_branch_name(&str, &len); + int refs_found = expand_ref(str, len, sha1, ref); + free(last_branch); + return refs_found; +} + +int expand_ref(const char *str, int len, unsigned char *sha1, char **ref) +{ const char **p, *r; int refs_found = 0; @@@ -452,6 -425,7 +452,6 @@@ warning("ignoring broken ref %s.", fullref); } } - free(last_branch); return refs_found; } @@@ -592,8 -566,8 +592,8 @@@ static int delete_pseudoref(const char return 0; } -int delete_ref(const char *refname, const unsigned char *old_sha1, - unsigned int flags) +int delete_ref(const char *msg, const char *refname, + const unsigned char *old_sha1, unsigned int flags) { struct ref_transaction *transaction; struct strbuf err = STRBUF_INIT; @@@ -604,7 -578,7 +604,7 @@@ transaction = ref_transaction_begin(&err); if (!transaction || ref_transaction_delete(transaction, refname, old_sha1, - flags, NULL, &err) || + flags, msg, &err) || ref_transaction_commit(transaction, &err)) { error("%s", err.buf); ref_transaction_free(transaction); @@@ -639,17 -613,12 +639,17 @@@ int copy_reflog_msg(char *buf, const ch int should_autocreate_reflog(const char *refname) { - if (!log_all_ref_updates) + switch (log_all_ref_updates) { + case LOG_REFS_ALWAYS: + return 1; + case LOG_REFS_NORMAL: + return starts_with(refname, "refs/heads/") || + starts_with(refname, "refs/remotes/") || + starts_with(refname, "refs/notes/") || + !strcmp(refname, "HEAD"); + default: return 0; - return starts_with(refname, "refs/heads/") || - starts_with(refname, "refs/remotes/") || - starts_with(refname, "refs/notes/") || - !strcmp(refname, "HEAD"); + } } int is_branch(const char *refname) @@@ -675,7 -644,7 +675,7 @@@ struct read_ref_at_cb int *cutoff_cnt; }; -static int read_ref_at_ent(unsigned char *osha1, unsigned char *nsha1, +static int read_ref_at_ent(struct object_id *ooid, struct object_id *noid, const char *email, unsigned long timestamp, int tz, const char *message, void *cb_data) { @@@ -699,30 -668,30 +699,30 @@@ * hold the values for the previous record. */ if (!is_null_sha1(cb->osha1)) { - hashcpy(cb->sha1, nsha1); - if (hashcmp(cb->osha1, nsha1)) + hashcpy(cb->sha1, noid->hash); + if (hashcmp(cb->osha1, noid->hash)) warning("Log for ref %s has gap after %s.", cb->refname, show_date(cb->date, cb->tz, DATE_MODE(RFC2822))); } else if (cb->date == cb->at_time) - hashcpy(cb->sha1, nsha1); - else if (hashcmp(nsha1, cb->sha1)) + hashcpy(cb->sha1, noid->hash); + else if (hashcmp(noid->hash, cb->sha1)) warning("Log for ref %s unexpectedly ended on %s.", cb->refname, show_date(cb->date, cb->tz, DATE_MODE(RFC2822))); - hashcpy(cb->osha1, osha1); - hashcpy(cb->nsha1, nsha1); + hashcpy(cb->osha1, ooid->hash); + hashcpy(cb->nsha1, noid->hash); cb->found_it = 1; return 1; } - hashcpy(cb->osha1, osha1); - hashcpy(cb->nsha1, nsha1); + hashcpy(cb->osha1, ooid->hash); + hashcpy(cb->nsha1, noid->hash); if (cb->cnt > 0) cb->cnt--; return 0; } -static int read_ref_at_ent_oldest(unsigned char *osha1, unsigned char *nsha1, +static int read_ref_at_ent_oldest(struct object_id *ooid, struct object_id *noid, const char *email, unsigned long timestamp, int tz, const char *message, void *cb_data) { @@@ -736,9 -705,9 +736,9 @@@ *cb->cutoff_tz = tz; if (cb->cutoff_cnt) *cb->cutoff_cnt = cb->reccnt; - hashcpy(cb->sha1, osha1); + hashcpy(cb->sha1, ooid->hash); if (is_null_sha1(cb->sha1)) - hashcpy(cb->sha1, nsha1); + hashcpy(cb->sha1, noid->hash); /* We just want the first entry */ return 1; } @@@ -888,14 -857,6 +888,14 @@@ int ref_transaction_verify(struct ref_t flags, NULL, err); } +int update_ref_oid(const char *msg, const char *refname, + const struct object_id *new_oid, const struct object_id *old_oid, + unsigned int flags, enum action_on_err onerr) +{ + return update_ref(msg, refname, new_oid ? new_oid->hash : NULL, + old_oid ? old_oid->hash : NULL, flags, onerr); +} + int update_ref(const char *msg, const char *refname, const unsigned char *new_sha1, const unsigned char *old_sha1, unsigned int flags, enum action_on_err onerr) @@@ -1035,10 -996,10 +1035,10 @@@ static struct string_list *hide_refs int parse_hide_refs_config(const char *var, const char *value, const char *section) { + const char *key; if (!strcmp("transfer.hiderefs", var) || - /* NEEDSWORK: use parse_config_key() once both are merged */ - (starts_with(var, section) && var[strlen(section)] == '.' && - !strcmp(var + strlen(section), ".hiderefs"))) { + (!parse_config_key(var, section, NULL, NULL, &key) && + !strcmp(key, "hiderefs"))) { char *ref; int len; @@@ -1119,20 -1080,20 +1119,20 @@@ const char *find_descendant_ref(const c return NULL; } -int rename_ref_available(const char *oldname, const char *newname) +int rename_ref_available(const char *old_refname, const char *new_refname) { struct string_list skip = STRING_LIST_INIT_NODUP; struct strbuf err = STRBUF_INIT; - int ret; + int ok; - string_list_insert(&skip, oldname); - ret = !verify_refname_available(newname, NULL, &skip, &err); - if (!ret) + string_list_insert(&skip, old_refname); + ok = !verify_refname_available(new_refname, NULL, &skip, &err); + if (!ok) error("%s", err.buf); string_list_clear(&skip, 0); strbuf_release(&err); - return ret; + return ok; } int head_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data) @@@ -1170,13 -1131,9 +1170,13 @@@ int head_ref(each_ref_fn fn, void *cb_d static int do_for_each_ref(const char *submodule, const char *prefix, each_ref_fn fn, int trim, int flags, void *cb_data) { + struct ref_store *refs = get_ref_store(submodule); struct ref_iterator *iter; - iter = files_ref_iterator_begin(submodule, prefix, flags); + if (!refs) + return 0; + + iter = refs->be->iterator_begin(refs, prefix, flags); iter = prefix_ref_iterator_begin(iter, prefix, trim); return do_for_each_ref_iterator(iter, fn, cb_data); @@@ -1235,10 -1192,8 +1235,10 @@@ int for_each_rawref(each_ref_fn fn, voi } /* This function needs to return a meaningful errno on failure */ -const char *resolve_ref_unsafe(const char *refname, int resolve_flags, - unsigned char *sha1, int *flags) +const char *resolve_ref_recursively(struct ref_store *refs, + const char *refname, + int resolve_flags, + unsigned char *sha1, int *flags) { static struct strbuf sb_refname = STRBUF_INIT; int unused_flags; @@@ -1270,8 -1225,7 +1270,8 @@@ for (symref_count = 0; symref_count < SYMREF_MAXDEPTH; symref_count++) { unsigned int read_flags = 0; - if (read_raw_ref(refname, sha1, &sb_refname, &read_flags)) { + if (refs->be->read_raw_ref(refs, refname, + sha1, &sb_refname, &read_flags)) { *flags |= read_flags; if (errno != ENOENT || (resolve_flags & RESOLVE_REF_READING)) return NULL; @@@ -1310,306 -1264,3 +1310,306 @@@ errno = ELOOP; return NULL; } + +/* backend functions */ +int refs_init_db(struct strbuf *err) +{ + struct ref_store *refs = get_ref_store(NULL); + + return refs->be->init_db(refs, err); +} + +const char *resolve_ref_unsafe(const char *refname, int resolve_flags, + unsigned char *sha1, int *flags) +{ + return resolve_ref_recursively(get_ref_store(NULL), refname, + resolve_flags, sha1, flags); +} + +int resolve_gitlink_ref(const char *submodule, const char *refname, + unsigned char *sha1) +{ + size_t len = strlen(submodule); + struct ref_store *refs; + int flags; + + while (len && submodule[len - 1] == '/') + len--; + + if (!len) + return -1; + + if (submodule[len]) { + /* We need to strip off one or more trailing slashes */ + char *stripped = xmemdupz(submodule, len); + + refs = get_ref_store(stripped); + free(stripped); + } else { + refs = get_ref_store(submodule); + } + + if (!refs) + return -1; + + if (!resolve_ref_recursively(refs, refname, 0, sha1, &flags) || + is_null_sha1(sha1)) + return -1; + return 0; +} + +struct submodule_hash_entry +{ + struct hashmap_entry ent; /* must be the first member! */ + + struct ref_store *refs; + + /* NUL-terminated name of submodule: */ + char submodule[FLEX_ARRAY]; +}; + +static int submodule_hash_cmp(const void *entry, const void *entry_or_key, + const void *keydata) +{ + const struct submodule_hash_entry *e1 = entry, *e2 = entry_or_key; + const char *submodule = keydata ? keydata : e2->submodule; + + return strcmp(e1->submodule, submodule); +} + +static struct submodule_hash_entry *alloc_submodule_hash_entry( + const char *submodule, struct ref_store *refs) +{ + struct submodule_hash_entry *entry; + + FLEX_ALLOC_STR(entry, submodule, submodule); + hashmap_entry_init(entry, strhash(submodule)); + entry->refs = refs; + return entry; +} + +/* A pointer to the ref_store for the main repository: */ +static struct ref_store *main_ref_store; + +/* A hashmap of ref_stores, stored by submodule name: */ +static struct hashmap submodule_ref_stores; + +/* + * Return the ref_store instance for the specified submodule (or the + * main repository if submodule is NULL). If that ref_store hasn't + * been initialized yet, return NULL. + */ +static struct ref_store *lookup_ref_store(const char *submodule) +{ + struct submodule_hash_entry *entry; + + if (!submodule) + return main_ref_store; + + if (!submodule_ref_stores.tablesize) + /* It's initialized on demand in register_ref_store(). */ + return NULL; + + entry = hashmap_get_from_hash(&submodule_ref_stores, + strhash(submodule), submodule); + return entry ? entry->refs : NULL; +} + +/* + * Register the specified ref_store to be the one that should be used + * for submodule (or the main repository if submodule is NULL). It is + * a fatal error to call this function twice for the same submodule. + */ +static void register_ref_store(struct ref_store *refs, const char *submodule) +{ + if (!submodule) { + if (main_ref_store) + die("BUG: main_ref_store initialized twice"); + + main_ref_store = refs; + } else { + if (!submodule_ref_stores.tablesize) + hashmap_init(&submodule_ref_stores, submodule_hash_cmp, 0); + + if (hashmap_put(&submodule_ref_stores, + alloc_submodule_hash_entry(submodule, refs))) + die("BUG: ref_store for submodule '%s' initialized twice", + submodule); + } +} + +/* + * Create, record, and return a ref_store instance for the specified + * submodule (or the main repository if submodule is NULL). + */ +static struct ref_store *ref_store_init(const char *submodule) +{ + const char *be_name = "files"; + struct ref_storage_be *be = find_ref_storage_backend(be_name); + struct ref_store *refs; + + if (!be) + die("BUG: reference backend %s is unknown", be_name); + + refs = be->init(submodule); + register_ref_store(refs, submodule); + return refs; +} + +struct ref_store *get_ref_store(const char *submodule) +{ + struct ref_store *refs; + + if (!submodule || !*submodule) { + refs = lookup_ref_store(NULL); + + if (!refs) + refs = ref_store_init(NULL); + } else { + 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 = ref_store_init(submodule); + strbuf_release(&submodule_sb); + } + } + + return refs; +} + +void base_ref_store_init(struct ref_store *refs, + const struct ref_storage_be *be) +{ + refs->be = be; +} + +/* backend functions */ +int pack_refs(unsigned int flags) +{ + struct ref_store *refs = get_ref_store(NULL); + + return refs->be->pack_refs(refs, flags); +} + +int peel_ref(const char *refname, unsigned char *sha1) +{ + struct ref_store *refs = get_ref_store(NULL); + + return refs->be->peel_ref(refs, refname, sha1); +} + +int create_symref(const char *ref_target, const char *refs_heads_master, + const char *logmsg) +{ + struct ref_store *refs = get_ref_store(NULL); + + return refs->be->create_symref(refs, ref_target, refs_heads_master, + logmsg); +} + +int ref_transaction_commit(struct ref_transaction *transaction, + struct strbuf *err) +{ + struct ref_store *refs = get_ref_store(NULL); + + return refs->be->transaction_commit(refs, transaction, err); +} + +int verify_refname_available(const char *refname, + const struct string_list *extra, + const struct string_list *skip, + struct strbuf *err) +{ + struct ref_store *refs = get_ref_store(NULL); + + return refs->be->verify_refname_available(refs, refname, extra, skip, err); +} + +int for_each_reflog(each_ref_fn fn, void *cb_data) +{ + struct ref_store *refs = get_ref_store(NULL); + struct ref_iterator *iter; + + iter = refs->be->reflog_iterator_begin(refs); + + return do_for_each_ref_iterator(iter, fn, cb_data); +} + +int for_each_reflog_ent_reverse(const char *refname, each_reflog_ent_fn fn, + void *cb_data) +{ + struct ref_store *refs = get_ref_store(NULL); + + return refs->be->for_each_reflog_ent_reverse(refs, refname, + fn, cb_data); +} + +int for_each_reflog_ent(const char *refname, each_reflog_ent_fn fn, + void *cb_data) +{ + struct ref_store *refs = get_ref_store(NULL); + + return refs->be->for_each_reflog_ent(refs, refname, fn, cb_data); +} + +int reflog_exists(const char *refname) +{ + struct ref_store *refs = get_ref_store(NULL); + + return refs->be->reflog_exists(refs, refname); +} + +int safe_create_reflog(const char *refname, int force_create, + struct strbuf *err) +{ + struct ref_store *refs = get_ref_store(NULL); + + return refs->be->create_reflog(refs, refname, force_create, err); +} + +int delete_reflog(const char *refname) +{ + struct ref_store *refs = get_ref_store(NULL); + + return refs->be->delete_reflog(refs, refname); +} + +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) +{ + struct ref_store *refs = get_ref_store(NULL); + + return refs->be->reflog_expire(refs, refname, sha1, flags, + prepare_fn, should_prune_fn, + cleanup_fn, policy_cb_data); +} + +int initial_ref_transaction_commit(struct ref_transaction *transaction, + struct strbuf *err) +{ + struct ref_store *refs = get_ref_store(NULL); + + return refs->be->initial_transaction_commit(refs, transaction, err); +} + +int delete_refs(struct string_list *refnames, unsigned int flags) +{ + struct ref_store *refs = get_ref_store(NULL); + + return refs->be->delete_refs(refs, refnames, flags); +} + +int rename_ref(const char *oldref, const char *newref, const char *logmsg) +{ + struct ref_store *refs = get_ref_store(NULL); + + return refs->be->rename_ref(refs, oldref, newref, logmsg); +}