summaryrefslogtreecommitdiff
path: root/builtin
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2018-05-30 21:51:26 +0900
committerJunio C Hamano <gitster@pobox.com>2018-05-30 21:51:26 +0900
commite12cbeaa624b82bc00d585bb24c8034fbf5f9de2 (patch)
tree6eed9588af71c6ba9776f592c3573d88929d1bab /builtin
parent6ac5acae2d93f49f169d9b10dd9fcbce3fd874e2 (diff)
parentdcc73cf7ffd17e68bda05fff4c139465580aff28 (diff)
downloadgit-e12cbeaa624b82bc00d585bb24c8034fbf5f9de2.tar.gz
Merge branch 'bw/ref-prefix-for-configured-refspec'
"git fetch $there $refspec" that talks over protocol v2 can take advantage of server-side ref filtering; the code has been extended so that this mechanism triggers also when fetching with configured refspec. * bw/ref-prefix-for-configured-refspec: (38 commits) fetch: generate ref-prefixes when using a configured refspec refspec: consolidate ref-prefix generation logic submodule: convert push_unpushed_submodules to take a struct refspec remote: convert check_push_refs to take a struct refspec remote: convert match_push_refs to take a struct refspec http-push: store refspecs in a struct refspec transport: remove transport_verify_remote_names send-pack: store refspecs in a struct refspec transport: convert transport_push to take a struct refspec push: convert to use struct refspec push: check for errors earlier remote: convert match_explicit_refs to take a struct refspec remote: convert get_ref_match to take a struct refspec remote: convert query_refspecs to take a struct refspec remote: convert apply_refspecs to take a struct refspec remote: convert get_stale_heads to take a struct refspec fetch: convert prune_refs to take a struct refspec fetch: convert get_ref_map to take a struct refspec fetch: convert do_fetch to take a struct refspec refspec: remove the deprecated functions ...
Diffstat (limited to 'builtin')
-rw-r--r--builtin/clone.c13
-rw-r--r--builtin/fast-export.c22
-rw-r--r--builtin/fetch.c139
-rw-r--r--builtin/merge.c1
-rw-r--r--builtin/pull.c9
-rw-r--r--builtin/push.c80
-rw-r--r--builtin/remote.c37
-rw-r--r--builtin/send-pack.c24
-rw-r--r--builtin/submodule--helper.c14
9 files changed, 147 insertions, 192 deletions
diff --git a/builtin/clone.c b/builtin/clone.c
index ecd8495dab..99e73dae85 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -14,6 +14,7 @@
#include "parse-options.h"
#include "fetch-pack.h"
#include "refs.h"
+#include "refspec.h"
#include "tree.h"
#include "tree-walk.h"
#include "unpack-trees.h"
@@ -546,7 +547,7 @@ static struct ref *find_remote_branch(const struct ref *refs, const char *branch
}
static struct ref *wanted_peer_refs(const struct ref *refs,
- struct refspec *refspec)
+ struct refspec_item *refspec)
{
struct ref *head = copy_ref(find_ref_by_name(refs, "HEAD"));
struct ref *local_refs = head;
@@ -894,8 +895,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
int err = 0, complete_refs_before_fetch = 1;
int submodule_progress;
- struct refspec *refspec;
- const char *fetch_pattern;
+ struct refspec_item refspec;
fetch_if_missing = 0;
@@ -1077,8 +1077,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
if (option_required_reference.nr || option_optional_reference.nr)
setup_reference();
- fetch_pattern = value.buf;
- refspec = parse_fetch_refspec(1, &fetch_pattern);
+ refspec_item_init(&refspec, value.buf, REFSPEC_FETCH);
strbuf_reset(&value);
@@ -1138,7 +1137,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
refs = transport_get_remote_refs(transport, NULL);
if (refs) {
- mapped_refs = wanted_peer_refs(refs, refspec);
+ mapped_refs = wanted_peer_refs(refs, &refspec);
/*
* transport_get_remote_refs() may return refs with null sha-1
* in mapped_refs (see struct transport->get_refs_list
@@ -1232,6 +1231,6 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
strbuf_release(&value);
junk_mode = JUNK_LEAVE_ALL;
- free(refspec);
+ refspec_item_clear(&refspec);
return err;
}
diff --git a/builtin/fast-export.c b/builtin/fast-export.c
index f9568ddba0..6c9768742f 100644
--- a/builtin/fast-export.c
+++ b/builtin/fast-export.c
@@ -7,6 +7,7 @@
#include "cache.h"
#include "config.h"
#include "refs.h"
+#include "refspec.h"
#include "commit.h"
#include "object.h"
#include "tag.h"
@@ -35,8 +36,7 @@ static int use_done_feature;
static int no_data;
static int full_tree;
static struct string_list extra_refs = STRING_LIST_INIT_NODUP;
-static struct refspec *refspecs;
-static int refspecs_nr;
+static struct refspec refspecs = REFSPEC_INIT_FETCH;
static int anonymize;
static int parse_opt_signed_tag_mode(const struct option *opt,
@@ -828,9 +828,9 @@ static void get_tags_and_duplicates(struct rev_cmdline_info *info)
if (dwim_ref(e->name, strlen(e->name), &oid, &full_name) != 1)
continue;
- if (refspecs) {
+ if (refspecs.nr) {
char *private;
- private = apply_refspecs(refspecs, refspecs_nr, full_name);
+ private = apply_refspecs(&refspecs, full_name);
if (private) {
free(full_name);
full_name = private;
@@ -976,8 +976,8 @@ static void import_marks(char *input_file)
static void handle_deletes(void)
{
int i;
- for (i = 0; i < refspecs_nr; i++) {
- struct refspec *refspec = &refspecs[i];
+ for (i = 0; i < refspecs.nr; i++) {
+ struct refspec_item *refspec = &refspecs.items[i];
if (*refspec->src)
continue;
@@ -1038,18 +1038,12 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
usage_with_options (fast_export_usage, options);
if (refspecs_list.nr) {
- const char **refspecs_str;
int i;
- ALLOC_ARRAY(refspecs_str, refspecs_list.nr);
for (i = 0; i < refspecs_list.nr; i++)
- refspecs_str[i] = refspecs_list.items[i].string;
-
- refspecs_nr = refspecs_list.nr;
- refspecs = parse_fetch_refspec(refspecs_nr, refspecs_str);
+ refspec_append(&refspecs, refspecs_list.items[i].string);
string_list_clear(&refspecs_list, 1);
- free(refspecs_str);
}
if (use_done_feature)
@@ -1088,7 +1082,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
if (use_done_feature)
printf("done\n");
- free_refspec(refspecs_nr, refspecs);
+ refspec_clear(&refspecs);
return 0;
}
diff --git a/builtin/fetch.c b/builtin/fetch.c
index 1f037e8e4b..c0d8ad1fe2 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -5,6 +5,7 @@
#include "config.h"
#include "repository.h"
#include "refs.h"
+#include "refspec.h"
#include "commit.h"
#include "builtin.h"
#include "string-list.h"
@@ -59,8 +60,7 @@ static const char *submodule_prefix = "";
static int recurse_submodules = RECURSE_SUBMODULES_DEFAULT;
static int recurse_submodules_default = RECURSE_SUBMODULES_ON_DEMAND;
static int shown_url = 0;
-static int refmap_alloc, refmap_nr;
-static const char **refmap_array;
+static struct refspec refmap = REFSPEC_INIT_FETCH;
static struct list_objects_filter_options filter_options;
static struct string_list server_options = STRING_LIST_INIT_DUP;
@@ -108,14 +108,12 @@ static int gitmodules_fetch_config(const char *var, const char *value, void *cb)
static int parse_refmap_arg(const struct option *opt, const char *arg, int unset)
{
- ALLOC_GROW(refmap_array, refmap_nr + 1, refmap_alloc);
-
/*
* "git fetch --refmap='' origin foo"
* can be used to tell the command not to store anywhere
*/
- if (*arg)
- refmap_array[refmap_nr++] = arg;
+ refspec_append(&refmap, arg);
+
return 0;
}
@@ -204,7 +202,7 @@ static void add_merge_config(struct ref **head,
for (i = 0; i < branch->merge_nr; i++) {
struct ref *rm, **old_tail = *tail;
- struct refspec refspec;
+ struct refspec_item refspec;
for (rm = *head; rm; rm = rm->next) {
if (branch_merge_matches(branch, i, rm->name)) {
@@ -341,7 +339,7 @@ static void find_non_local_tags(struct transport *transport,
}
static struct ref *get_ref_map(struct transport *transport,
- struct refspec *refspecs, int refspec_count,
+ struct refspec *rs,
int tags, int *autotags)
{
int i;
@@ -355,29 +353,26 @@ static struct ref *get_ref_map(struct transport *transport,
const struct ref *remote_refs;
- for (i = 0; i < refspec_count; i++) {
- if (!refspecs[i].exact_sha1) {
- const char *glob = strchr(refspecs[i].src, '*');
- if (glob)
- argv_array_pushf(&ref_prefixes, "%.*s",
- (int)(glob - refspecs[i].src),
- refspecs[i].src);
- else
- expand_ref_prefix(&ref_prefixes, refspecs[i].src);
- }
+ if (rs->nr)
+ refspec_ref_prefixes(rs, &ref_prefixes);
+ else if (transport->remote && transport->remote->fetch.nr)
+ refspec_ref_prefixes(&transport->remote->fetch, &ref_prefixes);
+
+ if (ref_prefixes.argc &&
+ (tags == TAGS_SET || (tags == TAGS_DEFAULT && !rs->nr))) {
+ argv_array_push(&ref_prefixes, "refs/tags/");
}
remote_refs = transport_get_remote_refs(transport, &ref_prefixes);
argv_array_clear(&ref_prefixes);
- if (refspec_count) {
+ if (rs->nr) {
struct refspec *fetch_refspec;
- int fetch_refspec_nr;
- for (i = 0; i < refspec_count; i++) {
- get_fetch_map(remote_refs, &refspecs[i], &tail, 0);
- if (refspecs[i].dst && refspecs[i].dst[0])
+ for (i = 0; i < rs->nr; i++) {
+ get_fetch_map(remote_refs, &rs->items[i], &tail, 0);
+ if (rs->items[i].dst && rs->items[i].dst[0])
*autotags = 1;
}
/* Merge everything on the command line (but not --tags) */
@@ -404,17 +399,14 @@ static struct ref *get_ref_map(struct transport *transport,
* by ref_remove_duplicates() in favor of one of these
* opportunistic entries with FETCH_HEAD_IGNORE.
*/
- if (refmap_array) {
- fetch_refspec = parse_fetch_refspec(refmap_nr, refmap_array);
- fetch_refspec_nr = refmap_nr;
- } else {
- fetch_refspec = transport->remote->fetch;
- fetch_refspec_nr = transport->remote->fetch_refspec_nr;
- }
+ if (refmap.nr)
+ fetch_refspec = &refmap;
+ else
+ fetch_refspec = &transport->remote->fetch;
- for (i = 0; i < fetch_refspec_nr; i++)
- get_fetch_map(ref_map, &fetch_refspec[i], &oref_tail, 1);
- } else if (refmap_array) {
+ for (i = 0; i < fetch_refspec->nr; i++)
+ get_fetch_map(ref_map, &fetch_refspec->items[i], &oref_tail, 1);
+ } else if (refmap.nr) {
die("--refmap option is only meaningful with command-line refspec(s).");
} else {
/* Use the defaults */
@@ -422,16 +414,16 @@ static struct ref *get_ref_map(struct transport *transport,
struct branch *branch = branch_get(NULL);
int has_merge = branch_has_merge_config(branch);
if (remote &&
- (remote->fetch_refspec_nr ||
+ (remote->fetch.nr ||
/* Note: has_merge implies non-NULL branch->remote_name */
(has_merge && !strcmp(branch->remote_name, remote->name)))) {
- for (i = 0; i < remote->fetch_refspec_nr; i++) {
- get_fetch_map(remote_refs, &remote->fetch[i], &tail, 0);
- if (remote->fetch[i].dst &&
- remote->fetch[i].dst[0])
+ for (i = 0; i < remote->fetch.nr; i++) {
+ get_fetch_map(remote_refs, &remote->fetch.items[i], &tail, 0);
+ if (remote->fetch.items[i].dst &&
+ remote->fetch.items[i].dst[0])
*autotags = 1;
if (!i && !has_merge && ref_map &&
- !remote->fetch[0].pattern)
+ !remote->fetch.items[0].pattern)
ref_map->fetch_head_status = FETCH_HEAD_MERGE;
}
/*
@@ -966,11 +958,11 @@ static int fetch_refs(struct transport *transport, struct ref *ref_map)
return ret;
}
-static int prune_refs(struct refspec *refs, int ref_count, struct ref *ref_map,
- const char *raw_url)
+static int prune_refs(struct refspec *rs, struct ref *ref_map,
+ const char *raw_url)
{
int url_len, i, result = 0;
- struct ref *ref, *stale_refs = get_stale_heads(refs, ref_count, ref_map);
+ struct ref *ref, *stale_refs = get_stale_heads(rs, ref_map);
char *url;
int summary_width = transport_summary_width(stale_refs);
const char *dangling_msg = dry_run
@@ -1116,7 +1108,7 @@ static void backfill_tags(struct transport *transport, struct ref *ref_map)
}
static int do_fetch(struct transport *transport,
- struct refspec *refs, int ref_count)
+ struct refspec *rs)
{
struct string_list existing_refs = STRING_LIST_INIT_DUP;
struct ref *ref_map;
@@ -1140,7 +1132,7 @@ static int do_fetch(struct transport *transport,
goto cleanup;
}
- ref_map = get_ref_map(transport, refs, ref_count, tags, &autotags);
+ ref_map = get_ref_map(transport, rs, tags, &autotags);
if (!update_head_ok)
check_not_current_branch(ref_map);
@@ -1164,11 +1156,10 @@ static int do_fetch(struct transport *transport,
* explicitly (via command line or configuration); we
* don't care whether --tags was specified.
*/
- if (ref_count) {
- prune_refs(refs, ref_count, ref_map, transport->url);
+ if (rs->nr) {
+ prune_refs(rs, ref_map, transport->url);
} else {
- prune_refs(transport->remote->fetch,
- transport->remote->fetch_refspec_nr,
+ prune_refs(&transport->remote->fetch,
ref_map,
transport->url);
}
@@ -1357,10 +1348,8 @@ static inline void fetch_one_setup_partial(struct remote *remote)
static int fetch_one(struct remote *remote, int argc, const char **argv, int prune_tags_ok)
{
- static const char **refs = NULL;
- struct refspec *refspec;
- int ref_nr = 0;
- int j = 0;
+ struct refspec rs = REFSPEC_INIT_FETCH;
+ int i;
int exit_code;
int maybe_prune_tags;
int remote_via_config = remote_is_configured(remote, 0);
@@ -1393,29 +1382,24 @@ static int fetch_one(struct remote *remote, int argc, const char **argv, int pru
maybe_prune_tags = prune_tags_ok && prune_tags;
if (maybe_prune_tags && remote_via_config)
- add_prune_tags_to_fetch_refspec(remote);
-
- if (argc > 0 || (maybe_prune_tags && !remote_via_config)) {
- size_t nr_alloc = st_add3(argc, maybe_prune_tags, 1);
- refs = xcalloc(nr_alloc, sizeof(const char *));
- if (maybe_prune_tags) {
- refs[j++] = xstrdup("refs/tags/*:refs/tags/*");
- ref_nr++;
- }
- }
-
- if (argc > 0) {
- int i;
- for (i = 0; i < argc; i++) {
- if (!strcmp(argv[i], "tag")) {
- i++;
- if (i >= argc)
- die(_("You need to specify a tag name."));
- refs[j++] = xstrfmt("refs/tags/%s:refs/tags/%s",
- argv[i], argv[i]);
- } else
- refs[j++] = argv[i];
- ref_nr++;
+ refspec_append(&remote->fetch, TAG_REFSPEC);
+
+ if (maybe_prune_tags && (argc || !remote_via_config))
+ refspec_append(&rs, TAG_REFSPEC);
+
+ for (i = 0; i < argc; i++) {
+ if (!strcmp(argv[i], "tag")) {
+ char *tag;
+ i++;
+ if (i >= argc)
+ die(_("You need to specify a tag name."));
+
+ tag = xstrfmt("refs/tags/%s:refs/tags/%s",
+ argv[i], argv[i]);
+ refspec_append(&rs, tag);
+ free(tag);
+ } else {
+ refspec_append(&rs, argv[i]);
}
}
@@ -1424,9 +1408,8 @@ static int fetch_one(struct remote *remote, int argc, const char **argv, int pru
sigchain_push_common(unlock_pack_on_signal);
atexit(unlock_pack);
- refspec = parse_fetch_refspec(ref_nr, refs);
- exit_code = do_fetch(gtransport, refspec, ref_nr);
- free_refspec(ref_nr, refspec);
+ exit_code = do_fetch(gtransport, &rs);
+ refspec_clear(&rs);
transport_disconnect(gtransport);
gtransport = NULL;
return exit_code;
diff --git a/builtin/merge.c b/builtin/merge.c
index fba0a7fc79..d85f99b781 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -14,6 +14,7 @@
#include "run-command.h"
#include "diff.h"
#include "refs.h"
+#include "refspec.h"
#include "commit.h"
#include "diffcore.h"
#include "revision.h"
diff --git a/builtin/pull.c b/builtin/pull.c
index 25f7db5b3a..1f2ecf3a88 100644
--- a/builtin/pull.c
+++ b/builtin/pull.c
@@ -15,6 +15,7 @@
#include "remote.h"
#include "dir.h"
#include "refs.h"
+#include "refspec.h"
#include "revision.h"
#include "submodule.h"
#include "submodule-config.h"
@@ -679,12 +680,12 @@ static const char *get_upstream_branch(const char *remote)
*/
static const char *get_tracking_branch(const char *remote, const char *refspec)
{
- struct refspec *spec;
+ struct refspec_item spec;
const char *spec_src;
const char *merge_branch;
- spec = parse_fetch_refspec(1, &refspec);
- spec_src = spec->src;
+ refspec_item_init(&spec, refspec, REFSPEC_FETCH);
+ spec_src = spec.src;
if (!*spec_src || !strcmp(spec_src, "HEAD"))
spec_src = "HEAD";
else if (skip_prefix(spec_src, "heads/", &spec_src))
@@ -704,7 +705,7 @@ static const char *get_tracking_branch(const char *remote, const char *refspec)
} else
merge_branch = NULL;
- free_refspec(1, spec);
+ refspec_item_clear(&spec);
return merge_branch;
}
diff --git a/builtin/push.c b/builtin/push.c
index ac3705370e..9cd8e8cd56 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -4,6 +4,7 @@
#include "cache.h"
#include "config.h"
#include "refs.h"
+#include "refspec.h"
#include "run-command.h"
#include "builtin.h"
#include "remote.h"
@@ -56,19 +57,10 @@ static enum transport_family family;
static struct push_cas_option cas;
-static const char **refspec;
-static int refspec_nr;
-static int refspec_alloc;
+static struct refspec rs = REFSPEC_INIT_PUSH;
static struct string_list push_options_config = STRING_LIST_INIT_DUP;
-static void add_refspec(const char *ref)
-{
- refspec_nr++;
- ALLOC_GROW(refspec, refspec_nr, refspec_alloc);
- refspec[refspec_nr-1] = ref;
-}
-
static const char *map_refspec(const char *ref,
struct remote *remote, struct ref *local_refs)
{
@@ -78,12 +70,11 @@ static const char *map_refspec(const char *ref,
if (count_refspec_match(ref, local_refs, &matched) != 1)
return ref;
- if (remote->push) {
- struct refspec query;
- memset(&query, 0, sizeof(struct refspec));
+ if (remote->push.nr) {
+ struct refspec_item query;
+ memset(&query, 0, sizeof(struct refspec_item));
query.src = matched->name;
- if (!query_refspecs(remote->push, remote->push_refspec_nr, &query) &&
- query.dst) {
+ if (!query_refspecs(&remote->push, &query) && query.dst) {
struct strbuf buf = STRBUF_INIT;
strbuf_addf(&buf, "%s%s:%s",
query.force ? "+" : "",
@@ -138,7 +129,7 @@ static void set_refspecs(const char **refs, int nr, const char *repo)
}
ref = map_refspec(ref, remote, local_refs);
}
- add_refspec(ref);
+ refspec_append(&rs, ref);
}
}
@@ -226,7 +217,7 @@ static void setup_push_upstream(struct remote *remote, struct branch *branch,
}
strbuf_addf(&refspec, "%s:%s", branch->refname, branch->merge[0]->src);
- add_refspec(refspec.buf);
+ refspec_append(&rs, refspec.buf);
}
static void setup_push_current(struct remote *remote, struct branch *branch)
@@ -236,7 +227,7 @@ static void setup_push_current(struct remote *remote, struct branch *branch)
if (!branch)
die(_(message_detached_head_die), remote->name);
strbuf_addf(&refspec, "%s:%s", branch->refname, branch->refname);
- add_refspec(refspec.buf);
+ refspec_append(&rs, refspec.buf);
}
static int is_workflow_triangular(struct remote *remote)
@@ -253,7 +244,7 @@ static void setup_default_push_refspecs(struct remote *remote)
switch (push_default) {
default:
case PUSH_DEFAULT_MATCHING:
- add_refspec(":");
+ refspec_append(&rs, ":");
break;
case PUSH_DEFAULT_UNSPECIFIED:
@@ -341,7 +332,8 @@ static void advise_ref_needs_force(void)
advise(_(message_advice_ref_needs_force));
}
-static int push_with_options(struct transport *transport, int flags)
+static int push_with_options(struct transport *transport, struct refspec *rs,
+ int flags)
{
int err;
unsigned int reject_reasons;
@@ -363,8 +355,7 @@ static int push_with_options(struct transport *transport, int flags)
if (verbosity > 0)
fprintf(stderr, _("Pushing to %s\n"), transport->url);
- err = transport_push(transport, refspec_nr, refspec, flags,
- &reject_reasons);
+ err = transport_push(transport, rs, flags, &reject_reasons);
if (err != 0) {
fprintf(stderr, "%s", push_get_color(PUSH_COLOR_ERROR));
error(_("failed to push some refs to '%s'"), transport->url);
@@ -397,6 +388,7 @@ static int do_push(const char *repo, int flags,
struct remote *remote = pushremote_get(repo);
const char **url;
int url_nr;
+ struct refspec *push_refspec = &rs;
if (!remote) {
if (repo)
@@ -417,27 +409,9 @@ static int do_push(const char *repo, int flags,
if (push_options->nr)
flags |= TRANSPORT_PUSH_OPTIONS;
- if ((flags & TRANSPORT_PUSH_ALL) && refspec) {
- if (!strcmp(*refspec, "refs/tags/*"))
- return error(_("--all and --tags are incompatible"));
- return error(_("--all can't be combined with refspecs"));
- }
-
- if ((flags & TRANSPORT_PUSH_MIRROR) && refspec) {
- if (!strcmp(*refspec, "refs/tags/*"))
- return error(_("--mirror and --tags are incompatible"));
- return error(_("--mirror can't be combined with refspecs"));
- }
-
- if ((flags & (TRANSPORT_PUSH_ALL|TRANSPORT_PUSH_MIRROR)) ==
- (TRANSPORT_PUSH_ALL|TRANSPORT_PUSH_MIRROR)) {
- return error(_("--all and --mirror are incompatible"));
- }
-
- if (!refspec && !(flags & TRANSPORT_PUSH_ALL)) {
- if (remote->push_refspec_nr) {
- refspec = remote->push_refspec;
- refspec_nr = remote->push_refspec_nr;
+ if (!push_refspec->nr && !(flags & TRANSPORT_PUSH_ALL)) {
+ if (remote->push.nr) {
+ push_refspec = &remote->push;
} else if (!(flags & TRANSPORT_PUSH_MIRROR))
setup_default_push_refspecs(remote);
}
@@ -449,7 +423,7 @@ static int do_push(const char *repo, int flags,
transport_get(remote, url[i]);
if (flags & TRANSPORT_PUSH_OPTIONS)
transport->push_options = push_options;
- if (push_with_options(transport, flags))
+ if (push_with_options(transport, push_refspec, flags))
errs++;
}
} else {
@@ -457,7 +431,7 @@ static int do_push(const char *repo, int flags,
transport_get(remote, NULL);
if (flags & TRANSPORT_PUSH_OPTIONS)
transport->push_options = push_options;
- if (push_with_options(transport, flags))
+ if (push_with_options(transport, push_refspec, flags))
errs++;
}
return !!errs;
@@ -625,6 +599,20 @@ int cmd_push(int argc, const char **argv, const char *prefix)
die(_("--delete is incompatible with --all, --mirror and --tags"));
if (deleterefs && argc < 2)
die(_("--delete doesn't make sense without any refs"));
+ if (flags & TRANSPORT_PUSH_ALL) {
+ if (tags)
+ die(_("--all and --tags are incompatible"));
+ if (argc >= 2)
+ die(_("--all can't be combined with refspecs"));
+ }
+ if (flags & TRANSPORT_PUSH_MIRROR) {
+ if (tags)
+ die(_("--mirror and --tags are incompatible"));
+ if (argc >= 2)
+ die(_("--mirror can't be combined with refspecs"));
+ }
+ if ((flags & TRANSPORT_PUSH_ALL) && (flags & TRANSPORT_PUSH_MIRROR))
+ die(_("--all and --mirror are incompatible"));
if (recurse_submodules == RECURSE_SUBMODULES_CHECK)
flags |= TRANSPORT_RECURSE_SUBMODULES_CHECK;
@@ -634,7 +622,7 @@ int cmd_push(int argc, const char **argv, const char *prefix)
flags |= TRANSPORT_RECURSE_SUBMODULES_ONLY;
if (tags)
- add_refspec("refs/tags/*");
+ refspec_append(&rs, "refs/tags/*");
if (argc > 0) {
repo = argv[0];
diff --git a/builtin/remote.c b/builtin/remote.c
index 0bbf9f4c9e..1a82d850a2 100644
--- a/builtin/remote.c
+++ b/builtin/remote.c
@@ -7,6 +7,7 @@
#include "strbuf.h"
#include "run-command.h"
#include "refs.h"
+#include "refspec.h"
#include "argv-array.h"
static const char * const builtin_remote_usage[] = {
@@ -336,10 +337,10 @@ static int get_ref_states(const struct ref *remote_refs, struct ref_states *stat
struct ref *ref, *stale_refs;
int i;
- for (i = 0; i < states->remote->fetch_refspec_nr; i++)
- if (get_fetch_map(remote_refs, states->remote->fetch + i, &tail, 1))
+ for (i = 0; i < states->remote->fetch.nr; i++)
+ if (get_fetch_map(remote_refs, &states->remote->fetch.items[i], &tail, 1))
die(_("Could not get fetch map for refspec %s"),
- states->remote->fetch_refspec[i]);
+ states->remote->fetch.raw[i]);
states->new_refs.strdup_strings = 1;
states->tracked.strdup_strings = 1;
@@ -350,8 +351,7 @@ static int get_ref_states(const struct ref *remote_refs, struct ref_states *stat
else
string_list_append(&states->tracked, abbrev_branch(ref->name));
}
- stale_refs = get_stale_heads(states->remote->fetch,
- states->remote->fetch_refspec_nr, fetch_map);
+ stale_refs = get_stale_heads(&states->remote->fetch, fetch_map);
for (ref = stale_refs; ref; ref = ref->next) {
struct string_list_item *item =
string_list_append(&states->stale, abbrev_branch(ref->name));
@@ -391,8 +391,7 @@ static int get_push_ref_states(const struct ref *remote_refs,
local_refs = get_local_heads();
push_map = copy_ref_list(remote_refs);
- match_push_refs(local_refs, &push_map, remote->push_refspec_nr,
- remote->push_refspec, MATCH_REFS_NONE);
+ match_push_refs(local_refs, &push_map, &remote->push, MATCH_REFS_NONE);
states->push.strdup_strings = 1;
for (ref = push_map; ref; ref = ref->next) {
@@ -438,14 +437,14 @@ static int get_push_ref_states_noquery(struct ref_states *states)
return 0;
states->push.strdup_strings = 1;
- if (!remote->push_refspec_nr) {
+ if (!remote->push.nr) {
item = string_list_append(&states->push, _("(matching)"));
info = item->util = xcalloc(1, sizeof(struct push_info));
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;
+ for (i = 0; i < remote->push.nr; i++) {
+ const struct refspec_item *spec = &remote->push.items[i];
if (spec->matching)
item = string_list_append(&states->push, _("(matching)"));
else if (strlen(spec->src))
@@ -465,7 +464,7 @@ static int get_head_names(const struct ref *remote_refs, struct ref_states *stat
{
struct ref *ref, *matches;
struct ref *fetch_map = NULL, **fetch_map_tail = &fetch_map;
- struct refspec refspec;
+ struct refspec_item refspec;
refspec.force = 0;
refspec.pattern = 1;
@@ -518,7 +517,7 @@ static int add_branch_for_removal(const char *refname,
const struct object_id *oid, int flags, void *cb_data)
{
struct branches_for_remote *branches = cb_data;
- struct refspec refspec;
+ struct refspec_item refspec;
struct known_remote *kr;
memset(&refspec, 0, sizeof(refspec));
@@ -589,12 +588,12 @@ static int migrate_file(struct remote *remote)
git_config_set_multivar(buf.buf, remote->url[i], "^$", 0);
strbuf_reset(&buf);
strbuf_addf(&buf, "remote.%s.push", remote->name);
- for (i = 0; i < remote->push_refspec_nr; i++)
- git_config_set_multivar(buf.buf, remote->push_refspec[i], "^$", 0);
+ for (i = 0; i < remote->push.raw_nr; i++)
+ git_config_set_multivar(buf.buf, remote->push.raw[i], "^$", 0);
strbuf_reset(&buf);
strbuf_addf(&buf, "remote.%s.fetch", remote->name);
- for (i = 0; i < remote->fetch_refspec_nr; i++)
- git_config_set_multivar(buf.buf, remote->fetch_refspec[i], "^$", 0);
+ for (i = 0; i < remote->fetch.raw_nr; i++)
+ git_config_set_multivar(buf.buf, remote->fetch.raw[i], "^$", 0);
if (remote->origin == REMOTE_REMOTES)
unlink_or_warn(git_path("remotes/%s", remote->name));
else if (remote->origin == REMOTE_BRANCHES)
@@ -649,11 +648,11 @@ static int mv(int argc, const char **argv)
strbuf_addf(&buf, "remote.%s.fetch", rename.new_name);
git_config_set_multivar(buf.buf, NULL, NULL, 1);
strbuf_addf(&old_remote_context, ":refs/remotes/%s/", rename.old_name);
- for (i = 0; i < oldremote->fetch_refspec_nr; i++) {
+ for (i = 0; i < oldremote->fetch.raw_nr; i++) {
char *ptr;
strbuf_reset(&buf2);
- strbuf_addstr(&buf2, oldremote->fetch_refspec[i]);
+ strbuf_addstr(&buf2, oldremote->fetch.raw[i]);
ptr = strstr(buf2.buf, old_remote_context.buf);
if (ptr) {
refspec_updated = 1;
@@ -837,7 +836,7 @@ static int append_ref_to_tracked_list(const char *refname,
const struct object_id *oid, int flags, void *cb_data)
{
struct ref_states *states = cb_data;
- struct refspec refspec;
+ struct refspec_item refspec;
if (flags & REF_ISSYMREF)
return 0;
diff --git a/builtin/send-pack.c b/builtin/send-pack.c
index b5427f75e3..4923b1058c 100644
--- a/builtin/send-pack.c
+++ b/builtin/send-pack.c
@@ -126,8 +126,7 @@ static int send_pack_config(const char *k, const char *v, void *cb)
int cmd_send_pack(int argc, const char **argv, const char *prefix)
{
- int i, nr_refspecs = 0;
- const char **refspecs = NULL;
+ struct refspec rs = REFSPEC_INIT_PUSH;
const char *remote_name = NULL;
struct remote *remote = NULL;
const char *dest = NULL;
@@ -189,8 +188,7 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix)
argc = parse_options(argc, argv, prefix, options, send_pack_usage, 0);
if (argc > 0) {
dest = argv[0];
- refspecs = (const char **)(argv + 1);
- nr_refspecs = argc - 1;
+ refspec_appendn(&rs, argv + 1, argc - 1);
}
if (!dest)
@@ -209,31 +207,23 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix)
args.push_options = push_options.nr ? &push_options : NULL;
if (from_stdin) {
- struct argv_array all_refspecs = ARGV_ARRAY_INIT;
-
- for (i = 0; i < nr_refspecs; i++)
- argv_array_push(&all_refspecs, refspecs[i]);
-
if (args.stateless_rpc) {
const char *buf;
while ((buf = packet_read_line(0, NULL)))
- argv_array_push(&all_refspecs, buf);
+ refspec_append(&rs, buf);
} else {
struct strbuf line = STRBUF_INIT;
while (strbuf_getline(&line, stdin) != EOF)
- argv_array_push(&all_refspecs, line.buf);
+ refspec_append(&rs, line.buf);
strbuf_release(&line);
}
-
- refspecs = all_refspecs.argv;
- nr_refspecs = all_refspecs.argc;
}
/*
* --all and --mirror are incompatible; neither makes sense
* with any refspecs.
*/
- if ((nr_refspecs > 0 && (send_all || args.send_mirror)) ||
+ if ((rs.nr > 0 && (send_all || args.send_mirror)) ||
(send_all && args.send_mirror))
usage_with_options(send_pack_usage, options);
@@ -275,8 +265,6 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix)
BUG("unknown protocol version");
}
- transport_verify_remote_names(nr_refspecs, refspecs);
-
local_refs = get_local_heads();
flags = MATCH_REFS_NONE;
@@ -287,7 +275,7 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix)
flags |= MATCH_REFS_MIRROR;
/* match them up */
- if (match_push_refs(local_refs, &remote_refs, nr_refspecs, refspecs, flags))
+ if (match_push_refs(local_refs, &remote_refs, &rs, flags))
return -1;
if (!is_empty_cas(&cas))
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 7c3cd9dbeb..bd250ca216 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -12,6 +12,7 @@
#include "run-command.h"
#include "remote.h"
#include "refs.h"
+#include "refspec.h"
#include "connect.h"
#include "revision.h"
#include "diffcore.h"
@@ -1753,13 +1754,14 @@ static int push_check(int argc, const char **argv, const char *prefix)
/* Check the refspec */
if (argc > 2) {
- int i, refspec_nr = argc - 2;
+ int i;
struct ref *local_refs = get_local_heads();
- struct refspec *refspec = parse_push_refspec(refspec_nr,
- argv + 2);
+ struct refspec refspec = REFSPEC_INIT_PUSH;
- for (i = 0; i < refspec_nr; i++) {
- struct refspec *rs = refspec + i;
+ refspec_appendn(&refspec, argv + 2, argc - 2);
+
+ for (i = 0; i < refspec.nr; i++) {
+ const struct refspec_item *rs = &refspec.items[i];
if (rs->pattern || rs->matching)
continue;
@@ -1786,7 +1788,7 @@ static int push_check(int argc, const char **argv, const char *prefix)
rs->src);
}
}
- free_refspec(refspec_nr, refspec);
+ refspec_clear(&refspec);
}
free(head);