@@ -400,8 +400,7 @@ static int unbundle_from_file(struct repository *r, const char *file)
refs_update_ref(get_main_ref_store(the_repository),
"fetched bundle", bundle_ref.buf, oid,
has_old ? &old_oid : NULL,
- REF_SKIP_OID_VERIFICATION,
- UPDATE_REFS_MSG_ON_ERR);
+ 0, UPDATE_REFS_MSG_ON_ERR);
}
bundle_header_release(&header);
@@ -3,6 +3,7 @@
test_description='test fetching bundles with --bundle-uri'
. ./test-lib.sh
+. "$TEST_DIRECTORY"/lib-bundle.sh
test_expect_success 'fail to clone from non-existent file' '
test_when_finished rm -rf test &&
@@ -19,10 +20,24 @@ test_expect_success 'fail to clone from non-bundle file' '
test_expect_success 'create bundle' '
git init clone-from &&
- git -C clone-from checkout -b topic &&
- test_commit -C clone-from A &&
- test_commit -C clone-from B &&
- git -C clone-from bundle create B.bundle topic
+ (
+ cd clone-from &&
+ git checkout -b topic &&
+
+ test_commit A &&
+ git bundle create A.bundle topic &&
+
+ test_commit B &&
+ git bundle create B.bundle topic &&
+
+ # Create a bundle with reference pointing to non-existent object.
+ commit_a=$(git rev-parse A) &&
+ commit_b=$(git rev-parse B) &&
+ sed -e "/^$/q" -e "s/$commit_a /$commit_b /" \
+ <A.bundle >bad-header.bundle &&
+ convert_bundle_to_pack \
+ <A.bundle >>bad-header.bundle
+ )
'
test_expect_success 'clone with path bundle' '
@@ -33,6 +48,16 @@ test_expect_success 'clone with path bundle' '
test_cmp expect actual
'
+test_expect_success 'clone with bundle that has bad header' '
+ # Write bundle ref fails, but clone can still proceed.
+ git clone --bundle-uri="clone-from/bad-header.bundle" \
+ clone-from clone-bad-header 2>err &&
+ commit_b=$(git -C clone-from rev-parse B) &&
+ test_grep "trying to write ref '\''refs/bundles/topic'\'' with nonexistent object $commit_b" err &&
+ git -C clone-bad-header for-each-ref --format="%(refname)" >refs &&
+ test_grep ! "refs/bundles/" refs
+'
+
test_expect_success 'clone with path bundle and non-default hash' '
test_when_finished "rm -rf clone-path-non-default-hash" &&
GIT_DEFAULT_HASH=sha256 git clone --bundle-uri="clone-from/B.bundle" \
@@ -259,6 +284,128 @@ test_expect_success 'clone bundle list (file, any mode, all failures)' '
! grep "refs/bundles/" refs
'
+test_expect_success 'negotiation: bundle with part of wanted commits' '
+ test_when_finished "rm -f trace*.txt" &&
+ GIT_TRACE_PACKET="$(pwd)/trace-packet.txt" \
+ git clone --no-local --bundle-uri="clone-from/A.bundle" \
+ clone-from nego-bundle-part &&
+ git -C nego-bundle-part for-each-ref --format="%(refname)" >refs &&
+ grep "refs/bundles/" refs >actual &&
+ test_write_lines refs/bundles/topic >expect &&
+ test_cmp expect actual &&
+ # Ensure that refs/bundles/topic are sent as "have".
+ tip=$(git -C clone-from rev-parse A) &&
+ test_grep "clone> have $tip" trace-packet.txt
+'
+
+test_expect_success 'negotiation: bundle with all wanted commits' '
+ test_when_finished "rm -f trace*.txt" &&
+ GIT_TRACE_PACKET="$(pwd)/trace-packet.txt" \
+ git clone --no-local --single-branch --branch=topic --no-tags \
+ --bundle-uri="clone-from/B.bundle" \
+ clone-from nego-bundle-all &&
+ git -C nego-bundle-all for-each-ref --format="%(refname)" >refs &&
+ grep "refs/bundles/" refs >actual &&
+ test_write_lines refs/bundles/topic >expect &&
+ test_cmp expect actual &&
+ # We already have all needed commits so no "want" needed.
+ test_grep ! "clone> want " trace-packet.txt
+'
+
+test_expect_success 'negotiation: bundle list (no heuristic)' '
+ test_when_finished "rm -f trace*.txt" &&
+ cat >bundle-list <<-EOF &&
+ [bundle]
+ version = 1
+ mode = all
+
+ [bundle "bundle-1"]
+ uri = file://$(pwd)/clone-from/bundle-1.bundle
+
+ [bundle "bundle-2"]
+ uri = file://$(pwd)/clone-from/bundle-2.bundle
+ EOF
+
+ GIT_TRACE_PACKET="$(pwd)/trace-packet.txt" \
+ git clone --no-local --bundle-uri="file://$(pwd)/bundle-list" \
+ clone-from nego-bundle-list-no-heuristic &&
+
+ git -C nego-bundle-list-no-heuristic for-each-ref --format="%(refname)" >refs &&
+ grep "refs/bundles/" refs >actual &&
+ cat >expect <<-\EOF &&
+ refs/bundles/base
+ refs/bundles/left
+ EOF
+ test_cmp expect actual &&
+ tip=$(git -C nego-bundle-list-no-heuristic rev-parse refs/bundles/left) &&
+ test_grep "clone> have $tip" trace-packet.txt
+'
+
+test_expect_success 'negotiation: bundle list (creationToken)' '
+ test_when_finished "rm -f trace*.txt" &&
+ cat >bundle-list <<-EOF &&
+ [bundle]
+ version = 1
+ mode = all
+ heuristic = creationToken
+
+ [bundle "bundle-1"]
+ uri = file://$(pwd)/clone-from/bundle-1.bundle
+ creationToken = 1
+
+ [bundle "bundle-2"]
+ uri = file://$(pwd)/clone-from/bundle-2.bundle
+ creationToken = 2
+ EOF
+
+ GIT_TRACE_PACKET="$(pwd)/trace-packet.txt" \
+ git clone --no-local --bundle-uri="file://$(pwd)/bundle-list" \
+ clone-from nego-bundle-list-heuristic &&
+
+ git -C nego-bundle-list-heuristic for-each-ref --format="%(refname)" >refs &&
+ grep "refs/bundles/" refs >actual &&
+ cat >expect <<-\EOF &&
+ refs/bundles/base
+ refs/bundles/left
+ EOF
+ test_cmp expect actual &&
+ tip=$(git -C nego-bundle-list-heuristic rev-parse refs/bundles/left) &&
+ test_grep "clone> have $tip" trace-packet.txt
+'
+
+test_expect_success 'negotiation: bundle list with all wanted commits' '
+ test_when_finished "rm -f trace*.txt" &&
+ cat >bundle-list <<-EOF &&
+ [bundle]
+ version = 1
+ mode = all
+ heuristic = creationToken
+
+ [bundle "bundle-1"]
+ uri = file://$(pwd)/clone-from/bundle-1.bundle
+ creationToken = 1
+
+ [bundle "bundle-2"]
+ uri = file://$(pwd)/clone-from/bundle-2.bundle
+ creationToken = 2
+ EOF
+
+ GIT_TRACE_PACKET="$(pwd)/trace-packet.txt" \
+ git clone --no-local --single-branch --branch=left --no-tags \
+ --bundle-uri="file://$(pwd)/bundle-list" \
+ clone-from nego-bundle-list-all &&
+
+ git -C nego-bundle-list-all for-each-ref --format="%(refname)" >refs &&
+ grep "refs/bundles/" refs >actual &&
+ cat >expect <<-\EOF &&
+ refs/bundles/base
+ refs/bundles/left
+ EOF
+ test_cmp expect actual &&
+ # We already have all needed commits so no "want" needed.
+ test_grep ! "clone> want " trace-packet.txt
+'
+
#########################################################################
# HTTP tests begin here