зеркало из https://github.com/microsoft/git.git
setup: introduce startup_info->original_cwd
Removing the current working directory causes all subsequent git commands run from that directory to get confused and fail with a message about being unable to read the current working directory: $ git status fatal: Unable to read current working directory: No such file or directory Non-git commands likely have similar warnings or even errors, e.g. $ bash -c 'echo hello' shell-init: error retrieving current directory: getcwd: cannot access parent directories: No such file or directory hello This confuses end users, particularly since the command they get the error from is not the one that caused the problem; the problem came from the side-effect of some previous command. We would like to avoid removing the current working directory of our parent process; towards this end, introduce a new variable, startup_info->original_cwd, that tracks the current working directory that we inherited from our parent process. For convenience of later comparisons, we prefer that this new variable store a path relative to the toplevel working directory (thus much like 'prefix'), except without the trailing slash. Subsequent commits will make use of this new variable. Acked-by: Derrick Stolee <stolee@gmail.com> Acked-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Родитель
8a0d52dfd8
Коммит
e6f8861bd4
2
cache.h
2
cache.h
|
@ -1834,8 +1834,10 @@ void overlay_tree_on_index(struct index_state *istate,
|
||||||
struct startup_info {
|
struct startup_info {
|
||||||
int have_repository;
|
int have_repository;
|
||||||
const char *prefix;
|
const char *prefix;
|
||||||
|
const char *original_cwd;
|
||||||
};
|
};
|
||||||
extern struct startup_info *startup_info;
|
extern struct startup_info *startup_info;
|
||||||
|
extern const char *tmp_original_cwd;
|
||||||
|
|
||||||
/* merge.c */
|
/* merge.c */
|
||||||
struct commit_list;
|
struct commit_list;
|
||||||
|
|
|
@ -26,6 +26,7 @@ static void restore_sigpipe_to_default(void)
|
||||||
int main(int argc, const char **argv)
|
int main(int argc, const char **argv)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
struct strbuf tmp = STRBUF_INIT;
|
||||||
|
|
||||||
trace2_initialize_clock();
|
trace2_initialize_clock();
|
||||||
|
|
||||||
|
@ -49,6 +50,9 @@ int main(int argc, const char **argv)
|
||||||
trace2_cmd_start(argv);
|
trace2_cmd_start(argv);
|
||||||
trace2_collect_process_info(TRACE2_PROCESS_INFO_STARTUP);
|
trace2_collect_process_info(TRACE2_PROCESS_INFO_STARTUP);
|
||||||
|
|
||||||
|
if (!strbuf_getcwd(&tmp))
|
||||||
|
tmp_original_cwd = strbuf_detach(&tmp, NULL);
|
||||||
|
|
||||||
result = cmd_main(argc, argv);
|
result = cmd_main(argc, argv);
|
||||||
|
|
||||||
trace2_cmd_exit(result);
|
trace2_cmd_exit(result);
|
||||||
|
|
65
setup.c
65
setup.c
|
@ -12,6 +12,7 @@ static int work_tree_config_is_bogus;
|
||||||
|
|
||||||
static struct startup_info the_startup_info;
|
static struct startup_info the_startup_info;
|
||||||
struct startup_info *startup_info = &the_startup_info;
|
struct startup_info *startup_info = &the_startup_info;
|
||||||
|
const char *tmp_original_cwd;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The input parameter must contain an absolute path, and it must already be
|
* The input parameter must contain an absolute path, and it must already be
|
||||||
|
@ -432,6 +433,69 @@ void setup_work_tree(void)
|
||||||
initialized = 1;
|
initialized = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void setup_original_cwd(void)
|
||||||
|
{
|
||||||
|
struct strbuf tmp = STRBUF_INIT;
|
||||||
|
const char *worktree = NULL;
|
||||||
|
int offset = -1;
|
||||||
|
|
||||||
|
if (!tmp_original_cwd)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* startup_info->original_cwd points to the current working
|
||||||
|
* directory we inherited from our parent process, which is a
|
||||||
|
* directory we want to avoid removing.
|
||||||
|
*
|
||||||
|
* For convience, we would like to have the path relative to the
|
||||||
|
* worktree instead of an absolute path.
|
||||||
|
*
|
||||||
|
* Yes, startup_info->original_cwd is usually the same as 'prefix',
|
||||||
|
* but differs in two ways:
|
||||||
|
* - prefix has a trailing '/'
|
||||||
|
* - if the user passes '-C' to git, that modifies the prefix but
|
||||||
|
* not startup_info->original_cwd.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Normalize the directory */
|
||||||
|
strbuf_realpath(&tmp, tmp_original_cwd, 1);
|
||||||
|
free((char*)tmp_original_cwd);
|
||||||
|
tmp_original_cwd = NULL;
|
||||||
|
startup_info->original_cwd = strbuf_detach(&tmp, NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get our worktree; we only protect the current working directory
|
||||||
|
* if it's in the worktree.
|
||||||
|
*/
|
||||||
|
worktree = get_git_work_tree();
|
||||||
|
if (!worktree)
|
||||||
|
goto no_prevention_needed;
|
||||||
|
|
||||||
|
offset = dir_inside_of(startup_info->original_cwd, worktree);
|
||||||
|
if (offset >= 0) {
|
||||||
|
/*
|
||||||
|
* If startup_info->original_cwd == worktree, that is already
|
||||||
|
* protected and we don't need original_cwd as a secondary
|
||||||
|
* protection measure.
|
||||||
|
*/
|
||||||
|
if (!*(startup_info->original_cwd + offset))
|
||||||
|
goto no_prevention_needed;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* original_cwd was inside worktree; precompose it just as
|
||||||
|
* we do prefix so that built up paths will match
|
||||||
|
*/
|
||||||
|
startup_info->original_cwd = \
|
||||||
|
precompose_string_if_needed(startup_info->original_cwd
|
||||||
|
+ offset);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
no_prevention_needed:
|
||||||
|
free((char*)startup_info->original_cwd);
|
||||||
|
startup_info->original_cwd = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static int read_worktree_config(const char *var, const char *value, void *vdata)
|
static int read_worktree_config(const char *var, const char *value, void *vdata)
|
||||||
{
|
{
|
||||||
struct repository_format *data = vdata;
|
struct repository_format *data = vdata;
|
||||||
|
@ -1330,6 +1394,7 @@ const char *setup_git_directory_gently(int *nongit_ok)
|
||||||
setenv(GIT_PREFIX_ENVIRONMENT, "", 1);
|
setenv(GIT_PREFIX_ENVIRONMENT, "", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setup_original_cwd();
|
||||||
|
|
||||||
strbuf_release(&dir);
|
strbuf_release(&dir);
|
||||||
strbuf_release(&gitdir);
|
strbuf_release(&gitdir);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче