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 15, 2008, 03:14 UTC
Message-ID
<1208229249-32033-1-git-send-email-shawn.bohrer@gmail.com>
In-Reply-To
<20080414170643.GA10548@mediacenter>

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.

The fix is to send len which could be shorter than ent->len because we have stripped the trailing '/' that read_directory adds. Additionaly match_one() was modified to allow a name[] that is not NUL terminated. This allows us to check if the name matched the pathspec exactly instead of recursively.

Signed-off-by: Shawn Bohrer <shawn.bohrer@gmail.com>
---
 builtin-clean.c |   13 +++++++------
 dir.c           |    2 +-
 2 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/builtin-clean.c b/builtin-clean.c
index fefec30..6778a03 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,18 @@ 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 == MATCHED_EXACTLY))) {
 				printf("Would remove %s\n", qname);
-			} else if (remove_directories || matches) {
+			} else if (remove_directories ||
+				   (matches == MATCHED_EXACTLY)) {
 				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.g62ee2.dirty
Previous: Joachim Berdal Haga
Message 14 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.