Skip to content

Commit b4ce837

Browse files
committed
Merge branch 'jk/fetch-reachability-error-fix' into next
Code clean-up and a fix for "git fetch" by an explicit object name (as opposed to fetching refs by name). * jk/fetch-reachability-error-fix: fetch: do not consider peeled tags as advertised tips remote.c: make singular free_ref() public fetch: use free_refs() pkt-line: prepare buffer before handling ERR packets upload-pack: send ERR packet for non-tip objects t5530: check protocol response for "not our ref" t5516: drop ok=sigpipe from unreachable-want tests
2 parents 1a90728 + 34066f0 commit b4ce837

File tree

7 files changed

+60
-26
lines changed

7 files changed

+60
-26
lines changed

fetch-pack.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -573,9 +573,14 @@ static void filter_refs(struct fetch_pack_args *args,
573573
next = ref->next;
574574

575575
if (starts_with(ref->name, "refs/") &&
576-
check_refname_format(ref->name, 0))
577-
; /* trash */
578-
else {
576+
check_refname_format(ref->name, 0)) {
577+
/*
578+
* trash or a peeled value; do not even add it to
579+
* unmatched list
580+
*/
581+
free_one_ref(ref);
582+
continue;
583+
} else {
579584
while (i < nr_sought) {
580585
int cmp = strcmp(ref->name, sought[i]->name);
581586
if (cmp < 0)
@@ -630,10 +635,7 @@ static void filter_refs(struct fetch_pack_args *args,
630635
}
631636

632637
oidset_clear(&tip_oids);
633-
for (ref = unmatched; ref; ref = next) {
634-
next = ref->next;
635-
free(ref);
636-
}
638+
free_refs(unmatched);
637639

638640
*refs = newlist;
639641
}

pkt-line.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -350,16 +350,17 @@ enum packet_read_status packet_read_with_status(int fd, char **src_buffer,
350350
return PACKET_READ_EOF;
351351
}
352352

353-
if ((options & PACKET_READ_DIE_ON_ERR_PACKET) &&
354-
starts_with(buffer, "ERR "))
355-
die(_("remote error: %s"), buffer + 4);
356-
357353
if ((options & PACKET_READ_CHOMP_NEWLINE) &&
358354
len && buffer[len-1] == '\n')
359355
len--;
360356

361357
buffer[len] = 0;
362358
packet_trace(buffer, len, 0);
359+
360+
if ((options & PACKET_READ_DIE_ON_ERR_PACKET) &&
361+
starts_with(buffer, "ERR "))
362+
die(_("remote error: %s"), buffer + 4);
363+
363364
*pktlen = len;
364365
return PACKET_READ_NORMAL;
365366
}

remote.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -820,11 +820,11 @@ struct ref *copy_ref_list(const struct ref *ref)
820820
return ret;
821821
}
822822

823-
static void free_ref(struct ref *ref)
823+
void free_one_ref(struct ref *ref)
824824
{
825825
if (!ref)
826826
return;
827-
free_ref(ref->peer_ref);
827+
free_one_ref(ref->peer_ref);
828828
free(ref->remote_status);
829829
free(ref->symref);
830830
free(ref);
@@ -835,7 +835,7 @@ void free_refs(struct ref *ref)
835835
struct ref *next;
836836
while (ref) {
837837
next = ref->next;
838-
free_ref(ref);
838+
free_one_ref(ref);
839839
ref = next;
840840
}
841841
}

remote.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,10 @@ int ref_compare_name(const void *, const void *);
131131
int check_ref_type(const struct ref *ref, int flags);
132132

133133
/*
134-
* Frees the entire list and peers of elements.
134+
* Free a single ref and its peer, or an entire list of refs and their peers,
135+
* respectively.
135136
*/
137+
void free_one_ref(struct ref *ref);
136138
void free_refs(struct ref *ref);
137139

138140
struct oid_array;

