From: Elijah Newren <newren@xxxxxxxxx> Signed-off-by: Elijah Newren <newren@xxxxxxxxx> --- builtin/clean.c | 29 ++++++++++++++++++++--------- t/t2501-cwd-empty.sh | 2 +- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/builtin/clean.c b/builtin/clean.c index 98a2860409b..17d54be57b7 100644 --- a/builtin/clean.c +++ b/builtin/clean.c @@ -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, @@ -231,16 +233,25 @@ 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, "ed, 0); - errno = saved_errno; - warning_errno(_(msg_warn_remove_failed), quoted.buf); + int prefixlen = prefix ? strlen(prefix) : 0; + if (prefix && + path->len == prefixlen + 2 && + !strncmp(path->buf, prefix, prefixlen) && + !strcmp(path->buf + prefixlen, "./")) { + 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, "ed, 0); + errno = saved_errno; + warning_errno(_(msg_warn_remove_failed), quoted.buf); + *dir_gone = 0; + ret = 1; + } } } diff --git a/t/t2501-cwd-empty.sh b/t/t2501-cwd-empty.sh index b92e1a9bb16..20e1b6adede 100755 --- a/t/t2501-cwd-empty.sh +++ b/t/t2501-cwd-empty.sh @@ -218,7 +218,7 @@ test_expect_failure 'apply does not remove cwd incidentally' ' test_path_is_dir subdir ' -test_expect_failure 'clean does not remove cwd incidentally' ' +test_expect_success 'clean does not remove cwd incidentally' ' git checkout foo/bar/baz && test_when_finished "git clean -fdx" && -- gitgitgadget