 7ec30aaa5b
			
		
	
	7ec30aaa5b
	
	
	
		
			
			Commit 1b77d83cab 'setup_git_directory_gently_1(): resolve symlinks
in ceiling paths' changed the setup code to resolve symlinks in the
entries in GIT_CEILING_DIRECTORIES.  Because those entries are
compared textually to the symlink-resolved current directory, an
entry in GIT_CEILING_DIRECTORIES that contained a symlink would have
no effect.  It was known that this could cause performance problems
if the symlink resolution *itself* touched slow filesystems, but it
was thought that such use cases would be unlikely.  The intention of
the earlier change was to deal with a case when the user has this:
	GIT_CEILING_DIRECTORIES=/home/gitster
but in reality, /home/gitster is a symbolic link to somewhere else,
e.g. /net/machine/home4/gitster. A textual comparison between the
specified value /home/gitster and the location getcwd(3) returns
would not help us, but readlink("/home/gitster") would still be
fast.
After this change was released, Anders Kaseorg <andersk@mit.edu>
reported:
> [...] my computer has been acting so slow when I’m not connected to
> the network.  I put various network filesystem paths in
> $GIT_CEILING_DIRECTORIES, such as
> /afs/athena.mit.edu/user/a/n/andersk (to avoid hitting its parents
> /afs/athena.mit.edu, /afs/athena.mit.edu/user/a, and
> /afs/athena.mit.edu/user/a/n which all live in different AFS
> volumes).  Now when I’m not connected to the network, every
> invocation of Git, including the __git_ps1 in my shell prompt, waits
> for AFS to timeout.
To allow users to work around this problem, give them a mechanism to
turn off symlink resolution in GIT_CEILING_DIRECTORIES entries.  All
the entries that follow an empty entry will not be checked for symbolic
links and used literally in comparison.  E.g. with these:
	GIT_CEILING_DIRECTORIES=:/foo/bar:/xyzzy or
	GIT_CEILING_DIRECTORIES=/foo/bar::/xyzzy
we will not readlink("/xyzzy") because it comes after an empty entry.
With the former (but not with the latter), "/foo/bar" comes after an
empty entry, and we will not readlink it, either.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
		
	
		
			
				
	
	
		
			182 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			182 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
| #!/bin/sh
 | |
| 
 | |
| test_description='test GIT_CEILING_DIRECTORIES'
 | |
| . ./test-lib.sh
 | |
| 
 | |
| test_prefix() {
 | |
| 	test_expect_success "$1" \
 | |
| 	"test '$2' = \"\$(git rev-parse --show-prefix)\""
 | |
| }
 | |
| 
 | |
| test_fail() {
 | |
| 	test_expect_success "$1: prefix" '
 | |
| 		test_expect_code 128 git rev-parse --show-prefix
 | |
| 	'
 | |
| }
 | |
| 
 | |
| TRASH_ROOT="$PWD"
 | |
| ROOT_PARENT=$(dirname "$TRASH_ROOT")
 | |
| 
 | |
| 
 | |
| unset GIT_CEILING_DIRECTORIES
 | |
| test_prefix no_ceil ""
 | |
| 
 | |
| export GIT_CEILING_DIRECTORIES
 | |
| 
 | |
| GIT_CEILING_DIRECTORIES=""
 | |
| test_prefix ceil_empty ""
 | |
| 
 | |
| GIT_CEILING_DIRECTORIES="$ROOT_PARENT"
 | |
| test_prefix ceil_at_parent ""
 | |
| 
 | |
| GIT_CEILING_DIRECTORIES="$ROOT_PARENT/"
 | |
| test_prefix ceil_at_parent_slash ""
 | |
| 
 | |
| GIT_CEILING_DIRECTORIES="$TRASH_ROOT"
 | |
| test_prefix ceil_at_trash ""
 | |
| 
 | |
| GIT_CEILING_DIRECTORIES="$TRASH_ROOT/"
 | |
