clean: show an error message when the path is too long

When `lstat()` failed, `git clean` would abort without an error message, leaving the user quite puzzled. In particular on Windows, where the default maximum path length is quite small (yet there are ways to circumvent that limit in many cases), it is very important that users be given an indication why their command failed because of too long paths when it did. This test case makes sure that a warning is issued that would have helped the user who reported this issue: https://github.com/git-for-windows/git/issues/521 Note that we temporarily set `core.longpaths = false` in the regression test; this ensures forward-compatibility with the `core.longpaths` feature that has not yet been upstreamed from Git for Windows. Helped-by: René Scharfe <l.s.r@web.de> Helped-by: SZEDER Gábor <szeder.dev@gmail.com> Helped-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Johannes Schindelin committed Jul 18, 2019 at 02:30 UTC b09364c47a015dee7735fd2c038d7d710417c2f2
2 files changed +14 -1
builtin/clean.c
+2 -1
@@ -34,6 +34,7 @@ static const char *msg_would_remove = N_("Would remove %s\n");
34 static const char *msg_skip_git_dir = N_("Skipping repository %s\n");
35 static const char *msg_would_skip_git_dir = N_("Would skip repository %s\n");
36 static const char *msg_warn_remove_failed = N_("failed to remove %s");
37 +static const char *msg_warn_lstat_failed = N_("could not lstat %s\n");
38
39 enum color_clean {
40 CLEAN_COLOR_RESET = 0,
@@ -194,7 +195,7 @@ static int remove_dirs(struct strbuf *path, const char *prefix, int force_flag,
195 strbuf_setlen(path, len);
196 strbuf_addstr(path, e->d_name);
197 if (lstat(path->buf, &st))
197 - ; /* fall thru */
198 + warning_errno(_(msg_warn_lstat_failed), path->buf);
199 else if (S_ISDIR(st.st_mode)) {
200 if (remove_dirs(path, prefix, force_flag, dry_run, quiet, &gone))
201 ret = 1;
t/t7300-clean.sh
+12
@@ -669,4 +669,16 @@ test_expect_success 'git clean -d skips untracked dirs containing ignored files'
669 test_path_is_missing foo/b/bb
670 '
671
672 +test_expect_success MINGW 'handle clean & core.longpaths = false nicely' '
673 + test_config core.longpaths false &&
674 + a50=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa &&
675 + mkdir -p $a50$a50/$a50$a50/$a50$a50 &&
676 + : >"$a50$a50/test.txt" 2>"$a50$a50/$a50$a50/$a50$a50/test.txt" &&
677 + # create a temporary outside the working tree to hide from "git clean"
678 + test_must_fail git clean -xdf 2>.git/err &&
679 + # grepping for a strerror string is unportable but it is OK here with
680 + # MINGW prereq
681 + test_i18ngrep "too long" .git/err
682 +'
683 +
684 test_done