Skip to content

Commit a6e3839

Browse files
committed
Merge branch 'jt/upload-pack-deepen-relative-proto-v2'
"git fetch --deepen=<more>" has been corrected to work over v2 protocol. * jt/upload-pack-deepen-relative-proto-v2: upload-pack: teach deepen-relative in protocol v2 fetch-pack: do not take shallow lock unnecessarily
2 parents 424a665 + 5056cf4 commit a6e3839

File tree

4 files changed

+80
-4
lines changed

4 files changed

+80
-4
lines changed

fetch-pack.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,6 +1007,8 @@ static void add_shallow_requests(struct strbuf *req_buf,
10071007
packet_buf_write(req_buf, "deepen-not %s", s->string);
10081008
}
10091009
}
1010+
if (args->deepen_relative)
1011+
packet_buf_write(req_buf, "deepen-relative\n");
10101012
}
10111013

10121014
static void add_wants(int no_dependents, const struct ref *wants, struct strbuf *req_buf)
@@ -1232,6 +1234,8 @@ static int process_acks(struct fetch_negotiator *negotiator,
12321234
static void receive_shallow_info(struct fetch_pack_args *args,
12331235
struct packet_reader *reader)
12341236
{
1237+
int line_received = 0;
1238+
12351239
process_section_header(reader, "shallow-info", 0);
12361240
while (packet_reader_read(reader) == PACKET_READ_NORMAL) {
12371241
const char *arg;
@@ -1241,6 +1245,7 @@ static void receive_shallow_info(struct fetch_pack_args *args,
12411245
if (get_oid_hex(arg, &oid))
12421246
die(_("invalid shallow line: %s"), reader->line);
12431247
register_shallow(the_repository, &oid);
1248+
line_received = 1;
12441249
continue;
12451250
}
12461251
if (skip_prefix(reader->line, "unshallow ", &arg)) {
@@ -1253,6 +1258,7 @@ static void receive_shallow_info(struct fetch_pack_args *args,
12531258
die(_("error in object: %s"), reader->line);
12541259
if (unregister_shallow(&oid))
12551260
die(_("no shallow found: %s"), reader->line);
1261+
line_received = 1;
12561262
continue;
12571263
}
12581264
die(_("expected shallow/unshallow, got %s"), reader->line);
@@ -1262,8 +1268,11 @@ static void receive_shallow_info(struct fetch_pack_args *args,
12621268
reader->status != PACKET_READ_DELIM)
12631269
die(_("error processing shallow info: %d"), reader->status);
12641270

1265-
setup_alternate_shallow(&shallow_lock, &alternate_shallow_file, NULL);
1266-
args->deepen = 1;
1271+
if (line_received) {
1272+
setup_alternate_shallow(&shallow_lock, &alternate_shallow_file,
1273+
NULL);
1274+
args->deepen = 1;
1275+
}
12671276
}
12681277

12691278
static void receive_wanted_refs(struct packet_reader *reader,

shallow.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,13 @@ int register_shallow(struct repository *r, const struct object_id *oid)
4343

4444
int is_repository_shallow(struct repository *r)
4545
{
46+
/*
47+
* NEEDSWORK: This function updates
48+
* r->parsed_objects->{is_shallow,shallow_stat} as a side effect but
49+
* there is no corresponding function to clear them when the shallow
50+
* file is updated.
51+
*/
52+
4653
FILE *fp;
4754
char buf[1024];
4855
const char *path = r->parsed_objects->alternate_shallow_file;

t/t5702-protocol-v2.sh

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,53 @@ test_expect_success 'upload-pack respects client shallows' '
471471
grep "fetch< version 2" trace
472472
'
473473

474+
test_expect_success 'ensure that multiple fetches in same process from a shallow repo works' '
475+
rm -rf server client trace &&
476+
477+
test_create_repo server &&
478+
test_commit -C server one &&
479+
test_commit -C server two &&
480+
test_commit -C server three &&
481+
git clone --shallow-exclude two "file://$(pwd)/server" client &&
482+
483+
git -C server tag -a -m "an annotated tag" twotag two &&
484+
485+
# Triggers tag following (thus, 2 fetches in one process)
486+
GIT_TRACE_PACKET="$(pwd)/trace" git -C client -c protocol.version=2 \
487+
fetch --shallow-exclude one origin &&
488+
# Ensure that protocol v2 is used
489+
grep "fetch< version 2" trace
490+
'
491+
492+
test_expect_success 'deepen-relative' '
493+
rm -rf server client trace &&
494+
495+
test_create_repo server &&
496+
test_commit -C server one &&
497+
test_commit -C server two &&
498+
test_commit -C server three &&
499+
git clone --depth 1 "file://$(pwd)/server" client &&
500+
test_commit -C server four &&
501+
502+
# Sanity check that only "three" is downloaded
503+
git -C client log --pretty=tformat:%s master >actual &&
504+
echo three >expected &&
505+
test_cmp expected actual &&
506+
507+
GIT_TRACE_PACKET="$(pwd)/trace" git -C client -c protocol.version=2 \
508+
fetch --deepen=1 origin &&
509+
# Ensure that protocol v2 is used
510+
grep "fetch< version 2" trace &&
511+
512+
git -C client log --pretty=tformat:%s origin/master >actual &&
513+
cat >expected <<-\EOF &&
514+
four
515+
three
516+
two
517+
EOF
518+
test_cmp expected actual
519+
'
520+
474521
# Test protocol v2 with 'http://' transport
475522
#
476523
. "$TEST_DIRECTORY"/lib-httpd.sh

upload-pack.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@
4343

4444
static timestamp_t oldest_have;
4545

46-
static int deepen_relative;
4746
static int multi_ack;
4847
static int no_done;
4948
static int use_thin_pack, use_ofs_delta, use_include_tag;
@@ -662,6 +661,9 @@ static void send_unshallow(const struct object_array *shallows,
662661
}
663662
}
664663

664+
static int check_ref(const char *refname_full, const struct object_id *oid,
665+
int flag, void *cb_data);
666+
665667
static void deepen(int depth, int deepen_relative,
666668
struct object_array *shallows, struct object_array *want_obj)
667669
{
@@ -676,6 +678,13 @@ static void deepen(int depth, int deepen_relative,
676678
struct object_array reachable_shallows = OBJECT_ARRAY_INIT;
677679
struct commit_list *result;
678680

681+
/*
682+
* Checking for reachable shallows requires that our refs be
683+
* marked with OUR_REF.
684+
*/
685+
head_ref_namespaced(check_ref, NULL);
686+
for_each_namespaced_ref(check_ref, NULL);
687+
679688
get_reachable_list(shallows, &reachable_shallows);
680689
result = get_shallow_commits(&reachable_shallows,
681690
depth + 1,
@@ -712,6 +721,7 @@ static void deepen_by_rev_list(int ac, const char **av,
712721
static int send_shallow_list(int depth, int deepen_rev_list,
713722
timestamp_t deepen_since,
714723
struct string_list *deepen_not,
724+
int deepen_relative,
715725
struct object_array *shallows,
716726
struct object_array *want_obj)
717727
{
@@ -834,6 +844,7 @@ static void receive_needs(struct object_array *want_obj)
834844
int has_non_tip = 0;
835845
timestamp_t deepen_since = 0;
836846
int deepen_rev_list = 0;
847+
int deepen_relative = 0;
837848

838849
shallow_nr = 0;
839850
for (;;) {
@@ -925,7 +936,8 @@ static void receive_needs(struct object_array *want_obj)
925936
return;
926937

927938
if (send_shallow_list(depth, deepen_rev_list, deepen_since,
928-
&deepen_not, &shallows, want_obj))
939+
&deepen_not, deepen_relative, &shallows,
940+
want_obj))
929941
packet_flush(1);
930942
object_array_clear(&shallows);
931943
}
@@ -1398,6 +1410,7 @@ static void send_shallow_info(struct upload_pack_data *data,
13981410

13991411
if (!send_shallow_list(data->depth, data->deepen_rev_list,
14001412
data->deepen_since, &data->deepen_not,
1413+
data->deepen_relative,
14011414
&data->shallows, want_obj) &&
14021415
is_repository_shallow(the_repository))
14031416
deepen(INFINITE_DEPTH, data->deepen_relative, &data->shallows,

0 commit comments

Comments
 (0)