File descriptors 3 and 4 are special in our test suite, as
they link back to the test script's original stdout and
stderr. Normally this isn't something tests need to worry
about: they are free to clobber these descriptors for
sub-commands without affecting the overall script.
But there's one very special thing about descriptor 4: since
d88785e424 (test-lib: set BASH_XTRACEFD automatically,
2016-05-11), we ask bash to output "set -x" output to it by
number. This goes to _any_ descriptor 4, even if it no
longer points to the place it did when we set BASH_XTRACEFD.
But in t5615, we run a shell loop with descriptor 4
redirected.  As a result, t5615 works with non-bash shells
even with "-x". And it works with bash without "-x". But the
combination of "bash t5615-alternate-env.sh -x" gets a test
failure (because our "set -x" output pollutes one of the
files).
We can fix this by using any descriptor _except_ the magical
4. So let's switch arbitrarily to using 5/6 in this loop,
not 3/4.
Another alternative is to use a different descriptor for
BASH_XTRACEFD. But picking an unused one turns out to be
hard. Most shells limit us to 9 numbered descriptors. Bash
can handle more, but:
  - while the BASH_XTRACEFD is specific to bash, GIT_TRACE=4
    has a similar problem, and would affect all shells
  - constructs like "999>/dev/null" are synticatically
    invalid to non-bash shells. So we have to actually bury
    it inside an eval, which creates more complications.
Of the numbers 1-9, you might think that "9" would be less
used than "4". But it's not; many of our scripts use
descriptors 8 and 9 (probably under the assumption that they
are high and therefore unused). The least-used descriptor is
currently "7". We could switch to that, but we're just
trading one magic number for another.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
		
	
		
			
				
	
	
		
			91 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			91 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
#!/bin/sh
 | 
						|
 | 
						|
test_description='handling of alternates in environment variables'
 | 
						|
. ./test-lib.sh
 | 
						|
 | 
						|
check_obj () {
 | 
						|
	alt=$1; shift
 | 
						|
	while read obj expect
 | 
						|
	do
 | 
						|
		echo "$obj" >&5 &&
 | 
						|
		echo "$obj $expect" >&6
 | 
						|
	done 5>input 6>expect &&
 | 
						|
	GIT_ALTERNATE_OBJECT_DIRECTORIES=$alt \
 | 
						|
		git "$@" cat-file --batch-check='%(objectname) %(objecttype)' \
 | 
						|
		<input >actual &&
 | 
						|
	test_cmp expect actual
 | 
						|
}
 | 
						|
 | 
						|
test_expect_success 'create alternate repositories' '
 | 
						|
	git init --bare one.git &&
 | 
						|
	one=$(echo one | git -C one.git hash-object -w --stdin) &&
 | 
						|
	git init --bare two.git &&
 | 
						|
	two=$(echo two | git -C two.git hash-object -w --stdin)
 | 
						|
'
 | 
						|
 | 
						|
test_expect_success 'objects inaccessible without alternates' '
 | 
						|
	check_obj "" <<-EOF
 | 
						|
	$one missing
 | 
						|
	$two missing
 | 
						|
	EOF
 | 
						|
'
 | 
						|
 | 
						|
test_expect_success 'access alternate via absolute path' '
 | 
						|
	check_obj "$PWD/one.git/objects" <<-EOF
 | 
						|
	$one blob
 | 
						|
	$two missing
 | 
						|
	EOF
 | 
						|
'
 | 
						|
 | 
						|
test_expect_success 'access multiple alternates' '
 | 
						|
	check_obj "$PWD/one.git/objects:$PWD/two.git/objects" <<-EOF
 | 
						|
	$one blob
 | 
						|
	$two blob
 | 
						|
	EOF
 | 
						|
'
 | 
						|
 | 
						|
# bare paths are relative from $GIT_DIR
 | 
						|
test_expect_success 'access alternate via relative path (bare)' '
 | 
						|
	git init --bare bare.git &&
 | 
						|
	check_obj "../one.git/objects" -C bare.git <<-EOF
 | 
						|
	$one blob
 | 
						|
	EOF
 | 
						|
'
 | 
						|
 | 
						|
# non-bare paths are relative to top of worktree
 | 
						|
test_expect_success 'access alternate via relative path (worktree)' '
 | 
						|
	git init worktree &&
 | 
						|
	check_obj "../one.git/objects" -C worktree <<-EOF
 | 
						|
	$one blob
 | 
						|
	EOF
 | 
						|
'
 | 
						|
 | 
						|
# path is computed after moving to top-level of worktree
 | 
						|
test_expect_success 'access alternate via relative path (subdir)' '
 | 
						|
	mkdir subdir &&
 | 
						|
	check_obj "one.git/objects" -C subdir <<-EOF
 | 
						|
	$one blob
 | 
						|
	EOF
 | 
						|
'
 | 
						|
 | 
						|
# set variables outside test to avoid quote insanity; the \057 is '/',
 | 
						|
# which doesn't need quoting, but just confirms that de-quoting
 | 
						|
# is working.
 | 
						|
quoted='"one.git\057objects"'
 | 
						|
unquoted='two.git/objects'
 | 
						|
test_expect_success 'mix of quoted and unquoted alternates' '
 | 
						|
	check_obj "$quoted:$unquoted" <<-EOF
 | 
						|
	$one blob
 | 
						|
	$two blob
 | 
						|
	EOF
 | 
						|
'
 | 
						|
 | 
						|
test_expect_success !MINGW 'broken quoting falls back to interpreting raw' '
 | 
						|
	mv one.git \"one.git &&
 | 
						|
	check_obj \"one.git/objects <<-EOF
 | 
						|
	$one blob
 | 
						|
	EOF
 | 
						|
'
 | 
						|
 | 
						|
test_done
 |