Skip to content

Commit

Permalink
Merge branch 'mh/maint-ceil-absolute'
Browse files Browse the repository at this point in the history
An earlier workaround designed to help people who list logical
directories that will not match what getcwd(3) returns in the
GIT_CEILING_DIRECTORIES had an adverse effect when it is slow to
stat and readlink a directory component of an element listed on it.

* mh/maint-ceil-absolute:
  Provide a mechanism to turn off symlink resolution in ceiling paths
  • Loading branch information
Junio C Hamano committed Feb 27, 2013
2 parents 27db5a0 + 7ec30aa commit 3e07d26
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 16 deletions.
19 changes: 13 additions & 6 deletions Documentation/git.txt
Original file line number Diff line number Diff line change
Expand Up @@ -678,12 +678,19 @@ Git so take care if using Cogito etc.
The '--namespace' command-line option also sets this value.

'GIT_CEILING_DIRECTORIES'::
This should be a colon-separated list of absolute paths.
If set, it is a list of directories that Git should not chdir
up into while looking for a repository directory.
It will not exclude the current working directory or
a GIT_DIR set on the command line or in the environment.
(Useful for excluding slow-loading network directories.)
This should be a colon-separated list of absolute paths. If
set, it is a list of directories that Git should not chdir up
into while looking for a repository directory (useful for
excluding slow-loading network directories). It will not
exclude the current working directory or a GIT_DIR set on the
command line or in the environment. Normally, Git has to read
the entries in this list and resolve any symlink that
might be present in order to compare them with the current
directory. However, if even this access is slow, you
can add an empty entry to the list to tell Git that the
subsequent entries are not symlinks and needn't be resolved;
e.g.,
'GIT_CEILING_DIRECTORIES=/maybe/symlink::/very/slow/non/symlink'.

'GIT_DISCOVERY_ACROSS_FILESYSTEM'::
When run in a directory that does not have ".git" repository
Expand Down
32 changes: 22 additions & 10 deletions setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -650,22 +650,32 @@ static dev_t get_device_or_die(const char *path, const char *prefix, int prefix_
/*
* A "string_list_each_func_t" function that canonicalizes an entry
* from GIT_CEILING_DIRECTORIES using real_path_if_valid(), or
* discards it if unusable.
* discards it if unusable. The presence of an empty entry in
* GIT_CEILING_DIRECTORIES turns off canonicalization for all
* subsequent entries.
*/
static int canonicalize_ceiling_entry(struct string_list_item *item,
void *unused)
void *cb_data)
{
int *empty_entry_found = cb_data;
char *ceil = item->string;
const char *real_path;

if (!*ceil || !is_absolute_path(ceil))
if (!*ceil) {
*empty_entry_found = 1;
return 0;
real_path = real_path_if_valid(ceil);
if (!real_path)
} else if (!is_absolute_path(ceil)) {
return 0;
free(item->string);
item->string = xstrdup(real_path);
return 1;
} else if (*empty_entry_found) {
/* Keep entry but do not canonicalize it */
return 1;
} else {
const char *real_path = real_path_if_valid(ceil);
if (!real_path)
return 0;
free(item->string);
item->string = xstrdup(real_path);
return 1;
}
}

/*
Expand Down Expand Up @@ -705,9 +715,11 @@ static const char *setup_git_directory_gently_1(int *nongit_ok)
return setup_explicit_git_dir(gitdirenv, cwd, len, nongit_ok);

if (env_ceiling_dirs) {
int empty_entry_found = 0;

string_list_split(&ceiling_dirs, env_ceiling_dirs, PATH_SEP, -1);
filter_string_list(&ceiling_dirs, 0,
canonicalize_ceiling_entry, NULL);
canonicalize_ceiling_entry, &empty_entry_found);
ceil_offset = longest_ancestor_length(cwd, &ceiling_dirs);
string_list_clear(&ceiling_dirs, 0);
}
Expand Down
17 changes: 17 additions & 0 deletions t/t1504-ceiling-dirs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ 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
Expand All @@ -68,6 +72,19 @@ 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/"

Expand Down

0 comments on commit 3e07d26

Please sign in to comment.