Skip to content

Commit 301f1e3

Browse files
jonathantanmygitster
authored andcommitted
promisor-remote: die upon failing fetch
In a partial clone, an attempt to read a missing object results in an attempt to fetch that single object. In order to avoid multiple sequential fetches, which would occur when multiple objects are missing (which is the typical case), some commands have been taught to prefetch in a batch: such a command would, in a partial clone, notice that several objects that it will eventually need are missing, and call promisor_remote_get_direct() with all such objects at once. When this batch prefetch fails, these commands fall back to the sequential fetches. But at $DAYJOB we have noticed that this results in a bad user experience: a command would take unexpectedly long to finish (and possibly use up a lot of bandwidth) if the batch prefetch would fail for some intermittent reason, but all subsequent fetches would work. It would be a better user experience for such a command would just fail. Therefore, make it a fatal error if the prefetch fails and at least one object being fetched is known to be a promisor object. (The latter criterion is to make sure that we are not misleading the user that such an object would be present from the promisor remote. For example, a missing object may be a result of repository corruption and not because it is expectedly missing due to the repository being a partial clone.) Signed-off-by: Jonathan Tan <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 00057bf commit 301f1e3

File tree

3 files changed

+24
-5
lines changed

3 files changed

+24
-5
lines changed

object-file.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1599,10 +1599,6 @@ static int do_oid_object_info_extended(struct repository *r,
15991599
if (fetch_if_missing && repo_has_promisor_remote(r) &&
16001600
!already_retried &&
16011601
!(flags & OBJECT_INFO_SKIP_FETCH_OBJECT)) {
1602-
/*
1603-
* TODO Investigate checking promisor_remote_get_direct()
1604-
* TODO return value and stopping on error here.
1605-
*/
16061602
promisor_remote_get_direct(r, real, 1);
16071603
already_retried = 1;
16081604
continue;

promisor-remote.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "config.h"
55
#include "transport.h"
66
#include "strvec.h"
7+
#include "packfile.h"
78

89
struct promisor_remote_config {
910
struct promisor_remote *promisors;
@@ -238,6 +239,7 @@ void promisor_remote_get_direct(struct repository *repo,
238239
struct object_id *remaining_oids = (struct object_id *)oids;
239240
int remaining_nr = oid_nr;
240241
int to_free = 0;
242+
int i;
241243

242244
if (oid_nr == 0)
243245
return;
@@ -255,9 +257,16 @@ void promisor_remote_get_direct(struct repository *repo,
255257
continue;
256258
}
257259
}
258-
break;
260+
goto all_fetched;
261+
}
262+
263+
for (i = 0; i < remaining_nr; i++) {
264+
if (is_promisor_object(&remaining_oids[i]))
265+
die(_("could not fetch %s from promisor remote"),
266+
oid_to_hex(&remaining_oids[i]));
259267
}
260268

269+
all_fetched:
261270
if (to_free)
262271
free(remaining_oids);
263272
}

t/t0410-partial-clone.sh

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,20 @@ test_expect_success 'fetching of missing objects' '
215215
grep "$HASH" out
216216
'
217217

218+
test_expect_success 'fetching of a promised object that promisor remote no longer has' '
219+
rm -f err &&
220+
test_create_repo unreliable-server &&
221+
git -C unreliable-server config uploadpack.allowanysha1inwant 1 &&
222+
git -C unreliable-server config uploadpack.allowfilter 1 &&
223+
test_commit -C unreliable-server foo &&
224+
225+
git clone --filter=blob:none --no-checkout "file://$(pwd)/unreliable-server" unreliable-client &&
226+
227+
rm -rf unreliable-server/.git/objects/* &&
228+
test_must_fail git -C unreliable-client checkout HEAD 2>err &&
229+
grep "could not fetch.*from promisor remote" err
230+
'
231+
218232
test_expect_success 'fetching of missing objects works with ref-in-want enabled' '
219233
# ref-in-want requires protocol version 2
220234
git -C server config protocol.version 2 &&

0 commit comments

Comments
 (0)