2006-05-07 22:19:47 +04:00
|
|
|
#!/bin/sh
|
|
|
|
#
|
|
|
|
# Copyright (C) 2006 Martin Waitz <tali@admingilde.org>
|
|
|
|
#
|
|
|
|
|
|
|
|
test_description='test transitive info/alternate entries'
|
|
|
|
. ./test-lib.sh
|
|
|
|
|
2016-10-03 23:34:05 +03:00
|
|
|
test_expect_success 'preparing first repository' '
|
2016-10-03 23:34:08 +03:00
|
|
|
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
|
|
|
|
)
|
2016-10-03 23:34:05 +03:00
|
|
|
'
|
2006-05-07 22:19:47 +04:00
|
|
|
|
2016-10-03 23:34:05 +03:00
|
|
|
test_expect_success 'preparing second repository' '
|
2016-10-03 23:34:08 +03:00
|
|
|
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
|
|
|
|
)
|
2016-10-03 23:34:05 +03:00
|
|
|
'
|
2006-05-07 22:19:47 +04:00
|
|
|
|
2016-10-03 23:34:05 +03:00
|
|
|
test_expect_success 'preparing third repository' '
|
2016-10-03 23:34:08 +03:00
|
|
|
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
|
|
|
|
)
|
2016-10-03 23:34:05 +03:00
|
|
|
'
|
2006-05-07 22:19:47 +04:00
|
|
|
|
2016-10-03 23:36:18 +03:00
|
|
|
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
|
|
|
|
'
|
|
|
|
|
2016-10-03 23:34:12 +03:00
|
|
|
# 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.
|
2016-10-03 23:34:05 +03:00
|
|
|
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 11:30:41 +04:00
|
|
|
|
2016-10-03 23:34:12 +03:00
|
|
|
test_expect_success 'validity of seventh repository' '
|
|
|
|
git -C G fsck
|
2016-10-03 23:34:05 +03:00
|
|
|
'
|
2006-05-07 22:19:47 +04:00
|
|
|
|
2016-10-03 23:34:12 +03:00
|
|
|
test_expect_success 'invalidity of eighth repository' '
|
|
|
|
test_must_fail git -C H fsck
|
2016-10-03 23:34:05 +03:00
|
|
|
'
|
2006-05-07 22:19:47 +04:00
|
|
|
|
2016-10-03 23:34:05 +03:00
|
|
|
test_expect_success 'breaking of loops' '
|
2016-10-03 23:34:08 +03:00
|
|
|
echo "$(pwd)"/B/.git/objects >>A/.git/objects/info/alternates &&
|
|
|
|
git -C C fsck
|
2016-10-03 23:34:05 +03:00
|
|
|
'
|
2006-05-07 22:19:47 +04:00
|
|
|
|
2016-10-03 23:34:05 +03:00
|
|
|
test_expect_success 'that info/alternates is necessary' '
|
2016-10-03 23:34:08 +03:00
|
|
|
rm -f C/.git/objects/info/alternates &&
|
|
|
|
test_must_fail git -C C fsck
|
2016-10-03 23:34:01 +03:00
|
|
|
'
|
2006-05-07 22:19:47 +04:00
|
|
|
|
2016-10-03 23:34:05 +03:00
|
|
|
test_expect_success 'that relative alternate is possible for current dir' '
|
2016-10-03 23:34:08 +03:00
|
|
|
echo "../../../B/.git/objects" >C/.git/objects/info/alternates &&
|
2016-10-03 23:34:05 +03:00
|
|
|
git fsck
|
|
|
|
'
|
2006-05-07 22:19:47 +04:00
|
|
|
|
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 23:36:22 +03: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
|
2008-02-01 12:50:53 +03:00
|
|
|
'
|
2006-05-07 22:19:47 +04:00
|
|
|
|
2016-10-03 23:36:26 +03: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
|
|
|
|
'
|
|
|
|
|
2006-05-07 22:19:47 +04:00
|
|
|
test_done
|