diff options
Diffstat (limited to 'builtin/fetch.c')
| -rw-r--r-- | builtin/fetch.c | 99 |
1 files changed, 63 insertions, 36 deletions
diff --git a/builtin/fetch.c b/builtin/fetch.c index 159fb7e916..9a3869f4ff 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -11,7 +11,7 @@ #include "run-command.h" #include "parse-options.h" #include "sigchain.h" -#include "transport.h" +#include "submodule-config.h" #include "submodule.h" #include "connected.h" #include "argv-array.h" @@ -68,7 +68,7 @@ static int git_fetch_config(const char *k, const char *v, void *cb) fetch_prune_config = git_config_bool(k, v); return 0; } - return 0; + return git_default_config(k, v, cb); } static int parse_refmap_arg(const struct option *opt, const char *arg, int unset) @@ -180,13 +180,15 @@ static void add_merge_config(struct ref **head, } } -static int add_existing(const char *refname, const unsigned char *sha1, +static int add_existing(const char *refname, const struct object_id *oid, int flag, void *cbdata) { struct string_list *list = (struct string_list *)cbdata; struct string_list_item *item = string_list_insert(list, refname); - item->util = xmalloc(20); - hashcpy(item->util, sha1); + struct object_id *old_oid = xmalloc(sizeof(*old_oid)); + + oidcpy(old_oid, oid); + item->util = old_oid; return 0; } @@ -404,23 +406,39 @@ static int s_update_ref(const char *action, { char msg[1024]; char *rla = getenv("GIT_REFLOG_ACTION"); - static struct ref_lock *lock; + struct ref_transaction *transaction; + struct strbuf err = STRBUF_INIT; + int ret, df_conflict = 0; if (dry_run) return 0; if (!rla) rla = default_rla.buf; snprintf(msg, sizeof(msg), "%s: %s", rla, action); - lock = lock_any_ref_for_update(ref->name, - check_old ? ref->old_sha1 : NULL, - 0, NULL); - if (!lock) - return errno == ENOTDIR ? STORE_REF_ERROR_DF_CONFLICT : - STORE_REF_ERROR_OTHER; - if (write_ref_sha1(lock, ref->new_sha1, msg) < 0) - return errno == ENOTDIR ? STORE_REF_ERROR_DF_CONFLICT : - STORE_REF_ERROR_OTHER; + + transaction = ref_transaction_begin(&err); + if (!transaction || + ref_transaction_update(transaction, ref->name, + ref->new_sha1, + check_old ? ref->old_sha1 : NULL, + 0, msg, &err)) + goto fail; + + ret = ref_transaction_commit(transaction, &err); + if (ret) { + df_conflict = (ret == TRANSACTION_NAME_CONFLICT); + goto fail; + } + + ref_transaction_free(transaction); + strbuf_release(&err); return 0; +fail: + ref_transaction_free(transaction); + error("%s", err.buf); + strbuf_release(&err); + return df_conflict ? STORE_REF_ERROR_DF_CONFLICT + : STORE_REF_ERROR_OTHER; } #define REFCOL_WIDTH 10 @@ -573,7 +591,8 @@ static int store_updated_refs(const char *raw_url, const char *remote_name, struct strbuf note = STRBUF_INIT; const char *what, *kind; struct ref *rm; - char *url, *filename = dry_run ? "/dev/null" : git_path("FETCH_HEAD"); + char *url; + const char *filename = dry_run ? "/dev/null" : git_path_fetch_head(); int want_status; fp = fopen(filename, "a"); @@ -772,20 +791,29 @@ static int prune_refs(struct refspec *refs, int ref_count, struct ref *ref_map, if (4 < i && !strncmp(".git", url + i - 3, 4)) url_len = i - 3; - for (ref = stale_refs; ref; ref = ref->next) { - if (!dry_run) - result |= delete_ref(ref->name, NULL, 0); - if (verbosity >= 0 && !shown_url) { - fprintf(stderr, _("From %.*s\n"), url_len, url); - shown_url = 1; - } - if (verbosity >= 0) { + if (!dry_run) { + struct string_list refnames = STRING_LIST_INIT_NODUP; + + for (ref = stale_refs; ref; ref = ref->next) + string_list_append(&refnames, ref->name); + + result = delete_refs(&refnames); + string_list_clear(&refnames, 0); + } + + if (verbosity >= 0) { + for (ref = stale_refs; ref; ref = ref->next) { + if (!shown_url) { + fprintf(stderr, _("From %.*s\n"), url_len, url); + shown_url = 1; + } fprintf(stderr, " x %-*s %-*s -> %s\n", TRANSPORT_SUMMARY(_("[deleted]")), REFCOL_WIDTH, _("(none)"), prettify_refname(ref->name)); warn_dangling_symref(stderr, dangling_msg, ref->name); } } + free(url); free_refs(stale_refs); return result; @@ -807,7 +835,7 @@ static void check_not_current_branch(struct ref *ref_map) static int truncate_fetch_head(void) { - char *filename = git_path("FETCH_HEAD"); + const char *filename = git_path_fetch_head(); FILE *fp = fopen(filename, "w"); if (!fp) @@ -897,9 +925,10 @@ static int do_fetch(struct transport *transport, struct string_list_item *peer_item = string_list_lookup(&existing_refs, rm->peer_ref->name); - if (peer_item) - hashcpy(rm->peer_ref->old_sha1, - peer_item->util); + if (peer_item) { + struct object_id *old_oid = peer_item->util; + hashcpy(rm->peer_ref->old_sha1, old_oid->hash); + } } } @@ -960,17 +989,15 @@ static int get_remote_group(const char *key, const char *value, void *priv) { struct remote_group_data *g = priv; - if (starts_with(key, "remotes.") && - !strcmp(key + 8, g->name)) { + if (skip_prefix(key, "remotes.", &key) && !strcmp(key, g->name)) { /* split list by white space */ - int space = strcspn(value, " \t\n"); while (*value) { - if (space > 1) { + size_t wordlen = strcspn(value, " \t\n"); + + if (wordlen >= 1) string_list_append(g->list, - xstrndup(value, space)); - } - value += space + (value[space] != '\0'); - space = strcspn(value, " \t\n"); + xstrndup(value, wordlen)); + value += wordlen + (value[wordlen] != '\0'); } } |
