git/t/t5613-info-alternate.sh

140 lines
3.9 KiB
Bash
Raw Normal View History

#!/bin/sh
#
# Copyright (C) 2006 Martin Waitz <tali@admingilde.org>
#
test_description='test transitive info/alternate entries'
. ./test-lib.sh
test_expect_success 'preparing first repository' '
test_create_repo A && (
cd A &&
echo "Hello World" > file1 &&
git add file1 &&
git commit -m "Initial commit" file1 &&
git repack -a -d &&
git prune
)
'
test_expect_success 'preparing second repository' '
git clone -l -s A B && (
cd B &&
echo "foo bar" > file2 &&
git add file2 &&
git commit -m "next commit" file2 &&
git repack -a -d -l &&
git prune
)
'
test_expect_success 'preparing third repository' '
git clone -l -s B C && (
cd C &&
echo "Goodbye, cruel world" > file3 &&
git add file3 &&
git commit -m "one more" file3 &&
git repack -a -d -l &&
git prune
)
'
test_expect_success 'count-objects shows the alternates' '
cat >expect <<-EOF &&
alternate: $(pwd)/B/.git/objects
alternate: $(pwd)/A/.git/objects
EOF
git -C C count-objects -v >actual &&
grep ^alternate: actual >actual.alternates &&
test_cmp expect actual.alternates
'
# Note: These tests depend on the hard-coded value of 5 as the maximum depth
# we will follow recursion. We start the depth at 0 and count links, not
# repositories. This means that in a chain like:
#
# A --> B --> C --> D --> E --> F --> G --> H
# 0 1 2 3 4 5 6
#
# we are OK at "G", but break at "H", even though "H" is actually the 8th
# repository, not the 6th, which you might expect. Counting the links allows
# N+1 repositories, and counting from 0 to 5 inclusive allows 6 links.
#
# Note also that we must use "--bare -l" to make the link to H. The "-l"
# ensures we do not do a connectivity check, and the "--bare" makes sure
# we do not try to checkout the result (which needs objects), either of
# which would cause the clone to fail.
test_expect_success 'creating too deep nesting' '
git clone -l -s C D &&
git clone -l -s D E &&
git clone -l -s E F &&
git clone -l -s F G &&
git clone --bare -l -s G H
'
clone: drop connectivity check for local clones Commit 0433ad1 (clone: run check_everything_connected, 2013-03-25) added the same connectivity check to clone that we use for fetching. The intent was to provide enough safety checks that "git clone git://..." could be counted on to detect bit errors and other repo corruption, and not silently propagate them to the clone. For local clones, this turns out to be a bad idea, for two reasons: 1. Local clones use hard linking (or even shared object stores), and so complete far more quickly. The time spent on the connectivity check is therefore proportionally much more painful. 2. Local clones do not actually meet our safety guarantee anyway. The connectivity check makes sure we have all of the objects we claim to, but it does not check for bit errors. We will notice bit errors in commits and trees, but we do not load blob objects at all. Whereas over the pack transport, we actually recompute the sha1 of each object in the incoming packfile; bit errors change the sha1 of the object, which is then caught by the connectivity check. This patch drops the connectivity check in the local case. Note that we have to revert the changes from 0433ad1 to t5710, as we no longer notice the corruption during clone. We could go a step further and provide a "verify even local clones" option, but it is probably not worthwhile. You can already spell that as "cd foo.git && git fsck && git clone ." or as "git clone --no-local foo.git". Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-07-08 07:30:41 +00:00
test_expect_success 'validity of seventh repository' '
git -C G fsck
'
test_expect_success 'invalidity of eighth repository' '
test_must_fail git -C H fsck
'
test_expect_success 'breaking of loops' '
echo "$(pwd)"/B/.git/objects >>A/.git/objects/info/alternates &&
git -C C fsck
'
test_expect_success 'that info/alternates is necessary' '
rm -f C/.git/objects/info/alternates &&
test_must_fail git -C C fsck
'
test_expect_success 'that relative alternate is possible for current dir' '
echo "../../../B/.git/objects" >C/.git/objects/info/alternates &&
git fsck
'
sha1_file: always allow relative paths to alternates We recursively expand alternates repositories, so that if A borrows from B which borrows from C, A can see all objects. For the root object database, we allow relative paths, so A can point to B as "../B/objects". However, we currently do not allow relative paths when recursing, so B must use an absolute path to reach C. That is an ancient protection from c2f493a (Transitively read alternatives, 2006-05-07) that tries to avoid adding the same alternate through two different paths. Since 5bdf0a8 (sha1_file: normalize alt_odb path before comparing and storing, 2011-09-07), we use a normalized absolute path for each alt_odb entry. This means that in most cases the protection is no longer necessary; we will detect the duplicate no matter how we got there (but see below). And it's a good idea to get rid of it, as it creates an unnecessary complication when setting up recursive alternates (B has to know that A is going to borrow from it and make sure to use an absolute path). Note that our normalization doesn't actually look at the filesystem, so it can still be fooled by crossing symbolic links. But that's also true of absolute paths, so it's not a good reason to disallow only relative paths (it's potentially a reason to switch to real_path(), but that's a separate and non-trivial change). We adjust the test script here to demonstrate that this now works, and add new tests to show that the normalization does indeed suppress duplicates. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-10-03 20:36:22 +00:00
test_expect_success 'that relative alternate is recursive' '
git -C D fsck
'
# we can reach "A" from our new repo both directly, and via "C".
# The deep/subdir is there to make sure we are not doing a stupid
# pure-text comparison of the alternate names.
test_expect_success 'relative duplicates are eliminated' '
mkdir -p deep/subdir &&
git init --bare deep/subdir/duplicate.git &&
cat >deep/subdir/duplicate.git/objects/info/alternates <<-\EOF &&
../../../../C/.git/objects
../../../../A/.git/objects
EOF
cat >expect <<-EOF &&
alternate: $(pwd)/C/.git/objects
alternate: $(pwd)/B/.git/objects
alternate: $(pwd)/A/.git/objects
EOF
git -C deep/subdir/duplicate.git count-objects -v >actual &&
grep ^alternate: actual >actual.alternates &&
test_cmp expect actual.alternates
Sane use of test_expect_failure Originally, test_expect_failure was designed to be the opposite of test_expect_success, but this was a bad decision. Most tests run a series of commands that leads to the single command that needs to be tested, like this: test_expect_{success,failure} 'test title' ' setup1 && setup2 && setup3 && what is to be tested ' And expecting a failure exit from the whole sequence misses the point of writing tests. Your setup$N that are supposed to succeed may have failed without even reaching what you are trying to test. The only valid use of test_expect_failure is to check a trivial single command that is expected to fail, which is a minority in tests of Porcelain-ish commands. This large-ish patch rewrites all uses of test_expect_failure to use test_expect_success and rewrites the condition of what is tested, like this: test_expect_success 'test title' ' setup1 && setup2 && setup3 && ! this command should fail ' test_expect_failure is redefined to serve as a reminder that that test *should* succeed but due to a known breakage in git it currently does not pass. So if git-foo command should create a file 'bar' but you discovered a bug that it doesn't, you can write a test like this: test_expect_failure 'git-foo should create bar' ' rm -f bar && git foo && test -f bar ' This construct acts similar to test_expect_success, but instead of reporting "ok/FAIL" like test_expect_success does, the outcome is reported as "FIXED/still broken". Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-02-01 09:50:53 +00:00
'
test_expect_success CASE_INSENSITIVE_FS 'dup finding can be case-insensitive' '
git init --bare insensitive.git &&
# the previous entry for "A" will have used uppercase
cat >insensitive.git/objects/info/alternates <<-\EOF &&
../../C/.git/objects
../../a/.git/objects
EOF
cat >expect <<-EOF &&
alternate: $(pwd)/C/.git/objects
alternate: $(pwd)/B/.git/objects
alternate: $(pwd)/A/.git/objects
EOF
git -C insensitive.git count-objects -v >actual &&
grep ^alternate: actual >actual.alternates &&
test_cmp expect actual.alternates
'
test_done