@@ -33,6 +33,11 @@ remote.<name>.fetch::
The default set of "refspec" for linkgit:git-fetch[1]. See
linkgit:git-fetch[1].
+remote.<name>.prefetch::
+ If false, refs from the remote would not be prefetched for
+ the prefetch task in linkgit:git-maintenance[1]. If not set,
+ the value is assumed to be true.
+
remote.<name>.push::
The default set of "refspec" for linkgit:git-push[1]. See
linkgit:git-push[1].
@@ -97,9 +97,10 @@ commit-graph::
prefetch::
The `prefetch` task updates the object directory with the latest
- objects from all registered remotes. For each remote, a `git fetch`
- command is run. The configured refspec is modified to place all
- requested refs within `refs/prefetch/`. Also, tags are not updated.
+ objects from all registered remotes unless they've disabled prefetch
+ using `remote.<remote>.prefetch` set to `false`. For each such remote,
+ a `git fetch` command is run. The configured refspec is modified to place
+ all requested refs within `refs/prefetch/`. Also, tags are not updated.
+
This is done to avoid disrupting the remote-tracking branches. The end users
expect these refs to stay unmoved unless they initiate a fetch. However,
@@ -1027,6 +1027,9 @@ static int fetch_remote(struct remote *remote, void *cbdata)
if (remote->skip_default_update)
return 0;
+ if (!remote->prefetch_enabled)
+ return 0;
+
child.git_cmd = 1;
strvec_pushl(&child.args, "fetch", remote->name,
"--prefetch", "--prune", "--no-tags",
@@ -140,6 +140,7 @@ static struct remote *make_remote(struct remote_state *remote_state,
CALLOC_ARRAY(ret, 1);
ret->prune = -1; /* unspecified */
ret->prune_tags = -1; /* unspecified */
+ ret->prefetch_enabled = 1;
ret->name = xstrndup(name, len);
refspec_init(&ret->push, REFSPEC_PUSH);
refspec_init(&ret->fetch, REFSPEC_FETCH);
@@ -456,6 +457,8 @@ static int handle_config(const char *key, const char *value,
remote->prune = git_config_bool(key, value);
else if (!strcmp(subkey, "prunetags"))
remote->prune_tags = git_config_bool(key, value);
+ else if (!strcmp(subkey, "prefetch"))
+ remote->prefetch_enabled = git_config_bool(key, value);
else if (!strcmp(subkey, "url")) {
if (!value)
return config_error_nonbool(key);
@@ -77,6 +77,8 @@ struct remote {
struct refspec fetch;
+ int prefetch_enabled;
+
/*
* The setting for whether to fetch tags (as a separate rule from the
* configured refspecs);
@@ -245,6 +245,48 @@ test_expect_success 'prefetch multiple remotes' '
test_subcommand git fetch remote2 $fetchargs <skip-remote1.txt
'
+test_expect_success 'prefetch respects remote.*.prefetch config' '
+ test_create_repo prefetch-test-config &&
+ (
+ cd prefetch-test-config &&
+ test_commit initial &&
+ test_create_repo clone1 &&
+ test_create_repo clone2 &&
+ test_create_repo clone3 &&
+
+ git remote add remote1 "file://$(pwd)/clone1" &&
+ git remote add remote2 "file://$(pwd)/clone2" &&
+ git remote add remote3 "file://$(pwd)/clone3" &&
+
+ git config remote.remote1.prefetch false &&
+ git config remote.remote2.prefetch true &&
+ # remote3 is left unset
+
+ # Make changes in all clones
+ git -C clone1 switch -c one &&
+ git -C clone2 switch -c two &&
+ git -C clone3 switch -c three &&
+ test_commit -C clone1 one &&
+ test_commit -C clone2 two &&
+ test_commit -C clone3 three &&
+
+ # Run maintenance prefetch task
+ GIT_TRACE2_EVENT="$(pwd)/prefetch.txt" git maintenance run --task=prefetch 2>/dev/null &&
+
+ # Check that if remotes were prefetched properly
+ fetchargs="--prefetch --prune --no-tags --no-write-fetch-head --recurse-submodules=no --quiet" &&
+ test_subcommand ! git fetch remote1 $fetchargs <prefetch.txt &&
+ test_subcommand git fetch remote2 $fetchargs <prefetch.txt &&
+ test_subcommand git fetch remote3 $fetchargs <prefetch.txt &&
+
+ # Verify that changes are in the prefetch refs for remote2 and remote3, but not remote1
+ test_must_fail git rev-parse refs/prefetch/remotes/remote1/one &&
+ git fetch --all &&
+ test_cmp_rev refs/remotes/remote2/two refs/prefetch/remotes/remote2/two &&
+ test_cmp_rev refs/remotes/remote3/three refs/prefetch/remotes/remote3/three
+ )
+'
+
test_expect_success 'loose-objects task' '
# Repack everything so we know the state of the object dir
git repack -adk &&