X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=remote.c;h=ff2c8021678fee5ef12060d35c6eb1960e8792c7;hb=3b6121f69b2a27c3bbff5cc3056c30b15394441b;hp=7c496f981e89ee2833214f27dcd94a86976f9e67;hpb=a83619d692deeb2565335144078465acb2dd1457;p=git.git diff --git a/remote.c b/remote.c index 7c496f981..ff2c80216 100644 --- a/remote.c +++ b/remote.c @@ -2,6 +2,16 @@ #include "remote.h" #include "refs.h" +static struct refspec s_tag_refspec = { + 0, + 1, + 0, + "refs/tags/", + "refs/tags/" +}; + +const struct refspec *tag_refspec = &s_tag_refspec; + struct counted_string { size_t len; const char *s; @@ -288,7 +298,7 @@ static void read_branches_file(struct remote *remote) remote->fetch_tags = 1; /* always auto-follow */ } -static int handle_config(const char *key, const char *value) +static int handle_config(const char *key, const char *value, void *cb) { const char *name; const char *subkey; @@ -337,44 +347,49 @@ static int handle_config(const char *key, const char *value) return 0; } remote = make_remote(name, subkey - name); - if (!value) { - /* if we ever have a boolean variable, e.g. "remote.*.disabled" - * [remote "frotz"] - * disabled - * is a valid way to set it to true; we get NULL in value so - * we need to handle it here. - * - * if (!strcmp(subkey, ".disabled")) { - * val = git_config_bool(key, value); - * return 0; - * } else - * - */ - return 0; /* ignore unknown booleans */ - } - if (!strcmp(subkey, ".url")) { - add_url(remote, xstrdup(value)); + if (!strcmp(subkey, ".mirror")) + remote->mirror = git_config_bool(key, value); + else if (!strcmp(subkey, ".skipdefaultupdate")) + remote->skip_default_update = git_config_bool(key, value); + + else if (!strcmp(subkey, ".url")) { + const char *v; + if (git_config_string(&v, key, value)) + return -1; + add_url(remote, v); } else if (!strcmp(subkey, ".push")) { - add_push_refspec(remote, xstrdup(value)); + const char *v; + if (git_config_string(&v, key, value)) + return -1; + add_push_refspec(remote, v); } else if (!strcmp(subkey, ".fetch")) { - add_fetch_refspec(remote, xstrdup(value)); + const char *v; + if (git_config_string(&v, key, value)) + return -1; + add_fetch_refspec(remote, v); } else if (!strcmp(subkey, ".receivepack")) { + const char *v; + if (git_config_string(&v, key, value)) + return -1; if (!remote->receivepack) - remote->receivepack = xstrdup(value); + remote->receivepack = v; else error("more than one receivepack given, using the first"); } else if (!strcmp(subkey, ".uploadpack")) { + const char *v; + if (git_config_string(&v, key, value)) + return -1; if (!remote->uploadpack) - remote->uploadpack = xstrdup(value); + remote->uploadpack = v; else error("more than one uploadpack given, using the first"); } else if (!strcmp(subkey, ".tagopt")) { if (!strcmp(value, "--no-tags")) remote->fetch_tags = -1; } else if (!strcmp(subkey, ".proxy")) { - remote->http_proxy = xstrdup(value); - } else if (!strcmp(subkey, ".skipdefaultupdate")) - remote->skip_default_update = 1; + return git_config_string((const char **)&remote->http_proxy, + key, value); + } return 0; } @@ -405,7 +420,7 @@ static void read_config(void) current_branch = make_branch(head_ref + strlen("refs/heads/"), 0); } - git_config(handle_config); + git_config(handle_config, NULL); alias_all_urls(); } @@ -696,6 +711,13 @@ struct ref *alloc_ref(unsigned namelen) return ret; } +struct ref *alloc_ref_from_str(const char* str) +{ + struct ref *ret = alloc_ref(strlen(str) + 1); + strcpy(ret->name, str); + return ret; +} + static struct ref *copy_ref(const struct ref *ref) { struct ref *ret = xmalloc(sizeof(struct ref) + strlen(ref->name) + 1); @@ -716,13 +738,22 @@ struct ref *copy_ref_list(const struct ref *ref) return ret; } +void free_ref(struct ref *ref) +{ + if (!ref) + return; + free(ref->remote_status); + free(ref->symref); + free(ref); +} + void free_refs(struct ref *ref) { struct ref *next; while (ref) { next = ref->next; free(ref->peer_ref); - free(ref); + free_ref(ref); ref = next; } } @@ -793,7 +824,6 @@ static struct ref *try_explicit_object_name(const char *name) { unsigned char sha1[20]; struct ref *ref; - int len; if (!*name) { ref = alloc_ref(20); @@ -803,21 +833,14 @@ static struct ref *try_explicit_object_name(const char *name) } if (get_sha1(name, sha1)) return NULL; - len = strlen(name) + 1; - ref = alloc_ref(len); - memcpy(ref->name, name, len); + ref = alloc_ref_from_str(name); hashcpy(ref->new_sha1, sha1); return ref; } static struct ref *make_linked_ref(const char *name, struct ref ***tail) { - struct ref *ret; - size_t len; - - len = strlen(name) + 1; - ret = alloc_ref(len); - memcpy(ret->name, name, len); + struct ref *ret = alloc_ref_from_str(name); tail_link_ref(ret, tail); return ret; } @@ -844,8 +867,7 @@ static char *guess_ref(const char *name, struct ref *peer) static int match_explicit(struct ref *src, struct ref *dst, struct ref ***dst_tail, - struct refspec *rs, - int errs) + struct refspec *rs) { struct ref *matched_src, *matched_dst; @@ -853,7 +875,7 @@ static int match_explicit(struct ref *src, struct ref *dst, char *dst_guess; if (rs->pattern || rs->matching) - return errs; + return 0; matched_src = matched_dst = NULL; switch (count_refspec_match(rs->src, src, &matched_src)) { @@ -866,23 +888,16 @@ static int match_explicit(struct ref *src, struct ref *dst, */ matched_src = try_explicit_object_name(rs->src); if (!matched_src) - error("src refspec %s does not match any.", rs->src); + return error("src refspec %s does not match any.", rs->src); break; default: - matched_src = NULL; - error("src refspec %s matches more than one.", rs->src); - break; + return error("src refspec %s matches more than one.", rs->src); } - if (!matched_src) - errs = 1; - if (!dst_value) { unsigned char sha1[20]; int flag; - if (!matched_src) - return errs; dst_value = resolve_ref(matched_src->name, sha1, 1, &flag); if (!dst_value || ((flag & REF_ISSYMREF) && @@ -913,18 +928,16 @@ static int match_explicit(struct ref *src, struct ref *dst, dst_value); break; } - if (errs || !matched_dst) - return 1; - if (matched_dst->peer_ref) { - errs = 1; - error("dst ref %s receives from more than one src.", + if (!matched_dst) + return -1; + if (matched_dst->peer_ref) + return error("dst ref %s receives from more than one src.", matched_dst->name); - } else { matched_dst->peer_ref = matched_src; matched_dst->force = rs->force; } - return errs; + return 0; } static int match_explicit_refs(struct ref *src, struct ref *dst, @@ -933,8 +946,8 @@ static int match_explicit_refs(struct ref *src, struct ref *dst, { int i, errs; for (i = errs = 0; i < rs_nr; i++) - errs |= match_explicit(src, dst, dst_tail, &rs[i], errs); - return -errs; + errs += match_explicit(src, dst, dst_tail, &rs[i]); + return errs; } static const struct refspec *check_pattern_match(const struct refspec *rs, @@ -1138,9 +1151,7 @@ static struct ref *get_local_ref(const char *name) return NULL; if (!prefixcmp(name, "refs/")) { - ret = alloc_ref(strlen(name) + 1); - strcpy(ret->name, name); - return ret; + return alloc_ref_from_str(name); } if (!prefixcmp(name, "heads/") || @@ -1199,3 +1210,15 @@ int get_fetch_map(const struct ref *remote_refs, return 0; } + +int resolve_remote_symref(struct ref *ref, struct ref *list) +{ + if (!ref->symref) + return 0; + for (; list; list = list->next) + if (!strcmp(ref->symref, list->name)) { + hashcpy(ref->old_sha1, list->old_sha1); + return 0; + } + return 1; +}