

As a result, we need toįor directories, if "-d" is not given we check that the pathspec matched exactly (i.e., we are even stricter, and require an explicit " git clean foo" to clean " foo/"). It uses a simplified version that may turn up false positives. However, read_directory does not actually check against our pathspec. Git-clean uses read_directory to fill in a struct dir with potential hits. Testing again without the " -d" flag showed that the same buggy behavior exists without using that flag, and has in fact existed since before cf424f5.

However, that pointed to a separate issue: while the " -d" flag was used by the original user who showed me this problem, that flag should have been irrelevant to this problem. If both directories had no tracked files then the clean command above would never clean either of the untracked files despite the pathspec explicitly calling both of them out.Ī bisect showed that the failure to clean out the files started with commit cf424f5 (" clean: respect pathspecs with " -d",, Git v1.9.1).If both directories had tracked files, then only one git clean would be necessary to clean both files.If only one of those two ut files existed (either one), then only one clean command would be necessary.With this setup, the user would need to run git clean -ffd */utĪ little testing showed some interesting variants: Required to clean out unwanted files: mkdir d Someone brought me a testcase where multiple git-clean invocations were (Merged by Junio C Hamano - gitster - in commit aafb754, ) t7300: add testcases showing failure to clean specified pathspecs See commit 69f272b (), and commit 902b90c, commit ca8b539, commit 09487f2, commit e86bbcf, commit 3aca580, commit 29b577b, commit 89a1f4a, commit a3d89d8, commit 404ebce, commit a5e916c, commit bbbb6b0, commit 7541cc5 () by Elijah Newren ( newren). This issue is a regression introduced in 6b1db43 ( clean: teachĬlean -d to preserve ignored paths,, Git v2.13.2). gitignore' rule in the outer repository happens to match a file in a nested repository or worktree, then something goes awry and ' git clean -fd' does delete the content of the nested repository's worktreeĮxcept that ignored file, potentially leading to data loss.Īdd a test to ' t7300-clean.sh' to demonstrate this breakage. To a different Git repository or worktree. ' git clean -fd' must not delete an untracked directory if it belongs (Merged by Junio C Hamano - gitster - in commit 026428c, ) t7300-clean: demonstrate deleting nested repo with an ignored file breakage See commit 502c386 () by SZEDER Gábor ( szeder). Git 2.24 (Q4 2019) illustrates this git clean behavior change introduces a regression. a fix is in progress, to be released later in 2020.
#Git clean repository Patch#
Patch series to fix ' git clean -d' deleting untracked directories even This slowdown was caused by commit df5bcdf, which was part of a With a depth of 120 directories it would take over 6*10^23 years to complete Since 2017, that change means git status -ignored hangs indefinitely!Īs reported by Martin Melka in this thread, and analyzed by SZEDER Gábor: To achieve this, cmd_clean() has to collect all untracked contents of untracked directories, in addition to all ignored paths, to determine which untracked dirs must be skipped (because they contain ignored paths) and which ones should not be skipped.īut. To get around this, we teach clean -d to collect ignored paths and skip an untracked directory if it contained an ignored path, instead just removing the untracked contents thereof. This makes sense in use cases where we're asking if a directory should be added to the git database, but not when we're asking if a directory can be safely removed from the working tree as a result, clean -d would assume that an "untracked" directory containing ignored paths could be deleted, even though doing so would also remove the ignored paths.

There is an implicit assumption that a directory containing only untracked and ignored paths should itself be considered untracked. (Merged by Junio C Hamano - gitster - in commit f4fd99b, ) clean: teach clean -d to preserve ignored paths See commit 6b1db43 (), and commit bbf504a, commit fb89888, commit df5bcdf, commit 0a81d4a, commit b3487cc () by Samuel Lijin ( sxlijin). " git status -ignored" did not list ignored and untracked files without " -uall". " git clean -d" used to clean directories that has ignored files, even though the command should not lose ignored ones without " -x". Warning: this git clean behavior will slightly change with Git 2.14 (Q3 2017)
