Merge branch 'jn/maint-setup-fix' (early part) into jn/paginate-fix
* 'jn/maint-setup-fix' (early part): Revert "rehabilitate 'git index-pack' inside the object store" setup: do not forget working dir from subdir of gitdir t4111 (apply): refresh index before applying patches to it setup: split off get_device_or_die helper setup: split off a function to handle hitting ceiling in repo search setup: split off code to handle stumbling upon a repository setup: split off a function to checks working dir for .git file setup: split off $GIT_DIR-set case from setup_git_directory_gently tests: try git apply from subdir of toplevel t1501 (rev-parse): clarify
This commit is contained in:
171
setup.c
171
setup.c
@ -313,6 +313,93 @@ const char *read_gitfile_gently(const char *path)
|
||||
return path;
|
||||
}
|
||||
|
||||
static const char *setup_explicit_git_dir(const char *gitdirenv,
|
||||
const char *work_tree_env, int *nongit_ok)
|
||||
{
|
||||
static char buffer[1024 + 1];
|
||||
const char *retval;
|
||||
|
||||
if (PATH_MAX - 40 < strlen(gitdirenv))
|
||||
die("'$%s' too big", GIT_DIR_ENVIRONMENT);
|
||||
if (!is_git_directory(gitdirenv)) {
|
||||
if (nongit_ok) {
|
||||
*nongit_ok = 1;
|
||||
return NULL;
|
||||
}
|
||||
die("Not a git repository: '%s'", gitdirenv);
|
||||
}
|
||||
if (!work_tree_env) {
|
||||
retval = set_work_tree(gitdirenv);
|
||||
/* config may override worktree */
|
||||
if (check_repository_format_gently(nongit_ok))
|
||||
return NULL;
|
||||
return retval;
|
||||
}
|
||||
if (check_repository_format_gently(nongit_ok))
|
||||
return NULL;
|
||||
retval = get_relative_cwd(buffer, sizeof(buffer) - 1,
|
||||
get_git_work_tree());
|
||||
if (!retval || !*retval)
|
||||
return NULL;
|
||||
set_git_dir(make_absolute_path(gitdirenv));
|
||||
if (chdir(work_tree_env) < 0)
|
||||
die_errno ("Could not chdir to '%s'", work_tree_env);
|
||||
strcat(buffer, "/");
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int cwd_contains_git_dir(const char **gitfile_dirp)
|
||||
{
|
||||
const char *gitfile_dir = read_gitfile_gently(DEFAULT_GIT_DIR_ENVIRONMENT);
|
||||
*gitfile_dirp = gitfile_dir;
|
||||
if (gitfile_dir) {
|
||||
if (set_git_dir(gitfile_dir))
|
||||
die("Repository setup failed");
|
||||
return 1;
|
||||
}
|
||||
return is_git_directory(DEFAULT_GIT_DIR_ENVIRONMENT);
|
||||
}
|
||||
|
||||
static const char *setup_bare_git_dir(const char *work_tree_env,
|
||||
int offset, int len, char *cwd, int *nongit_ok)
|
||||
{
|
||||
int root_len;
|
||||
|
||||
inside_git_dir = 1;
|
||||
if (!work_tree_env)
|
||||
inside_work_tree = 0;
|
||||
if (offset != len) {
|
||||
if (chdir(cwd))
|
||||
die_errno("Cannot come back to cwd");
|
||||
root_len = offset_1st_component(cwd);
|
||||
cwd[offset > root_len ? offset : root_len] = '\0';
|
||||
set_git_dir(cwd);
|
||||
} else
|
||||
set_git_dir(".");
|
||||
check_repository_format_gently(nongit_ok);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *setup_nongit(const char *cwd, int *nongit_ok)
|
||||
{
|
||||
if (!nongit_ok)
|
||||
die("Not a git repository (or any of the parent directories): %s", DEFAULT_GIT_DIR_ENVIRONMENT);
|
||||
if (chdir(cwd))
|
||||
die_errno("Cannot come back to cwd");
|
||||
*nongit_ok = 1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static dev_t get_device_or_die(const char *path, const char *prefix)
|
||||
{
|
||||
struct stat buf;
|
||||
if (stat(path, &buf))
|
||||
die_errno("failed to stat '%s%s%s'",
|
||||
prefix ? prefix : "",
|
||||
prefix ? "/" : "", path);
|
||||
return buf.st_dev;
|
||||
}
|
||||
|
||||
/*
|
||||
* We cannot decide in this function whether we are in the work tree or
|
||||
* not, since the config can only be read _after_ this function was called.
|
||||
@ -327,7 +414,6 @@ static const char *setup_git_directory_gently_1(int *nongit_ok)
|
||||
int len, offset, ceil_offset, root_len;
|
||||
dev_t current_device = 0;
|
||||
int one_filesystem = 1;
|
||||
struct stat buf;
|
||||
|
||||
/*
|
||||
* Let's assume that we are in a git repository.
|
||||
@ -343,38 +429,8 @@ static const char *setup_git_directory_gently_1(int *nongit_ok)
|
||||
* validation.
|
||||
*/
|
||||
gitdirenv = getenv(GIT_DIR_ENVIRONMENT);
|
||||
if (gitdirenv) {
|
||||
if (PATH_MAX - 40 < strlen(gitdirenv))
|
||||
die("'$%s' too big", GIT_DIR_ENVIRONMENT);
|
||||
if (is_git_directory(gitdirenv)) {
|
||||
static char buffer[1024 + 1];
|
||||
const char *retval;
|
||||
|
||||
if (!work_tree_env) {
|
||||
retval = set_work_tree(gitdirenv);
|
||||
/* config may override worktree */
|
||||
if (check_repository_format_gently(nongit_ok))
|
||||
return NULL;
|
||||
return retval;
|
||||
}
|
||||
if (check_repository_format_gently(nongit_ok))
|
||||
return NULL;
|
||||
retval = get_relative_cwd(buffer, sizeof(buffer) - 1,
|
||||
get_git_work_tree());
|
||||
if (!retval || !*retval)
|
||||
return NULL;
|
||||
set_git_dir(make_absolute_path(gitdirenv));
|
||||
if (chdir(work_tree_env) < 0)
|
||||
die_errno ("Could not chdir to '%s'", work_tree_env);
|
||||
strcat(buffer, "/");
|
||||
return retval;
|
||||
}
|
||||
if (nongit_ok) {
|
||||
*nongit_ok = 1;
|
||||
return NULL;
|
||||
}
|
||||
die("Not a git repository: '%s'", gitdirenv);
|
||||
}
|
||||
if (gitdirenv)
|
||||
return setup_explicit_git_dir(gitdirenv, work_tree_env, nongit_ok);
|
||||
|
||||
if (!getcwd(cwd, sizeof(cwd)-1))
|
||||
die_errno("Unable to read current working directory");
|
||||
@ -396,49 +452,20 @@ static const char *setup_git_directory_gently_1(int *nongit_ok)
|
||||
*/
|
||||
offset = len = strlen(cwd);
|
||||
one_filesystem = !git_env_bool("GIT_DISCOVERY_ACROSS_FILESYSTEM", 0);
|
||||
if (one_filesystem) {
|
||||
if (stat(".", &buf))
|
||||
die_errno("failed to stat '.'");
|
||||
current_device = buf.st_dev;
|
||||
}
|
||||
if (one_filesystem)
|
||||
current_device = get_device_or_die(".", NULL);
|
||||
for (;;) {
|
||||
gitfile_dir = read_gitfile_gently(DEFAULT_GIT_DIR_ENVIRONMENT);
|
||||
if (gitfile_dir) {
|
||||
if (set_git_dir(gitfile_dir))
|
||||
die("Repository setup failed");
|
||||
if (cwd_contains_git_dir(&gitfile_dir))
|
||||
break;
|
||||
}
|
||||
if (is_git_directory(DEFAULT_GIT_DIR_ENVIRONMENT))
|
||||
break;
|
||||
if (is_git_directory(".")) {
|
||||
inside_git_dir = 1;
|
||||
if (!work_tree_env)
|
||||
inside_work_tree = 0;
|
||||
if (offset != len) {
|
||||
root_len = offset_1st_component(cwd);
|
||||
cwd[offset > root_len ? offset : root_len] = '\0';
|
||||
set_git_dir(cwd);
|
||||
} else
|
||||
set_git_dir(".");
|
||||
check_repository_format_gently(nongit_ok);
|
||||
return NULL;
|
||||
}
|
||||
if (is_git_directory("."))
|
||||
return setup_bare_git_dir(work_tree_env, offset,
|
||||
len, cwd, nongit_ok);
|
||||
while (--offset > ceil_offset && cwd[offset] != '/');
|
||||
if (offset <= ceil_offset) {
|
||||
if (nongit_ok) {
|
||||
if (chdir(cwd))
|
||||
die_errno("Cannot come back to cwd");
|
||||
*nongit_ok = 1;
|
||||
return NULL;
|
||||
}
|
||||
die("Not a git repository (or any of the parent directories): %s", DEFAULT_GIT_DIR_ENVIRONMENT);
|
||||
}
|
||||
if (offset <= ceil_offset)
|
||||
return setup_nongit(cwd, nongit_ok);
|
||||
if (one_filesystem) {
|
||||
if (stat("..", &buf)) {
|
||||
cwd[offset] = '\0';
|
||||
die_errno("failed to stat '%s/..'", cwd);
|
||||
}
|
||||
if (buf.st_dev != current_device) {
|
||||
dev_t parent_device = get_device_or_die("..", cwd);
|
||||
if (parent_device != current_device) {
|
||||
if (nongit_ok) {
|
||||
if (chdir(cwd))
|
||||
die_errno("Cannot come back to cwd");
|
||||
|
||||
Reference in New Issue
Block a user