Add -e/--exclude to git-clean.
cover Add -e/--exclude to git-clean.
Changes:
- Use -e multiple times instead of using a separator
I'm starting a new thread since the code change is rather major. I've incorporated Julio's changes, touched up on them a bit, and updated the test suite so that it uses multiple instances of -e rather than using a separator in them.
Thanks to Julio and all that helped.
Jared Hance (2):
Add -e/--exclude to git-clean.
Add test for git clean -e.
Documentation/git-clean.txt | 8 +++++++- builtin/clean.c | 17 ++++++++++++++++- t/t7300-clean.sh | 16 ++++++++++++++++ 3 files changed, 39 insertions(+), 2 deletions(-)
My apologies, please:
%s/Julio/Junio/g
PATCH 1/2 Add -e/--exclude to git-clean.
In reply to Jared HanceWith the -e/--exclude option for git-clean, a user can specify files that they haven't yet told git about, but either need for a short amount of time or plan to tell git about them later. This allows one to still use git-clean while these files are around without losing data.
--- Documentation/git-clean.txt | 8 +++++++- builtin/clean.c | 17 ++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-)
Documentation/git-clean.txt +7 -1
@@ -8,7 +8,7 @@ git-clean - Remove untracked files from the working tree SYNOPSIS -------- [verse] -'git clean' [-d] [-f] [-n] [-q] [-x | -X] [--] <path>... +'git clean' [-d] [-f] [-n] [-q] [-e <pattern>] [-x | -X] [--] <path>... DESCRIPTION -----------
@@ -45,6 +45,12 @@ OPTIONS Be quiet, only report errors, but not the files that are 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:: Don't use the ignore rules. This allows removing all untracked files, including build products. This can be used (possibly in
builtin/clean.c +16 -1
@@ -10,12 +10,13 @@#include "cache.h" #include "dir.h" #include "parse-options.h" +#include "string-list.h" #include "quote.h" static int force =-1 ;/* unset */ 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 };
@@ -26,6 +27,13 @@ static int git_clean_config(const char *var, const char *value, void *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 = (struct string_list *)opt->value; +string_list_append (exclude_list, arg); +return 0 ; +} +int cmd_clean (int argc,const char **argv,const char *prefix) {int i;
@@ -36,6 +44,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)struct dir_struct dir;static const char **pathspec;struct strbuf buf =STRBUF_INIT ; +struct string_list exclude_list = {NULL ,0 ,0 ,0 };const char *qname;char *seen =NULL ;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 ('d' ,NULL , &remove_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_only, "remove only ignored files"),
@@ -81,6 +92,9 @@ int cmd_clean(int argc, const char **argv, const char *prefix)if (!ignored)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);fill_directory (&dir, pathspec);
@@ -167,5 +181,6 @@ int cmd_clean(int argc, const char **argv, const char *prefix)free (seen);strbuf_release (&directory); +string_list_clear (&exclude_list,0 );return (errors !=0 ); }
Signature · 1 line
1.7.1.1
Quoted 6 lines · Jared Hance
With the -e/--exclude option for git-clean, a user can specify files that they haven't yet told git about, but either need for a short amount of time or plan to tell git about them later. This allows one to still use git-clean while these files are around without losing data.
Signed-off-by Jared Hance <[email protected]>
Thanks.
builtin/clean.c static int git_clean_config(const char *var, const char *value, void *cb) · line 32
Quoted 3 lines
builtin/clean.c +3
-0+static int exclude_cb (const struct option *opt,const char *arg,int unset) +{ +struct string_list *exclude_list = (struct string_list *)opt->value;
Unnecessary cast, as opt->value is of type (void *).
builtin/clean.c int cmd_clean(int argc, const char **argv, const char *prefix) · line 47
Quoted 5 lines
builtin/clean.c +1
-0@@ -36,6 +44,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)struct dir_struct dir;static const char **pathspec;struct strbuf buf =STRBUF_INIT ; +struct string_list exclude_list = {NULL ,0 ,0 ,0 };
Mental note to myself. We should convert this to use STRING_LIST_INIT after the next release when Thiago's patch graduates to 'master'.
PATCH 2/2 Add test for git clean -e.
In reply to Jared Hance--- t/t7300-clean.sh | 16 ++++++++++++++++ 1 files changed, 16 insertions(+), 0 deletions(-)
t/t7300-clean.sh +16 -0
@@ -438,4 +438,20 @@ test_expect_success 'force removal of nested git work tree' ' ! 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
Signature · 1 line
1.7.1.1
Re: [PATCH 2/2] Add test for git clean -e.
Quoted 18 lines · Jared Hance
Signed-off-by Jared Hance <[email protected]>--- t/t7300-clean.sh | 16 ++++++++++++++++ 1 files changed, 16 insertions(+), 0 deletions(-)t/t7300-clean.sh +5
-0@@ -438,4 +438,20 @@ test_expect_success 'force removal of nested git work tree' ' ! test -d bar ' +test_expect_success 'git clean -e' ' + rm -fr repo && + mkdir repo && + ( + cd repo &&
t/t7300-clean.sh test_expect_success 'force removal of nested git work tree' ' · line 455
Quoted 10 lines
t/t7300-clean.sh +10
-0+ 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 + ) +'
This is a good start but it doesn't seem to test possible interactions with entries in .gitignore file(s) in the working tree. Do we care?
What should happen when a path "path":
(1) is marked to be ignored in .gitignore and -e "path" is also given;
(2) is marked not to be ignored (i.e. "!path") in .gitignore but -e
"path" is given;
(3) is marked to be ignored in .gitignore but -e "!path" is given;
(4) is marked not to be ignored in .gitignore and -e "!path" is also
given;
(5) perhaps other combinations like "!path" in a/.gitignore, and -e "a/path" from the command line.
What does the code actually do?
Re: [PATCH 2/2] Add test for git clean -e.
Quoted 2 lines · Junio C Hamano
This is a good start but it doesn't seem to test possible interactions with entries in .gitignore file(s) in the working tree. Do we care?
Honestly, I'm not sure that we do care.
Quoted 4 lines
What should happen when a path "path":
(1) is marked to be ignored in .gitignore and -e "path" is also given;
It is excluded.
Quoted 2 lines
(2) is marked not to be ignored (i.e. "!path") in .gitignore but -e
"path" is given;
I think it would be good for "!path" to cause -e path to have no effect because of globbing issues.
Currently, -e works as normal.
Quoted 1 line
(3) is marked to be ignored in .gitignore but -e "!path" is given;
Again, I'm not sure and am definately open to debate here. Personally, I think that -e "!path" is completely abusing the use of -e, because it is using -e to NOT exclude something.
Currently, -e has no effect.
Quoted 2 lines
(4) is marked not to be ignored in .gitignore and -e "!path" is also
given;
No effect happens. Again, this is abuse of -e in my opinion, as its goal to allow one to do a clean and save one or two files.
Quoted 2 lines
(5) perhaps other combinations like "!path" in a/.gitignore, and -e "a/path" from the command line.
Judging by (2), -e will work as normal.