File 0002-fetch-pack-in-protocol-v2-in_vain-only-after-ACK.patch of Package git (Revision a4558c0cae9a3f79701ca85225231a67)
Currently displaying revision a4558c0cae9a3f79701ca85225231a67 , Show latest
129
1
From cbfc00c0a924a625f29a8f696d1592785d0ed953 Mon Sep 17 00:00:00 2001
2
From: Jonathan Tan <jonathantanmy@google.com>
3
Date: Mon, 27 Apr 2020 17:01:09 -0700
4
Subject: [PATCH] fetch-pack: in protocol v2, in_vain only after ACK
5
6
References: bsc#1170741
7
Upstream: queued - expected 2.26.3
8
9
When fetching, Git stops negotiation when it has sent at least
10
MAX_IN_VAIN (which is 256) "have" lines without having any of them
11
ACK-ed. But this is supposed to trigger only after the first ACK, as
12
pack-protocol.txt says:
13
14
However, the 256 limit *only* turns on in the canonical client
15
implementation if we have received at least one "ACK %s continue"
16
during a prior round. This helps to ensure that at least one common
17
ancestor is found before we give up entirely.
18
19
The code path for protocol v0 observes this, but not protocol v2,
20
resulting in shorter negotiation rounds but significantly larger
21
packfiles. Teach the code path for protocol v2 to check this criterion
22
only after at least one ACK was received.
23
24
Signed-off-by: Jonathan Tan <jonathantanmy@google.com>
25
Signed-off-by: Junio C Hamano <gitster@pobox.com>
26
---
27
fetch-pack.c | 13 +++++++++----
28
t/t5500-fetch-pack.sh | 18 ++++++++++++++++++
29
2 files changed, 27 insertions(+), 4 deletions(-)
30
31
diff --git a/fetch-pack.c b/fetch-pack.c
32
index ffdec5e56b..8f50f6a248 100644
33
--- a/fetch-pack.c
34
+++ b/fetch-pack.c
35
36
}
37
38
static int add_haves(struct fetch_negotiator *negotiator,
39
+ int seen_ack,
40
struct strbuf *req_buf,
41
int *haves_to_send, int *in_vain)
42
{
43
44
}
45
46
*in_vain += haves_added;
47
- if (!haves_added || *in_vain >= MAX_IN_VAIN) {
48
+ if (!haves_added || (seen_ack && *in_vain >= MAX_IN_VAIN)) {
49
/* Send Done */
50
packet_buf_write(req_buf, "done\n");
51
ret = 1;
52
53
struct fetch_pack_args *args,
54
const struct ref *wants, struct oidset *common,
55
int *haves_to_send, int *in_vain,
56
- int sideband_all)
57
+ int sideband_all, int seen_ack)
58
{
59
int ret = 0;
60
struct strbuf req_buf = STRBUF_INIT;
61
62
add_common(&req_buf, common);
63
64
/* Add initial haves */
65
- ret = add_haves(negotiator, &req_buf, haves_to_send, in_vain);
66
+ ret = add_haves(negotiator, seen_ack, &req_buf,
67
+ haves_to_send, in_vain);
68
}
69
70
/* Send request */
71
72
int haves_to_send = INITIAL_FLUSH;
73
struct fetch_negotiator negotiator_alloc;
74
struct fetch_negotiator *negotiator;
75
+ int seen_ack = 0;
76
77
if (args->no_dependents) {
78
negotiator = NULL;
79
80
if (send_fetch_request(negotiator, fd[1], args, ref,
81
&common,
82
&haves_to_send, &in_vain,
83
- reader.use_sideband))
84
+ reader.use_sideband,
85
+ seen_ack))
86
state = FETCH_GET_PACK;
87
else
88
state = FETCH_PROCESS_ACKS;
89
90
break;
91
case COMMON_FOUND:
92
in_vain = 0;
93
+ seen_ack = 1;
94
/* fallthrough */
95
case NO_COMMON_FOUND:
96
state = FETCH_SEND_REQUEST;
97
diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh
98
index 6b97923964..95ed08db1b 100755
99
--- a/t/t5500-fetch-pack.sh
100
+++ b/t/t5500-fetch-pack.sh
101
102
test_cmp count8.expected count8.actual
103
'
104
105
+test_expect_success 'in_vain not triggered before first ACK' '
106
+ rm -rf myserver myclient trace &&
107
+ git init myserver &&
108
+ test_commit -C myserver foo &&
109
+ git clone "file://$(pwd)/myserver" myclient &&
110
+
111
+ # MAX_IN_VAIN is 256. Because of batching, the client will send 496
112
+ # (16+32+64+128+256) commits, not 256, before giving up. So create 496
113
+ # irrelevant commits.
114
+ test_commit_bulk -C myclient 496 &&
115
+
116
+ # The new commit that the client wants to fetch.
117
+ test_commit -C myserver bar &&
118
+
119
+ GIT_TRACE_PACKET="$(pwd)/trace" git -C myclient fetch --progress origin &&
120
+ test_i18ngrep "Total 3 " trace
121
+'
122
+
123
test_expect_success 'fetch in shallow repo unreachable shallow objects' '
124
(
125
git clone --bare --branch B --single-branch "file://$(pwd)/." no-reflog &&
126
--
127
2.26.1
128
129