t/t5516-fetch-push.sh

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1241,18 +1241,19 @@ do
12411241
cd shallow &&
12421242
# Some protocol versions (e.g. 2) support fetching
12431243
# unadvertised objects, so restrict this test to v0.
1244-
test_must_fail ok=sigpipe env GIT_TEST_PROTOCOL_VERSION= \
1245-
git fetch ../testrepo/.git $SHA1_3 &&
1246-
test_must_fail ok=sigpipe env GIT_TEST_PROTOCOL_VERSION= \
1244+
test_must_fail env GIT_TEST_PROTOCOL_VERSION= \
1245+
git fetepo/.git $SHA1_3 &&
1246+
test_must_fail env GIT_TEST_PROTOCOL_VERSION= \
12471247
git fetch ../testrepo/.git $SHA1_1 &&
12481248
git --git-dir=../testrepo/.git config uploadpack.allowreachablesha1inwant true &&
12491249
git fetch ../testrepo/.git $SHA1_1 &&
12501250
git cat-file commit $SHA1_1 &&
12511251
test_must_fail git cat-file commit $SHA1_2 &&
12521252
git fetch ../testrepo/.git $SHA1_2 &&
12531253
git cat-file commit $SHA1_2 &&
1254-
test_must_fail ok=sigpipe env GIT_TEST_PROTOCOL_VERSION= \
1255-
git fetch ../testrepo/.git $SHA1_3
1254+
test_must_fail env GIT_TEST_PROTOCOL_VERSION= \
1255+
git fetch ../testrepo/.git $SHA1_3 2>err &&
1256+
test_i18ngrep "remote error:.*not our ref.*$SHA1_3\$" err
12561257
)
12571258
'
12581259
done
@@ -1284,6 +1285,17 @@ test_expect_success 'fetch follows tags by default' '
12841285
test_cmp expect actual
12851286
'
12861287

1288+
test_expect_success 'peeled advertisements are not considered ref tips' '
1289+
mk_empty testrepo &&
1290+
git -C testrepo commit --allow-empty -m one &&
1291+
git -C testrepo commit --allow-empty -m two &&
1292+
git -C testrepo tag -m foo mytag HEAD^ &&
1293+
oid=$(git -C testrepo rev-parse mytag^{commit}) &&
1294+
test_must_fail env GIT_TEST_PROTOCOL_VERSION= \
1295+
git fetch testrepo $oid 2>err &&
1296+
test_i18ngrep "Server does not allow request for unadvertised object" err
1297+
'
1298+
12871299
test_expect_success 'pushing a specific ref applies remote.$name.push as refmap' '
12881300
mk_test testrepo heads/master &&
12891301
rm -fr src dst &&

t/t5530-upload-pack-error.sh

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,25 @@ test_expect_success 'upload-pack fails due to error in rev-list' '
5757
grep "bad tree object" output.err
5858
'
5959

60-
test_expect_success 'upload-pack error message when bad ref requested' '
60+
test_expect_success 'upload-pack fails due to bad want (no object)' '
6161
6262
printf "0045want %s multi_ack_detailed\n00000009done\n0000" \
6363
"deadbeefdeadbeefdeadbeefdeadbeefdeadbeef" >input &&
6464
test_must_fail git upload-pack . <input >output 2>output.err &&
65-
grep -q "not our ref" output.err &&
66-
! grep -q multi_ack_detailed output.err
65+
grep "not our ref" output.err &&
66+
grep "ERR" output &&
67+
! grep multi_ack_detailed output.err
68+
'
69+
70+
test_expect_success 'upload-pack fails due to bad want (not tip)' '
71+
72+
oid=$(echo an object we have | git hash-object -w --stdin) &&
73+
printf "0045want %s multi_ack_detailed\n00000009done\n0000" \
74+
"$oid" >input &&
75+
test_must_fail git upload-pack . <input >output 2>output.err &&
76+
grep "not our ref" output.err &&
77+
grep "ERR" output &&
78+
! grep multi_ack_detailed output.err
6779
'
6880

6981
test_expect_success 'upload-pack fails due to error in pack-objects enumeration' '

upload-pack.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -592,7 +592,8 @@ static int has_unreachable(struct object_array *src)
592592
return 1;
593593
}
594594

595-
static void check_non_tip(struct object_array *want_obj)
595+
static void check_non_tip(struct object_array *want_obj,
596+
struct packet_writer *writer)
596597
{
597598
int i;
598599

@@ -611,9 +612,13 @@ static void check_non_tip(struct object_array *want_obj)
611612
/* Pick one of them (we know there at least is one) */
612613
for (i = 0; i < want_obj->nr; i++) {
613614
struct object *o = want_obj->objects[i].item;
614-
if (!is_our_ref(o))
615+
if (!is_our_ref(o)) {
616+
packet_writer_error(writer,
617+
"upload-pack: not our ref %s",
618+
oid_to_hex(&o->oid));
615619
die("git upload-pack: not our ref %s",
616620
oid_to_hex(&o->oid));
621+
}
617622
}
618623
}
619624

@@ -936,7 +941,7 @@ static void receive_needs(struct packet_reader *reader, struct object_array *wan
936941
* by another process that handled the initial request.
937942
*/
938943
if (has_non_tip)
939-
check_non_tip(want_obj);
944+
check_non_tip(want_obj, &writer);
940945

941946
if (!use_sideband && daemon_mode)
942947
no_progress = 1;

0 commit comments

Comments
 (0)