Skip to content

Commit 203275d

Browse files
derrickstoleegitster
authored andcommitted
remote: add remote.*.negotiationRestrict config
In a previous change, the --negotiation-restrict command-line option of 'git fetch' was added as a synonym of --negotiation-tips. Both of these options restrict the set of 'haves' the client can send as part of negotiation. This was previously not available via a configuration option. Add a new 'remote.<name>.negotiationRestrict' multi-valued config option that updates 'git fetch <name>' to use these restrictions by default. If the user provides even one --negotiation-restrict argument, then the config is ignored. Signed-off-by: Derrick Stolee <stolee@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 9596a1c commit 203275d

File tree

5 files changed

+67
-2
lines changed

5 files changed

+67
-2
lines changed

Documentation/config/remote.adoc

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,22 @@ priority configuration file (e.g. `.git/config` in a repository) to clear
107107
the values inherited from a lower priority configuration files (e.g.
108108
`$HOME/.gitconfig`).
109109

110+
remote.<name>.negotiationRestrict::
111+
When negotiating with this remote during `git fetch` and `git push`,
112+
restrict the commits advertised as "have" lines to only those
113+
reachable from refs matching the given patterns. This multi-valued
114+
config option behaves like `--negotiation-restrict` on the command
115+
line.
116+
+
117+
Each value is either an exact ref name (e.g. `refs/heads/release`) or a
118+
glob pattern (e.g. `refs/heads/release/*`). The pattern syntax is the
119+
same as for `--negotiation-restrict`.
120+
+
121+
These config values are used as defaults for the `--negotiation-restrict`
122+
command-line option. If `--negotiation-restrict` (or its synonym
123+
`--negotiation-tip`) is specified on the command line, then the config
124+
values are not used.
125+
110126
remote.<name>.followRemoteHEAD::
111127
How linkgit:git-fetch[1] should handle updates to `remotes/<name>/HEAD`
112128
when fetching using the configured refspecs of a remote.

builtin/fetch.c

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1601,6 +1601,19 @@ static struct transport *prepare_transport(struct remote *remote, int deepen,
16011601
else
16021602
warning(_("ignoring %s because the protocol does not support it"),
16031603
"--negotiation-restrict");
1604+
} else if (remote->negotiation_restrict.nr) {
1605+
struct string_list_item *item;
1606+
for_each_string_list_item(item, &remote->negotiation_restrict)
1607+
string_list_append(&negotiation_tip, item->string);
1608+
if (transport->smart_options)
1609+
add_negotiation_restrict_tips(transport->smart_options);
1610+
else {
1611+
struct strbuf config_name = STRBUF_INIT;
1612+
strbuf_addf(&config_name, "remote.%s.negotiationRestrict", remote->name);
1613+
warning(_("ignoring %s because the protocol does not support it"),
1614+
config_name.buf);
1615+
strbuf_release(&config_name);
1616+
}
16041617
}
16051618
return transport;
16061619
}
@@ -2659,8 +2672,12 @@ int cmd_fetch(int argc,
26592672
config.display_format = DISPLAY_FORMAT_PORCELAIN;
26602673
}
26612674

2662-
if (negotiate_only && !negotiation_tip.nr)
2663-
die(_("--negotiate-only needs one or more --negotiation-restrict=*"));
2675+
if (negotiate_only && !negotiation_tip.nr) {
2676+
/*
2677+
* Defer this check: remote.<name>.negotiationRestrict may
2678+
* provide defaults in prepare_transport().
2679+
*/
2680+
}
26642681

26652682
if (deepen_relative) {
26662683
if (deepen_relative < 0)
@@ -2749,6 +2766,9 @@ int cmd_fetch(int argc,
27492766
if (!remote)
27502767
die(_("must supply remote when using --negotiate-only"));
27512768
gtransport = prepare_transport(remote, 1, &filter_options);
2769+
if (!gtransport->smart_options ||
2770+
!gtransport->smart_options->negotiation_restrict_tips)
2771+
die(_("--negotiate-only needs one or more --negotiation-restrict=*"));
27522772
if (gtransport->smart_options) {
27532773
gtransport->smart_options->acked_commits = &acked_commits;
27542774
} else {

remote.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ static struct remote *make_remote(struct remote_state *remote_state,
152152
refspec_init_push(&ret->push);
153153
refspec_init_fetch(&ret->fetch);
154154
string_list_init_dup(&ret->server_options);
155+
string_list_init_dup(&ret->negotiation_restrict);
155156

156157
ALLOC_GROW(remote_state->remotes, remote_state->remotes_nr + 1,
157158
remote_state->remotes_alloc);
@@ -179,6 +180,7 @@ static void remote_clear(struct remote *remote)
179180
FREE_AND_NULL(remote->http_proxy);
180181
FREE_AND_NULL(remote->http_proxy_authmethod);
181182
string_list_clear(&remote->server_options, 0);
183+
string_list_clear(&remote->negotiation_restrict, 0);
182184
}
183185

184186
static void add_merge(struct branch *branch, const char *name)
@@ -562,6 +564,10 @@ static int handle_config(const char *key, const char *value,
562564
} else if (!strcmp(subkey, "serveroption")) {
563565
return parse_transport_option(key, value,
564566
&remote->server_options);
567+
} else if (!strcmp(subkey, "negotiationrestrict")) {
568+
if (!value)
569+
return config_error_nonbool(key);
570+
string_list_append(&remote->negotiation_restrict, value);
565571
} else if (!strcmp(subkey, "followremotehead")) {
566572
const char *no_warn_branch;
567573
if (!strcmp(value, "never"))

remote.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ struct remote {
117117
char *http_proxy_authmethod;
118118

119119
struct string_list server_options;
120+
struct string_list negotiation_restrict;
120121

121122
enum follow_remote_head_settings follow_remote_head;
122123
const char *no_warn_branch;

t/t5510-fetch.sh

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1485,6 +1485,28 @@ test_expect_success '--negotiation-restrict and --negotiation-tip can be mixed'
14851485
check_negotiation_tip
14861486
'
14871487

1488+
test_expect_success 'remote.<name>.negotiationRestrict used as default' '
1489+
setup_negotiation_tip server server 0 &&
1490+
git -C client config --add remote.origin.negotiationRestrict alpha_1 &&
1491+
git -C client config --add remote.origin.negotiationRestrict beta_1 &&
1492+
GIT_TRACE_PACKET="$(pwd)/trace" git -C client fetch \
1493+
origin alpha_s beta_s &&
1494+
check_negotiation_tip
1495+
'
1496+
1497+
test_expect_success 'CLI --negotiation-restrict overrides remote config' '
1498+
setup_negotiation_tip server server 0 &&
1499+
git -C client config --add remote.origin.negotiationRestrict alpha_1 &&
1500+
git -C client config --add remote.origin.negotiationRestrict beta_1 &&
1501+
ALPHA_1=$(git -C client rev-parse alpha_1) &&
1502+
GIT_TRACE_PACKET="$(pwd)/trace" git -C client fetch \
1503+
--negotiation-restrict=alpha_1 \
1504+
origin alpha_s beta_s &&
1505+
test_grep "fetch> have $ALPHA_1" trace &&
1506+
BETA_1=$(git -C client rev-parse beta_1) &&
1507+
test_grep ! "fetch> have $BETA_1" trace
1508+
'
1509+
14881510
test_expect_success SYMLINKS 'clone does not get confused by a D/F conflict' '
14891511
git init df-conflict &&
14901512
(

0 commit comments

Comments
 (0)