Skip to content

Commit c14efdd

Browse files
committed
send-pack: pass remote name for push negotiation
When push.negotiate is enabled, send-pack spawns a 'git fetch --negotiate-only' subprocess to discover common commits. Previously this subprocess received only the remote URL, which meant it could not find per-remote config like remote.<name>.haveRefs. Add a remote_name field to send_pack_args, set it from the transport layer where the remote struct is available, and pass the remote name (falling back to the URL) to the negotiation subprocess. This allows the subprocess to resolve remote.<name>.haveRefs for the correct remote. Signed-off-by: Derrick Stolee <stolee@gmail.com>
1 parent fe068c7 commit c14efdd

File tree

4 files changed

+26
-2
lines changed

4 files changed

+26
-2
lines changed

send-pack.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,7 @@ static void reject_invalid_nonce(const char *nonce, int len)
433433

434434
static void get_commons_through_negotiation(struct repository *r,
435435
const char *url,
436+
const char *remote_name,
436437
const struct ref *remote_refs,
437438
struct oid_array *commons)
438439
{
@@ -452,7 +453,12 @@ static void get_commons_through_negotiation(struct repository *r,
452453
nr_negotiation_tip++;
453454
}
454455
}
455-
strvec_push(&child.args, url);
456+
/*
457+
* Use the remote name so the subprocess can find
458+
* remote.<name>.haveRefs config. Fall back to the URL if no
459+
* remote name is available.
460+
*/
461+
strvec_push(&child.args, remote_name ? remote_name : url);
456462

457463
if (!nr_negotiation_tip) {
458464
child_process_clear(&child);
@@ -528,7 +534,8 @@ int send_pack(struct repository *r,
528534
repo_config_get_bool(r, "push.negotiate", &push_negotiate);
529535
if (push_negotiate) {
530536
trace2_region_enter("send_pack", "push_negotiate", r);
531-
get_commons_through_negotiation(r, args->url, remote_refs, &commons);
537+
get_commons_through_negotiation(r, args->url, args->remote_name,
538+
remote_refs, &commons);
532539
trace2_region_leave("send_pack", "push_negotiate", r);
533540
}
534541

send-pack.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ struct repository;
1818

1919
struct send_pack_args {
2020
const char *url;
21+
const char *remote_name;
2122
unsigned verbose:1,
2223
quiet:1,
2324
porcelain:1,

t/t5516-fetch-push.sh

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,21 @@ test_expect_success 'push with negotiation does not attempt to fetch submodules'
254254
! grep "Fetching submodule" err
255255
'
256256

257+
test_expect_success 'push with negotiation and remote.<name>.haveRefs' '
258+
test_when_finished rm -rf haverefs &&
259+
mk_empty haverefs &&
260+
git push haverefs $the_first_commit:refs/remotes/origin/first_commit &&
261+
test_commit -C haverefs unrelated_commit &&
262+
git -C haverefs config receive.hideRefs refs/remotes/origin/first_commit &&
263+
test_when_finished "rm event" &&
264+
GIT_TRACE2_EVENT="$(pwd)/event" \
265+
git -c protocol.version=2 -c push.negotiate=1 \
266+
-c remote.haverefs.haveRefs=refs/heads/main \
267+
push haverefs refs/heads/main:refs/remotes/origin/main &&
268+
test_grep \"key\":\"total_rounds\" event &&
269+
grep_wrote 2 event # 1 commit, 1 tree
270+
'
271+
257272
test_expect_success 'push without wildcard' '
258273
mk_empty testrepo &&
259274

transport.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -921,6 +921,7 @@ static int git_transport_push(struct transport *transport, struct ref *remote_re
921921
args.atomic = !!(flags & TRANSPORT_PUSH_ATOMIC);
922922
args.push_options = transport->push_options;
923923
args.url = transport->url;
924+
args.remote_name = transport->remote->name;
924925

925926
if (flags & TRANSPORT_PUSH_CERT_ALWAYS)
926927
args.push_cert = SEND_PACK_PUSH_CERT_ALWAYS;

0 commit comments

Comments
 (0)