fetch-pack: add refetch
Allow a "refetch" where the contents of the local object store are ignored and a full fetch is performed, not attempting to find or negotiate common commits with the remote. A key use case is to apply a new partial clone blob/tree filter and refetch all the associated matching content, which would otherwise not be transferred when the commit objects are already present locally. Signed-off-by: Robert Coup <robert@coup.net.nz> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Robert Coup committed
Mar 28, 2022 at 14:02 UTC
4dfd0925cbba78cc737e3af29faa5774bbc7b6a3
2 files changed
+30
-17
fetch-pack.c
+29
-17
@@ -312,19 +312,21 @@ static int find_common(struct fetch_negotiator *negotiator,
312
const char *remote_hex;
313
struct object *o;
314
315
- /*
316
- * If that object is complete (i.e. it is an ancestor of a
317
- * local ref), we tell them we have it but do not have to
318
- * tell them about its ancestors, which they already know
319
- * about.
320
- *
321
- * We use lookup_object here because we are only
322
- * interested in the case we *know* the object is
323
- * reachable and we have already scanned it.
324
- */
325
- if (((o = lookup_object(the_repository, remote)) != NULL) &&
326
- (o->flags & COMPLETE)) {
327
- continue;
315
+ if (!args->refetch) {
316
+ /*
317
+ * If that object is complete (i.e. it is an ancestor of a
318
+ * local ref), we tell them we have it but do not have to
319
+ * tell them about its ancestors, which they already know
320
+ * about.
321
+ *
322
+ * We use lookup_object here because we are only
323
+ * interested in the case we *know* the object is
324
+ * reachable and we have already scanned it.
325
+ */
326
+ if (((o = lookup_object(the_repository, remote)) != NULL) &&
327
+ (o->flags & COMPLETE)) {
328
+ continue;
329
+ }
330
}
331
332
remote_hex = oid_to_hex(remote);
@@ -692,6 +694,9 @@ static void mark_complete_and_common_ref(struct fetch_negotiator *negotiator,
694
int old_save_commit_buffer = save_commit_buffer;
695
timestamp_t cutoff = 0;
696
697
+ if (args->refetch)
698
+ return;
699
+
700
save_commit_buffer = 0;
701
702
trace2_region_enter("fetch-pack", "parse_remote_refs_and_find_cutoff", NULL);
@@ -1028,7 +1033,11 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
1033
struct fetch_negotiator *negotiator;
1034
1035
negotiator = &negotiator_alloc;
1031
- fetch_negotiator_init(r, negotiator);
1036
+ if (args->refetch) {
1037
+ fetch_negotiator_init_noop(negotiator);
1038
+ } else {
1039
+ fetch_negotiator_init(r, negotiator);
1040
+ }
1041
1042
sort_ref_list(&ref, ref_compare_name);
1043
QSORT(sought, nr_sought, cmp_ref_by_name);
@@ -1121,7 +1130,7 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
1130
1131
mark_complete_and_common_ref(negotiator, args, &ref);
1132
filter_refs(args, &ref, sought, nr_sought);
1124
- if (everything_local(args, &ref)) {
1133
+ if (!args->refetch && everything_local(args, &ref)) {
1134
packet_flush(fd[1]);
1135
goto all_done;
1136
}
@@ -1587,7 +1596,10 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
1596
struct strvec index_pack_args = STRVEC_INIT;
1597
1598
negotiator = &negotiator_alloc;
1590
- fetch_negotiator_init(r, negotiator);
1599
+ if (args->refetch)
1600
+ fetch_negotiator_init_noop(negotiator);
1601
+ else
1602
+ fetch_negotiator_init(r, negotiator);
1603
1604
packet_reader_init(&reader, fd[0], NULL, 0,
1605
PACKET_READ_CHOMP_NEWLINE |
@@ -1613,7 +1625,7 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
1625
/* Filter 'ref' by 'sought' and those that aren't local */
1626
mark_complete_and_common_ref(negotiator, args, &ref);
1627
filter_refs(args, &ref, sought, nr_sought);
1616
- if (everything_local(args, &ref))
1628
+ if (!args->refetch && everything_local(args, &ref))
1629
state = FETCH_DONE;
1630
else
1631
state = FETCH_SEND_REQUEST;
fetch-pack.h
+1
@@ -42,6 +42,7 @@ struct fetch_pack_args {
42
unsigned update_shallow:1;
43
unsigned reject_shallow_remote:1;
44
unsigned deepen:1;
45
+ unsigned refetch:1;
46
47
/*
48
* Indicate that the remote of this request is a promisor remote. The