git clean: Don't automatically remove directories when run within subdirectory
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> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Shawn Bohrer committed
Apr 14, 2008 at 22:14 UTC
f2d0df7148a1b9ee69bd69a365ffcd1965872451
2 files changed
+8
-7
builtin-clean.c
+7
-6
@@ -95,7 +95,8 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
95
96
for (i = 0; i < dir.nr; i++) {
97
struct dir_entry *ent = dir.entries[i];
98
- int len, pos, matches;
98
+ int len, pos;
99
+ int matches = 0;
100
struct cache_entry *ce;
101
struct stat st;
102
@@ -127,18 +128,18 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
128
129
if (pathspec) {
130
memset(seen, 0, argc > 0 ? argc : 1);
130
- matches = match_pathspec(pathspec, ent->name, ent->len,
131
+ matches = match_pathspec(pathspec, ent->name, len,
132
baselen, seen);
132
- } else {
133
- matches = 0;
133
}
134
135
if (S_ISDIR(st.st_mode)) {
136
strbuf_addstr(&directory, ent->name);
137
qname = quote_path_relative(directory.buf, directory.len, &buf, prefix);
139
- if (show_only && (remove_directories || matches)) {
138
+ if (show_only && (remove_directories ||
139
+ (matches == MATCHED_EXACTLY))) {
140
printf("Would remove %s\n", qname);
141
- } else if (remove_directories || matches) {
141
+ } else if (remove_directories ||
142
+ (matches == MATCHED_EXACTLY)) {
143
if (!quiet)
144
printf("Removing %s\n", qname);
145
if (remove_dir_recursively(&directory, 0) != 0) {
dir.c
+1
-1
@@ -80,7 +80,7 @@ static int match_one(const char *match, const char *name, int namelen)
80
if (strncmp(match, name, matchlen))
81
return !fnmatch(match, name, 0) ? MATCHED_FNMATCH : 0;
82
83
- if (!name[matchlen])
83
+ if (namelen == matchlen)
84
return MATCHED_EXACTLY;
85
if (match[matchlen-1] == '/' || name[matchlen] == '/')
86
return MATCHED_RECURSIVELY;