Merge branch 'jh/clean-exclude'

* jh/clean-exclude:
  Add test for git clean -e.
  Add -e/--exclude to git-clean.
This commit is contained in:
Junio C Hamano 2010-08-18 12:17:02 -07:00
commit 8d8c92521c
3 changed files with 39 additions and 2 deletions

View File

@ -8,7 +8,7 @@ git-clean - Remove untracked files from the working tree
SYNOPSIS SYNOPSIS
-------- --------
[verse] [verse]
'git clean' [-d] [-f] [-n] [-q] [-x | -X] [--] <path>... 'git clean' [-d] [-f] [-n] [-q] [-e <pattern>] [-x | -X] [--] <path>...
DESCRIPTION DESCRIPTION
----------- -----------
@ -45,6 +45,12 @@ OPTIONS
Be quiet, only report errors, but not the files that are Be quiet, only report errors, but not the files that are
successfully removed. successfully removed.
-e <pattern>::
--exclude=<pattern>::
Specify special exceptions to not be cleaned. Each <pattern> is
the same form as in $GIT_DIR/info/excludes and this option can be
given multiple times.
-x:: -x::
Don't use the ignore rules. This allows removing all untracked Don't use the ignore rules. This allows removing all untracked
files, including build products. This can be used (possibly in files, including build products. This can be used (possibly in

View File

@ -10,12 +10,13 @@
#include "cache.h" #include "cache.h"
#include "dir.h" #include "dir.h"
#include "parse-options.h" #include "parse-options.h"
#include "string-list.h"
#include "quote.h" #include "quote.h"
static int force = -1; /* unset */ static int force = -1; /* unset */
static const char *const builtin_clean_usage[] = { static const char *const builtin_clean_usage[] = {
"git clean [-d] [-f] [-n] [-q] [-x | -X] [--] <paths>...", "git clean [-d] [-f] [-n] [-q] [-e <pattern>] [-x | -X] [--] <paths>...",
NULL NULL
}; };
@ -26,6 +27,13 @@ static int git_clean_config(const char *var, const char *value, void *cb)
return git_default_config(var, value, cb); return git_default_config(var, value, cb);
} }
static int exclude_cb(const struct option *opt, const char *arg, int unset)
{
struct string_list *exclude_list = opt->value;
string_list_append(exclude_list, arg);
return 0;
}
int cmd_clean(int argc, const char **argv, const char *prefix) int cmd_clean(int argc, const char **argv, const char *prefix)
{ {
int i; int i;
@ -36,6 +44,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
struct dir_struct dir; struct dir_struct dir;
static const char **pathspec; static const char **pathspec;
struct strbuf buf = STRBUF_INIT; struct strbuf buf = STRBUF_INIT;
struct string_list exclude_list = { NULL, 0, 0, 0 };
const char *qname; const char *qname;
char *seen = NULL; char *seen = NULL;
struct option options[] = { struct option options[] = {
@ -44,6 +53,8 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
OPT_BOOLEAN('f', "force", &force, "force"), OPT_BOOLEAN('f', "force", &force, "force"),
OPT_BOOLEAN('d', NULL, &remove_directories, OPT_BOOLEAN('d', NULL, &remove_directories,
"remove whole directories"), "remove whole directories"),
{ OPTION_CALLBACK, 'e', "exclude", &exclude_list, "pattern",
"exclude <pattern>", PARSE_OPT_NONEG, exclude_cb },
OPT_BOOLEAN('x', NULL, &ignored, "remove ignored files, too"), OPT_BOOLEAN('x', NULL, &ignored, "remove ignored files, too"),
OPT_BOOLEAN('X', NULL, &ignored_only, OPT_BOOLEAN('X', NULL, &ignored_only,
"remove only ignored files"), "remove only ignored files"),
@ -81,6 +92,9 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
if (!ignored) if (!ignored)
setup_standard_excludes(&dir); setup_standard_excludes(&dir);
for (i = 0; i < exclude_list.nr; i++)
add_exclude(exclude_list.items[i].string, "", 0, dir.exclude_list);
pathspec = get_pathspec(prefix, argv); pathspec = get_pathspec(prefix, argv);
fill_directory(&dir, pathspec); fill_directory(&dir, pathspec);
@ -167,5 +181,6 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
free(seen); free(seen);
strbuf_release(&directory); strbuf_release(&directory);
string_list_clear(&exclude_list, 0);
return (errors != 0); return (errors != 0);
} }

View File

@ -438,4 +438,20 @@ test_expect_success 'force removal of nested git work tree' '
! test -d bar ! test -d bar
' '
test_expect_success 'git clean -e' '
rm -fr repo &&
mkdir repo &&
(
cd repo &&
git init &&
touch 1 2 3 known &&
git add known &&
git clean -f -e 1 -e 2 &&
test -e 1 &&
test -e 2 &&
! (test -e 3) &&
test -e known
)
'
test_done test_done