| test_prefix ceil_at_trash_slash ""
 | |
| 
 | |
| GIT_CEILING_DIRECTORIES="$TRASH_ROOT/sub"
 | |
| test_prefix ceil_at_sub ""
 | |
| 
 | |
| GIT_CEILING_DIRECTORIES="$TRASH_ROOT/sub/"
 | |
| test_prefix ceil_at_sub_slash ""
 | |
| 
 | |
| if test_have_prereq SYMLINKS
 | |
| then
 | |
| 	ln -s sub top
 | |
| fi
 | |
| 
 | |
| mkdir -p sub/dir || exit 1
 | |
| cd sub/dir || exit 1
 | |
| 
 | |
| unset GIT_CEILING_DIRECTORIES
 | |
| test_prefix subdir_no_ceil "sub/dir/"
 | |
| 
 | |
| export GIT_CEILING_DIRECTORIES
 | |
| 
 | |
| GIT_CEILING_DIRECTORIES=""
 | |
| test_prefix subdir_ceil_empty "sub/dir/"
 | |
| 
 | |
| GIT_CEILING_DIRECTORIES="$TRASH_ROOT"
 | |
| test_fail subdir_ceil_at_trash
 | |
| 
 | |
| GIT_CEILING_DIRECTORIES="$TRASH_ROOT/"
 | |
| test_fail subdir_ceil_at_trash_slash
 | |
| 
 | |
| GIT_CEILING_DIRECTORIES="$TRASH_ROOT/sub"
 | |
| test_fail subdir_ceil_at_sub
 | |
| 
 | |
| GIT_CEILING_DIRECTORIES="$TRASH_ROOT/sub/"
 | |
| test_fail subdir_ceil_at_sub_slash
 | |
| 
 | |
| if test_have_prereq SYMLINKS
 | |
| then
 | |
| 	GIT_CEILING_DIRECTORIES="$TRASH_ROOT/top"
 | |
| 	test_fail subdir_ceil_at_top
 | |
| 	GIT_CEILING_DIRECTORIES="$TRASH_ROOT/top/"
 | |
| 	test_fail subdir_ceil_at_top_slash
 | |
| 
 | |
| 	GIT_CEILING_DIRECTORIES=":$TRASH_ROOT/top"
 | |
| 	test_prefix subdir_ceil_at_top_no_resolve "sub/dir/"
 | |
| 	GIT_CEILING_DIRECTORIES=":$TRASH_ROOT/top/"
 | |
| 	test_prefix subdir_ceil_at_top_slash_no_resolve "sub/dir/"
 | |
| fi
 | |
| 
 | |
| GIT_CEILING_DIRECTORIES="$TRASH_ROOT/sub/dir"
 | |
| test_prefix subdir_ceil_at_subdir "sub/dir/"
 | |
| 
 | |
| GIT_CEILING_DIRECTORIES="$TRASH_ROOT/sub/dir/"
 | |
| test_prefix subdir_ceil_at_subdir_slash "sub/dir/"
 | |
| 
 | |
| 
 | |
| GIT_CEILING_DIRECTORIES="$TRASH_ROOT/su"
 | |
| test_prefix subdir_ceil_at_su "sub/dir/"
 | |
| 
 | |
| GIT_CEILING_DIRECTORIES="$TRASH_ROOT/su/"
 | |
| test_prefix subdir_ceil_at_su_slash "sub/dir/"
 | |
| 
 | |
| GIT_CEILING_DIRECTORIES="$TRASH_ROOT/sub/di"
 | |
| test_prefix subdir_ceil_at_sub_di "sub/dir/"
 | |
| 
 | |
| GIT_CEILING_DIRECTORIES="$TRASH_ROOT/sub/di"
 | |
| test_prefix subdir_ceil_at_sub_di_slash "sub/dir/"
 | |
| 
 | |
| GIT_CEILING_DIRECTORIES="$TRASH_ROOT/subdi"
 | |
