clean: do not attempt to remove startup_info->original_cwd

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:
Elijah Newren 2021-12-09 05:08:30 +00:00 коммит произвёл Junio C Hamano
Родитель 00fcce285d
Коммит c65744e7d7
2 изменённых файлов: 38 добавлений и 11 удалений

Просмотреть файл

@ -36,6 +36,8 @@ static const char *msg_skip_git_dir = N_("Skipping repository %s\n");
static const char *msg_would_skip_git_dir = N_("Would skip repository %s\n");
static const char *msg_warn_remove_failed = N_("failed to remove %s");
static const char *msg_warn_lstat_failed = N_("could not lstat %s\n");
static const char *msg_skip_cwd = N_("Refusing to remove current working directory\n");
static const char *msg_would_skip_cwd = N_("Would refuse to remove current working directory\n");
enum color_clean {
CLEAN_COLOR_RESET = 0,
@ -153,6 +155,8 @@ static int remove_dirs(struct strbuf *path, const char *prefix, int force_flag,
{
DIR *dir;
struct strbuf quoted = STRBUF_INIT;
struct strbuf realpath = STRBUF_INIT;
struct strbuf real_ocwd = STRBUF_INIT;
struct dirent *e;
int res = 0, ret = 0, gone = 1, original_len = path->len, len;
struct string_list dels = STRING_LIST_INIT_DUP;
@ -231,16 +235,36 @@ static int remove_dirs(struct strbuf *path, const char *prefix, int force_flag,
strbuf_setlen(path, original_len);
if (*dir_gone) {
res = dry_run ? 0 : rmdir(path->buf);
if (!res)
*dir_gone = 1;
else {
int saved_errno = errno;
quote_path(path->buf, prefix, &quoted, 0);
errno = saved_errno;
warning_errno(_(msg_warn_remove_failed), quoted.buf);
/*
* Normalize path components in path->buf, e.g. change '\' to
* '/' on Windows.
*/
strbuf_realpath(&realpath, path->buf, 1);
/*
* path and realpath are absolute; for comparison, we would
* like to transform startup_info->original_cwd to an absolute
* path too.
*/
if (startup_info->original_cwd)
strbuf_realpath(&real_ocwd,
startup_info->original_cwd, 1);
if (!strbuf_cmp(&realpath, &real_ocwd)) {
printf("%s", dry_run ? _(msg_would_skip_cwd) : _(msg_skip_cwd));
*dir_gone = 0;
ret = 1;
} else {
res = dry_run ? 0 : rmdir(path->buf);
if (!res)
*dir_gone = 1;
else {
int saved_errno = errno;
quote_path(path->buf, prefix, &quoted, 0);
errno = saved_errno;
warning_errno(_(msg_warn_remove_failed), quoted.buf);
*dir_gone = 0;
ret = 1;
}
}
}
@ -250,6 +274,8 @@ static int remove_dirs(struct strbuf *path, const char *prefix, int force_flag,
printf(dry_run ? _(msg_would_remove) : _(msg_remove), dels.items[i].string);
}
out:
strbuf_release(&realpath);
strbuf_release(&real_ocwd);
strbuf_release(&quoted);
string_list_clear(&dels, 0);
return ret;

Просмотреть файл

@ -230,8 +230,9 @@ test_incidental_untracked_dir_removal () {
}
test_expect_success 'clean does not remove cwd incidentally' '
test_incidental_untracked_dir_removal failure \
git -C .. clean -fd -e warnings . >warnings
test_incidental_untracked_dir_removal success \
git -C .. clean -fd -e warnings . >warnings &&
grep "Refusing to remove current working directory" warnings
'
test_expect_success 'stash does not remove cwd incidentally' '