diff options
| -rwxr-xr-x | t/t5530-upload-pack-error.sh | 68 | ||||
| -rw-r--r-- | upload-pack.c | 19 |
2 files changed, 51 insertions, 36 deletions
diff --git a/t/t5530-upload-pack-error.sh b/t/t5530-upload-pack-error.sh index 558eedf25a..d40292cfb7 100755 --- a/t/t5530-upload-pack-error.sh +++ b/t/t5530-upload-pack-error.sh @@ -4,8 +4,6 @@ test_description='errors in upload-pack' . ./test-lib.sh -D=$(pwd) - corrupt_repo () { object_sha1=$(git rev-parse "$1") && ob=$(expr "$object_sha1" : "\(..\)") && @@ -21,11 +19,7 @@ test_expect_success 'setup and corrupt repository' ' test_tick && echo changed >file && git commit -a -m changed && - corrupt_repo HEAD:file - -' - -test_expect_success 'fsck fails' ' + corrupt_repo HEAD:file && test_must_fail git fsck ' @@ -40,17 +34,12 @@ test_expect_success 'upload-pack fails due to error in pack-objects packing' ' ' test_expect_success 'corrupt repo differently' ' - git hash-object -w file && - corrupt_repo HEAD^^{tree} - -' - -test_expect_success 'fsck fails' ' + corrupt_repo HEAD^^{tree} && test_must_fail git fsck ' -test_expect_success 'upload-pack fails due to error in rev-list' ' +test_expect_success 'upload-pack fails due to error in rev-list' ' printf "%04xwant %s\n%04xshallow %s00000009done\n0000" \ $(($hexsz + 10)) $(git rev-parse HEAD) \ $(($hexsz + 12)) $(git rev-parse HEAD^) >input && @@ -59,7 +48,6 @@ test_expect_success 'upload-pack fails due to error in rev-list' ' ' test_expect_success 'upload-pack fails due to bad want (no object)' ' - printf "%04xwant %s multi_ack_detailed\n00000009done\n0000" \ $(($hexsz + 29)) $(test_oid deadbeef) >input && test_must_fail git upload-pack . <input >output 2>output.err && @@ -69,7 +57,6 @@ test_expect_success 'upload-pack fails due to bad want (no object)' ' ' test_expect_success 'upload-pack fails due to bad want (not tip)' ' - oid=$(echo an object we have | git hash-object -w --stdin) && printf "%04xwant %s multi_ack_detailed\n00000009done\n0000" \ $(($hexsz + 29)) "$oid" >input && @@ -80,7 +67,6 @@ test_expect_success 'upload-pack fails due to bad want (not tip)' ' ' test_expect_success 'upload-pack fails due to error in pack-objects enumeration' ' - printf "%04xwant %s\n00000009done\n0000" \ $((hexsz + 10)) $(git rev-parse HEAD) >input && test_must_fail git upload-pack . <input >/dev/null 2>output.err && @@ -105,18 +91,48 @@ test_expect_success 'upload-pack tolerates EOF just after stateless client wants test_cmp expect actual ' -test_expect_success 'create empty repository' ' - - mkdir foo && - cd foo && - git init - -' - test_expect_success 'fetch fails' ' + git init foo && + test_must_fail git -C foo fetch .. main +' - test_must_fail git fetch .. main +test_expect_success 'upload-pack ACKs repeated non-commit objects repeatedly (protocol v0)' ' + commit_id=$(git rev-parse HEAD) && + tree_id=$(git rev-parse HEAD^{tree}) && + test-tool pkt-line pack >request <<-EOF && + want $commit_id + 0000 + have $tree_id + have $tree_id + 0000 + EOF + git upload-pack --stateless-rpc . <request >actual && + depacketize <actual >actual.raw && + grep ^ACK actual.raw >actual.acks && + cat >expect <<-EOF && + ACK $tree_id + ACK $tree_id + EOF + test_cmp expect actual.acks +' +test_expect_success 'upload-pack ACKs repeated non-commit objects once only (protocol v2)' ' + commit_id=$(git rev-parse HEAD) && + tree_id=$(git rev-parse HEAD^{tree}) && + test-tool pkt-line pack >request <<-EOF && + command=fetch + object-format=$(test_oid algo) + 0001 + want $commit_id + have $tree_id + have $tree_id + 0000 + EOF + GIT_PROTOCOL=version=2 git upload-pack . <request >actual && + depacketize <actual >actual.raw && + grep ^ACK actual.raw >actual.acks && + echo "ACK $tree_id" >expect && + test_cmp expect actual.acks ' test_done diff --git a/upload-pack.c b/upload-pack.c index 91fcdcad9b..f78fabc1e1 100644 --- a/upload-pack.c +++ b/upload-pack.c @@ -476,20 +476,17 @@ static void create_pack_file(struct upload_pack_data *pack_data, static int do_got_oid(struct upload_pack_data *data, const struct object_id *oid) { - int we_knew_they_have = 0; struct object *o = parse_object_with_flags(the_repository, oid, PARSE_OBJECT_SKIP_HASH_CHECK | PARSE_OBJECT_DISCARD_TREE); if (!o) die("oops (%s)", oid_to_hex(oid)); + if (o->type == OBJ_COMMIT) { struct commit_list *parents; struct commit *commit = (struct commit *)o; - if (o->flags & THEY_HAVE) - we_knew_they_have = 1; - else - o->flags |= THEY_HAVE; + if (!data->oldest_have || (commit->date < data->oldest_have)) data->oldest_have = commit->date; for (parents = commit->parents; @@ -497,11 +494,13 @@ static int do_got_oid(struct upload_pack_data *data, const struct object_id *oid parents = parents->next) parents->item->object.flags |= THEY_HAVE; } - if (!we_knew_they_have) { - add_object_array(o, NULL, &data->have_obj); - return 1; - } - return 0; + + if (o->flags & THEY_HAVE) + return 0; + o->flags |= THEY_HAVE; + + add_object_array(o, NULL, &data->have_obj); + return 1; } static int got_oid(struct upload_pack_data *data, |