| test_prefix subdir_ceil_at_subdi "sub/dir/"
 | |
| 
 | |
| GIT_CEILING_DIRECTORIES="$TRASH_ROOT/subdi"
 | |
| test_prefix subdir_ceil_at_subdi_slash "sub/dir/"
 | |
| 
 | |
| 
 | |
| GIT_CEILING_DIRECTORIES="/foo:$TRASH_ROOT/sub"
 | |
| test_fail second_of_two
 | |
| 
 | |
| GIT_CEILING_DIRECTORIES="$TRASH_ROOT/sub:/bar"
 | |
| test_fail first_of_two
 | |
| 
 | |
| GIT_CEILING_DIRECTORIES="/foo:$TRASH_ROOT/sub:/bar"
 | |
| test_fail second_of_three
 | |
| 
 | |
| 
 | |
| GIT_CEILING_DIRECTORIES="$TRASH_ROOT/sub"
 | |
| GIT_DIR=../../.git
 | |
| export GIT_DIR
 | |
| test_prefix git_dir_specified ""
 | |
| unset GIT_DIR
 | |
| 
 | |
| 
 | |
| cd ../.. || exit 1
 | |
| mkdir -p s/d || exit 1
 | |
| cd s/d || exit 1
 | |
| 
 | |
| unset GIT_CEILING_DIRECTORIES
 | |
| test_prefix sd_no_ceil "s/d/"
 | |
| 
 | |
| export GIT_CEILING_DIRECTORIES
 | |
| 
 | |
| GIT_CEILING_DIRECTORIES=""
 | |
| test_prefix sd_ceil_empty "s/d/"
 | |
| 
 | |
| GIT_CEILING_DIRECTORIES="$TRASH_ROOT"
 | |
| test_fail sd_ceil_at_trash
 | |
| 
 | |
| GIT_CEILING_DIRECTORIES="$TRASH_ROOT/"
 | |
| test_fail sd_ceil_at_trash_slash
 | |
| 
 | |
| GIT_CEILING_DIRECTORIES="$TRASH_ROOT/s"
 | |
| test_fail sd_ceil_at_s
 | |
| 
 | |
| GIT_CEILING_DIRECTORIES="$TRASH_ROOT/s/"
 | |
| test_fail sd_ceil_at_s_slash
 | |
| 
 | |
| GIT_CEILING_DIRECTORIES="$TRASH_ROOT/s/d"
 | |
| test_prefix sd_ceil_at_sd "s/d/"
 | |
| 
 | |
| GIT_CEILING_DIRECTORIES="$TRASH_ROOT/s/d/"
 | |
| test_prefix sd_ceil_at_sd_slash "s/d/"
 | |
| 
 | |
| 
 | |
| GIT_CEILING_DIRECTORIES="$TRASH_ROOT/su"
 | |
| test_prefix sd_ceil_at_su "s/d/"
 | |
| 
 | |
| GIT_CEILING_DIRECTORIES="$TRASH_ROOT/su/"
 | |
| test_prefix sd_ceil_at_su_slash "s/d/"
 | |
| 
 | |
| GIT_CEILING_DIRECTORIES="$TRASH_ROOT/s/di"
 | |
| test_prefix sd_ceil_at_s_di "s/d/"
 | |
| 
 | |
| GIT_CEILING_DIRECTORIES="$TRASH_ROOT/s/di"
 | |
| test_prefix sd_ceil_at_s_di_slash "s/d/"
 | |
| 
 | |
| GIT_CEILING_DIRECTORIES="$TRASH_ROOT/sdi"
 | |
| test_prefix sd_ceil_at_sdi "s/d/"
 | |
| 
 | |
| GIT_CEILING_DIRECTORIES="$TRASH_ROOT/sdi"
 | |
| test_prefix sd_ceil_at_sdi_slash "s/d/"
 | |
| 
 | |
| 
 | |
| test_done
 |