git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH] git clean: Don't automatically remove directories when run within subdirectory

From
Shawn Bohrer <shawn.bohrer@gmail.com>
Date
Apr 13, 2008, 23:49 UTC
Message-ID
<1208130578-24748-1-git-send-email-shawn.bohrer@gmail.com>
In-Reply-To
<85fxtvj6y8.fsf_-_@lupus.strangled.net>

When git clean is run from a subdirectory it should follow the normal policy and only remove directories if they are passed in as a pathspec, or -d is specified.

Signed-off-by: Shawn Bohrer <shawn.bohrer@gmail.com>
---
On Wed, Apr 09, 2008 at 07:04:15PM +0200, Joachim B Haga wrote:
Show 6 quoted lines
> Joachim B Haga <jobh@broadpark.no> writes:
> I have tried to fix this, but I don't know the code. The previous logic was
> obviously (?) broken, as it had this (paraphrased):
>
> if (remove_directories || matches)
>       remove_dir_recursively(...);

git clean will remove directories if you specify -d (setting the remove_directories flag), or if you explicitly passed the directory in as a pathspec. For example:

mkdir foo git clean foo

After looking at the code a bit I think the real problem is with match_pathspec, or at least with how git clean uses match_pathspec. How does the following patch look?

 builtin-clean.c |   11 +++++------
 dir.c           |    2 +-
 2 files changed, 6 insertions(+), 7 deletions(-)
diff --git a/builtin-clean.c b/builtin-clean.c
index fefec30..5c5ec98 100644
--- a/builtin-clean.c
+++ b/builtin-clean.c
@@ -95,7 +95,8 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
 
 	for (i = 0; i < dir.nr; i++) {
 		struct dir_entry *ent = dir.entries[i];
-		int len, pos, matches;
+		int len, pos;
+		int matches = 0;
 		struct cache_entry *ce;
 		struct stat st;
 
@@ -127,18 +128,16 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
 
 		if (pathspec) {
 			memset(seen, 0, argc > 0 ? argc : 1);
-			matches = match_pathspec(pathspec, ent->name, ent->len,
+			matches = match_pathspec(pathspec, ent->name, len,
 						 baselen, seen);
-		} else {
-			matches = 0;
 		}
 
 		if (S_ISDIR(st.st_mode)) {
 			strbuf_addstr(&directory, ent->name);
 			qname = quote_path_relative(directory.buf, directory.len, &buf, prefix);
-			if (show_only && (remove_directories || matches)) {
+			if (show_only && (remove_directories || (matches >= 2))) {
 				printf("Would remove %s\n", qname);
-			} else if (remove_directories || matches) {
+			} else if (remove_directories || (matches >= 2)) {
 				if (!quiet)
 					printf("Removing %s\n", qname);
 				if (remove_dir_recursively(&directory, 0) != 0) {
diff --git a/dir.c b/dir.c
index b5bfbca..63715c9 100644
--- a/dir.c
+++ b/dir.c
@@ -80,7 +80,7 @@ static int match_one(const char *match, const char *name, int namelen)
 	if (strncmp(match, name, matchlen))
 		return !fnmatch(match, name, 0) ? MATCHED_FNMATCH : 0;
 
-	if (!name[matchlen])
+	if (namelen == matchlen)
 		return MATCHED_EXACTLY;
 	if (match[matchlen-1] == '/' || name[matchlen] == '/')
 		return MATCHED_RECURSIVELY;
-- 
1.5.5.106.g42c8b
Previous: Joachim B HagaNext: Shawn Bohrer
Message 4 of 14 in “git clean removes directories when not asked to”
  1. Joachim B HagaApr 8, 2008
  2. Joachim B HagaApr 8, 2008
  3. Re: git clean removes directories when not asked toJoachim B Haga, Apr 9, 2008
  4. git clean: Don't automatically remove directories when run within subdirectoryShawn Bohrer, Apr 13, 2008
  5. git clean: Add test to verify directories aren't removed with a prefixShawn Bohrer, Apr 13, 2008
  6. Joachim Berdal HagaApr 14, 2008
  7. Junio C HamanoApr 14, 2008
  8. Shawn BohrerApr 14, 2008
  9. Joachim Berdal HagaApr 14, 2008
  10. Shawn BohrerApr 15, 2008
  11. Joachim Berdal HagaApr 15, 2008
  12. Shawn BohrerApr 15, 2008
  13. Joachim Berdal HagaApr 15, 2008
  14. git clean: Don't automatically remove directories when run within subdirectoryShawn Bohrer, Apr 15, 2008

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.