From: Junio C Hamano Date: Sun, 8 Mar 2009 08:12:33 +0000 (-0800) Subject: Adjust js/remote-improvements and db/refspec-wildcard-in-the-middle X-Git-Tag: v1.6.3-rc0~123^2 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/5ad6b0252b4fff02ac8516b2ea5e3e7330dcc76f Adjust js/remote-improvements and db/refspec-wildcard-in-the-middle The latter topic changes the definition of how refspec's src and dst side is stored in-core; it used to be that the asterisk for pattern was omitted, but now it is included. The former topic handcrafts an old style refspec to feed the refspec matching machinery that lacks the asterisk and triggers an error. This resolves the semantic clash between the two topics early before they need to be merged to integration branches. Signed-off-by: Junio C Hamano --- 5ad6b0252b4fff02ac8516b2ea5e3e7330dcc76f diff --cc builtin-clone.c index 06b5a7fc39,3146ca87f8..b385b97828 --- a/builtin-clone.c +++ b/builtin-clone.c @@@ -544,9 -507,10 +508,10 @@@ int cmd_clone(int argc, const char **ar if (refs) { clear_extra_refs(); - mapped_refs = write_remote_refs(refs, &refspec, reflog_msg.buf); + mapped_refs = write_remote_refs(refs, refspec, reflog_msg.buf); - head_points_at = locate_head(refs, mapped_refs, &remote_head); + remote_head = find_ref_by_name(refs, "HEAD"); + head_points_at = guess_remote_head(remote_head, mapped_refs, 0); } else { warning("You appear to have cloned an empty repository."); diff --cc builtin-remote.c index ac69d37c8a,7b31e554e9..3e4a41b11b --- a/builtin-remote.c +++ b/builtin-remote.c @@@ -271,6 -276,133 +276,125 @@@ static int get_ref_states(const struct return 0; } + struct push_info { + char *dest; + int forced; + enum { + PUSH_STATUS_CREATE = 0, + PUSH_STATUS_DELETE, + PUSH_STATUS_UPTODATE, + PUSH_STATUS_FASTFORWARD, + PUSH_STATUS_OUTOFDATE, + PUSH_STATUS_NOTQUERIED, + } status; + }; + + static int get_push_ref_states(const struct ref *remote_refs, + struct ref_states *states) + { + struct remote *remote = states->remote; + struct ref *ref, *local_refs, *push_map, **push_tail; + if (remote->mirror) + return 0; + + local_refs = get_local_heads(); + ref = push_map = copy_ref_list(remote_refs); + while (ref->next) + ref = ref->next; + push_tail = &ref->next; + + match_refs(local_refs, push_map, &push_tail, remote->push_refspec_nr, + remote->push_refspec, MATCH_REFS_NONE); + + states->push.strdup_strings = 1; + for (ref = push_map; ref; ref = ref->next) { + struct string_list_item *item; + struct push_info *info; + + if (!ref->peer_ref) + continue; + hashcpy(ref->new_sha1, ref->peer_ref->new_sha1); + + item = string_list_append(abbrev_branch(ref->peer_ref->name), + &states->push); + item->util = xcalloc(sizeof(struct push_info), 1); + info = item->util; + info->forced = ref->force; + info->dest = xstrdup(abbrev_branch(ref->name)); + + if (is_null_sha1(ref->new_sha1)) { + info->status = PUSH_STATUS_DELETE; + } else if (!hashcmp(ref->old_sha1, ref->new_sha1)) + info->status = PUSH_STATUS_UPTODATE; + else if (is_null_sha1(ref->old_sha1)) + info->status = PUSH_STATUS_CREATE; + else if (has_sha1_file(ref->old_sha1) && + ref_newer(ref->new_sha1, ref->old_sha1)) + info->status = PUSH_STATUS_FASTFORWARD; + else + info->status = PUSH_STATUS_OUTOFDATE; + } + free_refs(local_refs); + free_refs(push_map); + return 0; + } + + static int get_push_ref_states_noquery(struct ref_states *states) + { + int i; + struct remote *remote = states->remote; + struct string_list_item *item; + struct push_info *info; + + if (remote->mirror) + return 0; + + states->push.strdup_strings = 1; + if (!remote->push_refspec_nr) { + item = string_list_append("(matching)", &states->push); + info = item->util = xcalloc(sizeof(struct push_info), 1); + info->status = PUSH_STATUS_NOTQUERIED; + info->dest = xstrdup(item->string); + } + for (i = 0; i < remote->push_refspec_nr; i++) { + struct refspec *spec = remote->push + i; - char buf[PATH_MAX]; + if (spec->matching) + item = string_list_append("(matching)", &states->push); - else if (spec->pattern) { - snprintf(buf, (sizeof(buf)), "%s*", spec->src); - item = string_list_append(buf, &states->push); - snprintf(buf, (sizeof(buf)), "%s*", spec->dst); - } else if (strlen(spec->src)) ++ else if (strlen(spec->src)) + item = string_list_append(spec->src, &states->push); + else + item = string_list_append("(delete)", &states->push); + + info = item->util = xcalloc(sizeof(struct push_info), 1); + info->forced = spec->force; + info->status = PUSH_STATUS_NOTQUERIED; - if (spec->pattern) - info->dest = xstrdup(buf); - else - info->dest = xstrdup(spec->dst ? spec->dst : item->string); ++ info->dest = xstrdup(spec->dst ? spec->dst : item->string); + } + return 0; + } + + static int get_head_names(const struct ref *remote_refs, struct ref_states *states) + { + struct ref *ref, *matches; + struct ref *fetch_map = NULL, **fetch_map_tail = &fetch_map; + struct refspec refspec; + + refspec.force = 0; + refspec.pattern = 1; - refspec.src = refspec.dst = "refs/heads/"; ++ refspec.src = refspec.dst = "refs/heads/*"; + states->heads.strdup_strings = 1; + get_fetch_map(remote_refs, &refspec, &fetch_map_tail, 0); + matches = guess_remote_head(find_ref_by_name(remote_refs, "HEAD"), + fetch_map, 1); + for(ref = matches; ref; ref = ref->next) + string_list_append(abbrev_branch(ref->name), &states->heads); + + free_refs(fetch_map); + free_refs(matches); + + return 0; + } + struct known_remote { struct known_remote *next; struct remote *remote;