setup: rework setup_explicit_git_dir()
This function is the most complex one among the three setup_* functions because all GIT_DIR, GIT_WORK_TREE, core.worktree and core.bare are involved. Because core.worktree is only effective inside setup_explicit_git_dir() and the extra code in setup_git_directory() is to handle that. The extra code can now be retired. Also note that setup_explicit assignment is removed, worktree setting is no longer decided by get_git_work_tree(). get_git_work_tree() will be simplified in the next commit. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
9951d3b37e
commit
b3f66fd3e3
134
setup.c
134
setup.c
@ -208,24 +208,6 @@ int is_inside_work_tree(void)
|
|||||||
return inside_work_tree;
|
return inside_work_tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* set_work_tree() is only ever called if you set GIT_DIR explicitly.
|
|
||||||
* The old behaviour (which we retain here) is to set the work tree root
|
|
||||||
* to the cwd, unless overridden by the config, the command line, or
|
|
||||||
* GIT_WORK_TREE.
|
|
||||||
*/
|
|
||||||
static const char *set_work_tree(const char *dir)
|
|
||||||
{
|
|
||||||
char buffer[PATH_MAX + 1];
|
|
||||||
|
|
||||||
if (!getcwd(buffer, sizeof(buffer)))
|
|
||||||
die ("Could not get the current working directory");
|
|
||||||
git_work_tree_cfg = xstrdup(buffer);
|
|
||||||
inside_work_tree = 1;
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setup_work_tree(void)
|
void setup_work_tree(void)
|
||||||
{
|
{
|
||||||
const char *work_tree, *git_dir;
|
const char *work_tree, *git_dir;
|
||||||
@ -326,40 +308,92 @@ const char *read_gitfile_gently(const char *path)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const char *setup_explicit_git_dir(const char *gitdirenv,
|
static const char *setup_explicit_git_dir(const char *gitdirenv,
|
||||||
const char *work_tree_env, int *nongit_ok)
|
char *cwd, int len,
|
||||||
|
int *nongit_ok)
|
||||||
{
|
{
|
||||||
static char buffer[1024 + 1];
|
const char *work_tree_env = getenv(GIT_WORK_TREE_ENVIRONMENT);
|
||||||
const char *retval;
|
const char *worktree;
|
||||||
|
char *gitfile;
|
||||||
|
|
||||||
if (startup_info)
|
|
||||||
startup_info->setup_explicit = 1;
|
|
||||||
if (PATH_MAX - 40 < strlen(gitdirenv))
|
if (PATH_MAX - 40 < strlen(gitdirenv))
|
||||||
die("'$%s' too big", GIT_DIR_ENVIRONMENT);
|
die("'$%s' too big", GIT_DIR_ENVIRONMENT);
|
||||||
|
|
||||||
|
gitfile = (char*)read_gitfile_gently(gitdirenv);
|
||||||
|
if (gitfile) {
|
||||||
|
gitfile = xstrdup(gitfile);
|
||||||
|
gitdirenv = gitfile;
|
||||||
|
}
|
||||||
|
|
||||||
if (!is_git_directory(gitdirenv)) {
|
if (!is_git_directory(gitdirenv)) {
|
||||||
if (nongit_ok) {
|
if (nongit_ok) {
|
||||||
*nongit_ok = 1;
|
*nongit_ok = 1;
|
||||||
|
free(gitfile);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
die("Not a git repository: '%s'", gitdirenv);
|
die("Not a git repository: '%s'", gitdirenv);
|
||||||
}
|
}
|
||||||
if (!work_tree_env) {
|
|
||||||
retval = set_work_tree(gitdirenv);
|
if (check_repository_format_gently(gitdirenv, nongit_ok)) {
|
||||||
/* config may override worktree */
|
free(gitfile);
|
||||||
if (check_repository_format_gently(gitdirenv, nongit_ok))
|
|
||||||
return NULL;
|
return NULL;
|
||||||
return retval;
|
|
||||||
}
|
}
|
||||||
if (check_repository_format_gently(gitdirenv, nongit_ok))
|
|
||||||
|
/* #3, #7, #11, #15, #19, #23, #27, #31 (see t1510) */
|
||||||
|
if (work_tree_env)
|
||||||
|
set_git_work_tree(work_tree_env);
|
||||||
|
else if (is_bare_repository_cfg > 0) {
|
||||||
|
if (git_work_tree_cfg) /* #22.2, #30 */
|
||||||
|
die("core.bare and core.worktree do not make sense");
|
||||||
|
|
||||||
|
/* #18, #26 */
|
||||||
|
set_git_dir(gitdirenv);
|
||||||
|
free(gitfile);
|
||||||
return NULL;
|
return NULL;
|
||||||
retval = get_relative_cwd(buffer, sizeof(buffer) - 1,
|
}
|
||||||
get_git_work_tree());
|
else if (git_work_tree_cfg) { /* #6, #14 */
|
||||||
if (!retval || !*retval)
|
if (is_absolute_path(git_work_tree_cfg))
|
||||||
|
set_git_work_tree(git_work_tree_cfg);
|
||||||
|
else {
|
||||||
|
char core_worktree[PATH_MAX];
|
||||||
|
if (chdir(gitdirenv))
|
||||||
|
die_errno("Could not chdir to '%s'", gitdirenv);
|
||||||
|
if (chdir(git_work_tree_cfg))
|
||||||
|
die_errno("Could not chdir to '%s'", git_work_tree_cfg);
|
||||||
|
if (!getcwd(core_worktree, PATH_MAX))
|
||||||
|
die_errno("Could not get directory '%s'", git_work_tree_cfg);
|
||||||
|
if (chdir(cwd))
|
||||||
|
die_errno("Could not come back to cwd");
|
||||||
|
set_git_work_tree(core_worktree);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else /* #2, #10 */
|
||||||
|
set_git_work_tree(".");
|
||||||
|
|
||||||
|
/* set_git_work_tree() must have been called by now */
|
||||||
|
worktree = get_git_work_tree();
|
||||||
|
|
||||||
|
/* both get_git_work_tree() and cwd are already normalized */
|
||||||
|
if (!strcmp(cwd, worktree)) { /* cwd == worktree */
|
||||||
|
set_git_dir(gitdirenv);
|
||||||
|
free(gitfile);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!prefixcmp(cwd, worktree) &&
|
||||||
|
cwd[strlen(worktree)] == '/') { /* cwd inside worktree */
|
||||||
set_git_dir(make_absolute_path(gitdirenv));
|
set_git_dir(make_absolute_path(gitdirenv));
|
||||||
if (chdir(work_tree_env) < 0)
|
if (chdir(worktree))
|
||||||
die_errno ("Could not chdir to '%s'", work_tree_env);
|
die_errno("Could not chdir to '%s'", worktree);
|
||||||
strcat(buffer, "/");
|
cwd[len++] = '/';
|
||||||
return retval;
|
cwd[len] = '\0';
|
||||||
|
free(gitfile);
|
||||||
|
return cwd + strlen(worktree) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* cwd outside worktree */
|
||||||
|
set_git_dir(gitdirenv);
|
||||||
|
free(gitfile);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *setup_discovered_git_dir(const char *gitdir,
|
static const char *setup_discovered_git_dir(const char *gitdir,
|
||||||
@ -441,7 +475,6 @@ static dev_t get_device_or_die(const char *path, const char *prefix)
|
|||||||
*/
|
*/
|
||||||
static const char *setup_git_directory_gently_1(int *nongit_ok)
|
static const char *setup_git_directory_gently_1(int *nongit_ok)
|
||||||
{
|
{
|
||||||
const char *work_tree_env = getenv(GIT_WORK_TREE_ENVIRONMENT);
|
|
||||||
const char *env_ceiling_dirs = getenv(CEILING_DIRECTORIES_ENVIRONMENT);
|
const char *env_ceiling_dirs = getenv(CEILING_DIRECTORIES_ENVIRONMENT);
|
||||||
static char cwd[PATH_MAX+1];
|
static char cwd[PATH_MAX+1];
|
||||||
const char *gitdirenv, *ret;
|
const char *gitdirenv, *ret;
|
||||||
@ -458,6 +491,10 @@ static const char *setup_git_directory_gently_1(int *nongit_ok)
|
|||||||
if (nongit_ok)
|
if (nongit_ok)
|
||||||
*nongit_ok = 0;
|
*nongit_ok = 0;
|
||||||
|
|
||||||
|
if (!getcwd(cwd, sizeof(cwd)-1))
|
||||||
|
die_errno("Unable to read current working directory");
|
||||||
|
offset = len = strlen(cwd);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If GIT_DIR is set explicitly, we're not going
|
* If GIT_DIR is set explicitly, we're not going
|
||||||
* to do any discovery, but we still do repository
|
* to do any discovery, but we still do repository
|
||||||
@ -465,10 +502,7 @@ static const char *setup_git_directory_gently_1(int *nongit_ok)
|
|||||||
*/
|
*/
|
||||||
gitdirenv = getenv(GIT_DIR_ENVIRONMENT);
|
gitdirenv = getenv(GIT_DIR_ENVIRONMENT);
|
||||||
if (gitdirenv)
|
if (gitdirenv)
|
||||||
return setup_explicit_git_dir(gitdirenv, work_tree_env, nongit_ok);
|
return setup_explicit_git_dir(gitdirenv, cwd, len, nongit_ok);
|
||||||
|
|
||||||
if (!getcwd(cwd, sizeof(cwd)-1))
|
|
||||||
die_errno("Unable to read current working directory");
|
|
||||||
|
|
||||||
ceil_offset = longest_ancestor_length(cwd, env_ceiling_dirs);
|
ceil_offset = longest_ancestor_length(cwd, env_ceiling_dirs);
|
||||||
if (ceil_offset < 0 && has_dos_drive_prefix(cwd))
|
if (ceil_offset < 0 && has_dos_drive_prefix(cwd))
|
||||||
@ -485,7 +519,6 @@ static const char *setup_git_directory_gently_1(int *nongit_ok)
|
|||||||
* - ../../.git/
|
* - ../../.git/
|
||||||
* etc.
|
* etc.
|
||||||
*/
|
*/
|
||||||
offset = len = strlen(cwd);
|
|
||||||
one_filesystem = !git_env_bool("GIT_DISCOVERY_ACROSS_FILESYSTEM", 0);
|
one_filesystem = !git_env_bool("GIT_DISCOVERY_ACROSS_FILESYSTEM", 0);
|
||||||
if (one_filesystem)
|
if (one_filesystem)
|
||||||
current_device = get_device_or_die(".", NULL);
|
current_device = get_device_or_die(".", NULL);
|
||||||
@ -628,20 +661,5 @@ int check_repository_format(void)
|
|||||||
*/
|
*/
|
||||||
const char *setup_git_directory(void)
|
const char *setup_git_directory(void)
|
||||||
{
|
{
|
||||||
const char *retval = setup_git_directory_gently(NULL);
|
return setup_git_directory_gently(NULL);
|
||||||
|
|
||||||
/* If the work tree is not the default one, recompute prefix */
|
|
||||||
if ((!startup_info || startup_info->setup_explicit) &&
|
|
||||||
inside_work_tree < 0) {
|
|
||||||
static char buffer[PATH_MAX + 1];
|
|
||||||
char *rel;
|
|
||||||
if (retval && chdir(retval))
|
|
||||||
die_errno ("Could not jump back into original cwd");
|
|
||||||
rel = get_relative_cwd(buffer, PATH_MAX, get_git_work_tree());
|
|
||||||
if (rel && *rel && chdir(get_git_work_tree()))
|
|
||||||
die_errno ("Could not jump to working directory");
|
|
||||||
return rel && *rel ? strcat(rel, "/") : NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return retval;
|
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user