summaryrefslogtreecommitdiff
path: root/builtin/fetch.c
diff options
context:
space:
mode:
Diffstat (limited to 'builtin/fetch.c')
-rw-r--r--builtin/fetch.c46
1 files changed, 35 insertions, 11 deletions
diff --git a/builtin/fetch.c b/builtin/fetch.c
index 025bc3e38d..e8d0cca3e4 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -45,6 +45,8 @@ static struct transport *gsecondary;
static const char *submodule_prefix = "";
static const char *recurse_submodules_default;
static int shown_url = 0;
+static int refmap_alloc, refmap_nr;
+static const char **refmap_array;
static int option_parse_recurse_submodules(const struct option *opt,
const char *arg, int unset)
@@ -69,6 +71,19 @@ static int git_fetch_config(const char *k, const char *v, void *cb)
return 0;
}
+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;
+ return 0;
+}
+
static struct option builtin_fetch_options[] = {
OPT__VERBOSITY(&verbosity),
OPT_BOOL(0, "all", &all,
@@ -107,6 +122,8 @@ static struct option builtin_fetch_options[] = {
N_("default mode for recursion"), PARSE_OPT_HIDDEN },
OPT_BOOL(0, "update-shallow", &update_shallow,
N_("accept refs that update .git/shallow")),
+ { OPTION_CALLBACK, 0, "refmap", NULL, N_("refmap"),
+ N_("specify fetch refmap"), PARSE_OPT_NONEG, parse_refmap_arg },
OPT_END()
};
@@ -278,6 +295,9 @@ static struct ref *get_ref_map(struct transport *transport,
const struct ref *remote_refs = transport_get_remote_refs(transport);
if (refspec_count) {
+ 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])
@@ -307,12 +327,21 @@ 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.
*/
- for (i = 0; i < transport->remote->fetch_refspec_nr; i++)
- get_fetch_map(ref_map, &transport->remote->fetch[i],
- &oref_tail, 1);
+ 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;
+ }
+
+ for (i = 0; i < fetch_refspec_nr; i++)
+ get_fetch_map(ref_map, &fetch_refspec[i], &oref_tail, 1);
if (tags == TAGS_SET)
get_fetch_map(remote_refs, tag_refspec, &tail, 0);
+ } else if (refmap_array) {
+ die("--refmap option is only meaningful with command-line refspec(s).");
} else {
/* Use the defaults */
struct remote *remote = transport->remote;
@@ -1026,7 +1055,6 @@ static int fetch_multiple(struct string_list *list)
static int fetch_one(struct remote *remote, int argc, const char **argv)
{
- int i;
static const char **refs = NULL;
struct refspec *refspec;
int ref_nr = 0;
@@ -1050,19 +1078,15 @@ static int fetch_one(struct remote *remote, int argc, const char **argv)
if (argc > 0) {
int j = 0;
+ int i;
refs = xcalloc(argc + 1, sizeof(const char *));
for (i = 0; i < argc; i++) {
if (!strcmp(argv[i], "tag")) {
- char *ref;
i++;
if (i >= argc)
die(_("You need to specify a tag name."));
- ref = xmalloc(strlen(argv[i]) * 2 + 22);
- strcpy(ref, "refs/tags/");
- strcat(ref, argv[i]);
- strcat(ref, ":refs/tags/");
- strcat(ref, argv[i]);
- refs[j++] = ref;
+ refs[j++] = xstrfmt("refs/tags/%s:refs/tags/%s",
+ argv[i], argv[i]);
} else
refs[j++] = argv[i];
}