1
0
Fork 0
mirror of https://github.com/git/git.git synced 2024-05-26 14:06:14 +02:00

fetch: allow explicit --refmap to override configuration

Since the introduction of opportunisitic updates of remote-tracking
branches, started at around f2690487 (fetch: opportunistically
update tracking refs, 2013-05-11) with a few updates in v1.8.4 era,
the remote.*.fetch configuration always kicks in even when a refspec
to specify what to fetch is given on the command line, and there is
no way to disable or override it per-invocation.

Teach the command to pay attention to the --refmap=<lhs>:<rhs>
command-line options that can be used to override the use of
configured remote.*.fetch as the refmap.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
This commit is contained in:
Junio C Hamano 2014-05-29 15:21:31 -07:00
parent fcb14b0c8d
commit c5558f80c3
4 changed files with 81 additions and 3 deletions

View File

@ -72,6 +72,14 @@ endif::git-pull[]
setting. See linkgit:git-config[1].
ifndef::git-pull[]
--refmap=<refspec>::
When fetching refs listed on the command line, use the
specified refspec (can be given more than once) to map the
refs to remote-tracking branches, instead of the values of
`remote.*.fetch` configuration variables for the remote
repository. See section on "Configured Remote-tracking
Branches" for details.
-t::
--tags::
Fetch all tags from the remote (i.e., fetch remote tags

View File

@ -95,6 +95,10 @@ This configuration is used in two ways:
only used to decide _where_ the refs that are fetched are stored
by acting as a mapping.
The latter use of the `remote.<repository>.fetch` values can be
overridden by giving the `--refmap=<refspec>` parameter(s) on the
command line.
EXAMPLES
--------

View File

@ -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;

View File

@ -447,6 +447,43 @@ test_expect_success 'explicit pull should update tracking' '
)
'
test_expect_success 'explicit --refmap is allowed only with command-line refspec' '
cd "$D" &&
(
cd three &&
test_must_fail git fetch --refmap="*:refs/remotes/none/*"
)
'
test_expect_success 'explicit --refmap option overrides remote.*.fetch' '
cd "$D" &&
git branch -f side &&
(
cd three &&
git update-ref refs/remotes/origin/master base-origin-master &&
o=$(git rev-parse --verify refs/remotes/origin/master) &&
git fetch --refmap="refs/heads/*:refs/remotes/other/*" origin master &&
n=$(git rev-parse --verify refs/remotes/origin/master) &&
test "$o" = "$n" &&
test_must_fail git rev-parse --verify refs/remotes/origin/side &&
git rev-parse --verify refs/remotes/other/master
)
'
test_expect_success 'explicitly empty --refmap option disables remote.*.fetch' '
cd "$D" &&
git branch -f side &&
(
cd three &&
git update-ref refs/remotes/origin/master base-origin-master &&
o=$(git rev-parse --verify refs/remotes/origin/master) &&
git fetch --refmap="" origin master &&
n=$(git rev-parse --verify refs/remotes/origin/master) &&
test "$o" = "$n" &&
test_must_fail git rev-parse --verify refs/remotes/origin/side
)
'
test_expect_success 'configured fetch updates tracking' '
cd "$D" &&