{"thread":{"id":"24433","subject":"[PATCH] Add --exclude to git-clean.j","startedAt":"2010-07-19T15:50:08Z","lastAt":"2010-09-23T09:05:05Z","messageCount":16,"participants":["Jared Hance","Jonathan Nieder","Junio C Hamano","Aaron Crane","Louis Strous"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"145791","messageId":"bf4ea4e83162ebf1d915b87413aad54a1162a637.1279554580.git.jaredhance@gmail.com","threadId":"24433","inReplyTo":null,"subject":"[PATCH] Add --exclude to git-clean.j","fromName":"Jared Hance","fromEmail":"jaredhance@gmail.com","sentAt":"2010-07-19T15:50:08Z","receivedAt":"2010-07-19T15:50:08Z","isPatch":true,"sender":{"key":"jaredhance@gmail.com","avatar":"https://avatars.githubusercontent.com/u/170192?v=4"},"body":"With the -e/--exclude option for git-clean, a user can specify files\nthat they haven't yet told git about, but either need for a short amount\nof time or plan to tell git about them later. This allows one to still\nuse git-clean while these files are around without losing data.\n\nSigned-off-by: Jared Hance <jaredhance@gmail.com>\n---\n Documentation/git-clean.txt |    6 +++++-\n builtin/clean.c             |   21 +++++++++++++++++++++\n 2 files changed, 26 insertions(+), 1 deletions(-)\n\ndiff --git a/Documentation/git-clean.txt b/Documentation/git-clean.txt\nindex a81cb6c..2bf9cf2 100644\n--- a/Documentation/git-clean.txt\n+++ b/Documentation/git-clean.txt\n@@ -8,7 +8,7 @@ git-clean - Remove untracked files from the working tree\n SYNOPSIS\n --------\n [verse]\n-'git clean' [-d] [-f] [-n] [-q] [-x | -X] [--] <path>...\n+'git clean' [-d] [-f] [-n] [-q] [-e] [-x | -X] [--] <path>...\n \n DESCRIPTION\n -----------\n@@ -45,6 +45,10 @@ OPTIONS\n \tBe quiet, only report errors, but not the files that are\n \tsuccessfully removed.\n \n+-e::\n+--exclude::\n+\tSpecify special exceptions to not be cleaned. Separate with colon.\n+\n -x::\n \tDon't use the ignore rules.  This allows removing all untracked\n \tfiles, including build products.  This can be used (possibly in\ndiff --git a/builtin/clean.c b/builtin/clean.c\nindex fac64e6..aa3eed8 100644\n--- a/builtin/clean.c\n+++ b/builtin/clean.c\n@@ -13,6 +13,7 @@\n #include \"quote.h\"\n \n static int force = -1; /* unset */\n+static char *excludes;\n \n static const char *const builtin_clean_usage[] = {\n \t\"git clean [-d] [-f] [-n] [-q] [-x | -X] [--] <paths>...\",\n@@ -36,6 +37,8 @@ int cmd_clean(int argc, const char **argv, const char *prefix)\n \tstruct dir_struct dir;\n \tstatic const char **pathspec;\n \tstruct strbuf buf = STRBUF_INIT;\n+\tstruct strbuf excludes_buf = STRBUF_INIT;\n+\tstruct strbuf **excludes_split;\n \tconst char *qname;\n \tchar *seen = NULL;\n \tstruct option options[] = {\n@@ -44,6 +47,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)\n \t\tOPT_BOOLEAN('f', \"force\", &force, \"force\"),\n \t\tOPT_BOOLEAN('d', NULL, &remove_directories,\n \t\t\t\t\"remove whole directories\"),\n+\t\tOPT_STRING('e', \"exclude\", &excludes, \"EXCLUDES\", \"specify files not to clean\"),\n \t\tOPT_BOOLEAN('x', NULL, &ignored, \"remove ignored files, too\"),\n \t\tOPT_BOOLEAN('X', NULL, &ignored_only,\n \t\t\t\t\"remove only ignored files\"),\n@@ -81,6 +85,17 @@ int cmd_clean(int argc, const char **argv, const char *prefix)\n \tif (!ignored)\n \t\tsetup_standard_excludes(&dir);\n \n+\tif (excludes) {\n+\t\tstrbuf_addstr(&excludes_buf, excludes);\n+\t\texcludes_split = strbuf_split(&excludes_buf, ':');\n+\t\tfor (i = 0; excludes_split[i]; i++) {\n+\t\t\tif (excludes_split[i]->buf[excludes_split[i]->len - 1] == ':') {\n+\t\t\t\tstrbuf_remove(excludes_split[i], excludes_split[i]->len - 1, 1);\n+\t\t\t}\n+\t\t\tadd_exclude(excludes_split[i]->buf, \"\", 0, dir.exclude_list);\n+\t\t}\n+\t}\n+\n \tpathspec = get_pathspec(prefix, argv);\n \n \tfill_directory(&dir, pathspec);\n@@ -167,5 +182,11 @@ int cmd_clean(int argc, const char **argv, const char *prefix)\n \tfree(seen);\n \n \tstrbuf_release(&directory);\n+\tif (excludes) {\n+\t\tstrbuf_release(&excludes_buf);\n+\t\tfor (i = 0; excludes_split[i]; i++) {\n+\t\t\tstrbuf_release(excludes_split[i]);\n+\t\t}\n+\t}\n \treturn (errors != 0);\n }\n-- \n1.7.1.1\n"},{"id":"145793","messageId":"20100719161414.GA17597@burratino","threadId":"24433","inReplyTo":"bf4ea4e83162ebf1d915b87413aad54a1162a637.1279554580.git.jaredhance@gmail.com","subject":"Re: [PATCH] Add --exclude to git-clean.j","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-07-19T16:14:14Z","receivedAt":"2010-07-19T16:14:14Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Jared Hance wrote:\n\n> With the -e/--exclude option for git-clean, a user can specify files\n> that they haven't yet told git about, but either need for a short amount\n> of time or plan to tell git about them later.\n\nNo thoughts on your patch, but have you looked into “git add -N”?\n\nJonathan\n"},{"id":"145794","messageId":"bf4ea4e83162ebf1d915b87413aad54a1162a637.1279556172.git.jaredhance@gmail.com","threadId":"24433","inReplyTo":"bf4ea4e83162ebf1d915b87413aad54a1162a637.1279554580.git.jaredhance@gmail.com","subject":"[PATCH v2] Add --exclude to git-clean.","fromName":"Jared Hance","fromEmail":"jaredhance@gmail.com","sentAt":"2010-07-19T16:18:08Z","receivedAt":"2010-07-19T16:18:08Z","isPatch":true,"sender":{"key":"jaredhance@gmail.com","avatar":"https://avatars.githubusercontent.com/u/170192?v=4"},"body":"With the -e/--exclude option for git-clean, a user can specify files\nthat they haven't yet told git about, but either need for a short amount\nof time or plan to tell git about them later. This allows one to still\nuse git-clean while these files are around without losing data.\n\nSigned-off-by: Jared Hance <jaredhance@gmail.com>\n---\n Documentation/git-clean.txt |    6 +++++-\n builtin/clean.c             |   21 +++++++++++++++++++++\n 2 files changed, 26 insertions(+), 1 deletions(-)\n\ndiff --git a/Documentation/git-clean.txt b/Documentation/git-clean.txt\nindex a81cb6c..2bf9cf2 100644\n--- a/Documentation/git-clean.txt\n+++ b/Documentation/git-clean.txt\n@@ -8,7 +8,7 @@ git-clean - Remove untracked files from the working tree\n SYNOPSIS\n --------\n [verse]\n-'git clean' [-d] [-f] [-n] [-q] [-x | -X] [--] <path>...\n+'git clean' [-d] [-f] [-n] [-q] [-e] [-x | -X] [--] <path>...\n \n DESCRIPTION\n -----------\n@@ -45,6 +45,10 @@ OPTIONS\n \tBe quiet, only report errors, but not the files that are\n \tsuccessfully removed.\n \n+-e::\n+--exclude::\n+\tSpecify special exceptions to not be cleaned. Separate with colon.\n+\n -x::\n \tDon't use the ignore rules.  This allows removing all untracked\n \tfiles, including build products.  This can be used (possibly in\ndiff --git a/builtin/clean.c b/builtin/clean.c\nindex fac64e6..aa3eed8 100644\n--- a/builtin/clean.c\n+++ b/builtin/clean.c\n@@ -13,6 +13,7 @@\n #include \"quote.h\"\n \n static int force = -1; /* unset */\n+static char *excludes;\n \n static const char *const builtin_clean_usage[] = {\n \t\"git clean [-d] [-f] [-n] [-q] [-x | -X] [--] <paths>...\",\n@@ -36,6 +37,8 @@ int cmd_clean(int argc, const char **argv, const char *prefix)\n \tstruct dir_struct dir;\n \tstatic const char **pathspec;\n \tstruct strbuf buf = STRBUF_INIT;\n+\tstruct strbuf excludes_buf = STRBUF_INIT;\n+\tstruct strbuf **excludes_split;\n \tconst char *qname;\n \tchar *seen = NULL;\n \tstruct option options[] = {\n@@ -44,6 +47,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)\n \t\tOPT_BOOLEAN('f', \"force\", &force, \"force\"),\n \t\tOPT_BOOLEAN('d', NULL, &remove_directories,\n \t\t\t\t\"remove whole directories\"),\n+\t\tOPT_STRING('e', \"exclude\", &excludes, \"EXCLUDES\", \"specify files not to clean\"),\n \t\tOPT_BOOLEAN('x', NULL, &ignored, \"remove ignored files, too\"),\n \t\tOPT_BOOLEAN('X', NULL, &ignored_only,\n \t\t\t\t\"remove only ignored files\"),\n@@ -81,6 +85,17 @@ int cmd_clean(int argc, const char **argv, const char *prefix)\n \tif (!ignored)\n \t\tsetup_standard_excludes(&dir);\n \n+\tif (excludes) {\n+\t\tstrbuf_addstr(&excludes_buf, excludes);\n+\t\texcludes_split = strbuf_split(&excludes_buf, ':');\n+\t\tfor (i = 0; excludes_split[i]; i++) {\n+\t\t\tif (excludes_split[i]->buf[excludes_split[i]->len - 1] == ':') {\n+\t\t\t\tstrbuf_remove(excludes_split[i], excludes_split[i]->len - 1, 1);\n+\t\t\t}\n+\t\t\tadd_exclude(excludes_split[i]->buf, \"\", 0, dir.exclude_list);\n+\t\t}\n+\t}\n+\n \tpathspec = get_pathspec(prefix, argv);\n \n \tfill_directory(&dir, pathspec);\n@@ -167,5 +182,11 @@ int cmd_clean(int argc, const char **argv, const char *prefix)\n \tfree(seen);\n \n \tstrbuf_release(&directory);\n+\tif (excludes) {\n+\t\tstrbuf_release(&excludes_buf);\n+\t\tfor (i = 0; excludes_split[i]; i++) {\n+\t\t\tstrbuf_release(excludes_split[i]);\n+\t\t}\n+\t}\n \treturn (errors != 0);\n }\n-- \n1.7.1.1\n"},{"id":"145795","messageId":"20100719162116.GA4463@localhost.localdomain","threadId":"24433","inReplyTo":"20100719161414.GA17597@burratino","subject":"Re: [PATCH] Add --exclude to git-clean.j","fromName":"Jared Hance","fromEmail":"jaredhance@gmail.com","sentAt":"2010-07-19T16:21:16Z","receivedAt":"2010-07-19T16:21:16Z","isPatch":true,"sender":{"key":"jaredhance@gmail.com","avatar":"https://avatars.githubusercontent.com/u/170192?v=4"},"body":"On Mon, Jul 19, 2010 at 11:14:14AM -0500, Jonathan Nieder wrote:\nJohnathon wrote:\n> No thoughts on your patch, but have you looked into “git add -N”?\n\nThat is interesting. However, it doesn't really help for files that\nyou don't intend to add to the index later. \"git clean -e\" is nice for\nwhen you have a file you are using for some temporary purpose.\n\nOn another note, I failed getting my title correct, so I sent another\npatch with the correct title (I think it affects the description of\nthe commit).\n"},{"id":"145802","messageId":"7vbpa3pdtc.fsf@alter.siamese.dyndns.org","threadId":"24433","inReplyTo":"bf4ea4e83162ebf1d915b87413aad54a1162a637.1279556172.git.jaredhance@gmail.com","subject":"Re: [PATCH v2] Add --exclude to git-clean.","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-07-19T17:43:43Z","receivedAt":"2010-07-19T17:43:43Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jared Hance <jaredhance@gmail.com> writes:\n\n> diff --git a/Documentation/git-clean.txt b/Documentation/git-clean.txt\n> index a81cb6c..2bf9cf2 100644\n> --- a/Documentation/git-clean.txt\n> +++ b/Documentation/git-clean.txt\n> @@ -8,7 +8,7 @@ git-clean - Remove untracked files from the working tree\n>  SYNOPSIS\n>  --------\n>  [verse]\n> -'git clean' [-d] [-f] [-n] [-q] [-x | -X] [--] <path>...\n> +'git clean' [-d] [-f] [-n] [-q] [-e] [-x | -X] [--] <path>...\n\nThis and ...\n\n>  DESCRIPTION\n>  -----------\n> @@ -45,6 +45,10 @@ OPTIONS\n>  \tBe quiet, only report errors, but not the files that are\n>  \tsuccessfully removed.\n>  \n> +-e::\n> +--exclude::\n\nthis both look wrong.  They do not tell the readers that the option takes\na mandatory argument that specifies the \"exceptions\".  Worse yet,\n\n> +\tSpecify special exceptions to not be cleaned. Separate with colon.\n\nthis does not tell _how_ exceptions are specified.\n\nWhat should each element on the list look like?\n\nIs it a dot-suffix without dot (e.g. \"html\") or with dot (e.g. \".html\")?\nOr is it a glob (e.g. \"*.html\")?  Or is it a full path relative to the\nworktree root (e.g. \"Documentation/index.html\")?\n\nUsing colon as an inter-element separator makes sense only if last one is\ntrue (i.e. \"concrete path, not glob nor suffix\"), so an intelligent reader\ncould probably guess what you meant, but you shouldn't make readers guess\nin the first place.\n\nIf on the other hand you wanted to allow specifying the same kind of\npatterns used in the gitignore files from the command line:\n\n (1) A list separated with whitespace would be more natural, not a colon;\n     and\n\n (2) I have to wonder why do we give such a command line exclude override\n     to begin with.\n\n     (2-a) wouldn't it be easier for the user to add such a local\n           configuration to $GIT_DIR/info/exclude once and be done with\n           it?\n\n     (2-b) if command-line override has benefit, why is it limited to only\n           _exclude_ and not include (iow, additional ignore patterns)?\n"},{"id":"145805","messageId":"20100719182233.GA4713@localhost.localdomain","threadId":"24433","inReplyTo":"7vbpa3pdtc.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH v2] Add --exclude to git-clean.","fromName":"Jared Hance","fromEmail":"jaredhance@gmail.com","sentAt":"2010-07-19T18:22:33Z","receivedAt":"2010-07-19T18:22:33Z","isPatch":true,"sender":{"key":"jaredhance@gmail.com","avatar":"https://avatars.githubusercontent.com/u/170192?v=4"},"body":"On Mon, Jul 19, 2010 at 10:43:43AM -0700, Junio C Hamano wrote:\n> this both look wrong.  They do not tell the readers that the option takes\n> a mandatory argument that specifies the \"exceptions\".  Worse yet,\n\nSorry about that. I will get that fixed.\n\n> > +\tSpecify special exceptions to not be cleaned. Separate with colon.\n> \n> this does not tell _how_ exceptions are specified.\n> \n> What should each element on the list look like?\n> \n> Is it a dot-suffix without dot (e.g. \"html\") or with dot (e.g. \".html\")?\n> Or is it a glob (e.g. \"*.html\")?  Or is it a full path relative to the\n> worktree root (e.g. \"Documentation/index.html\")?\n> \n> Using colon as an inter-element separator makes sense only if last one is\n> true (i.e. \"concrete path, not glob nor suffix\"), so an intelligent reader\n> could probably guess what you meant, but you shouldn't make readers guess\n> in the first place.\n> \n> If on the other hand you wanted to allow specifying the same kind of\n> patterns used in the gitignore files from the command line:\n> \n>  (1) A list separated with whitespace would be more natural, not a colon;\n>      and\n\nIt is a global (like in the .gitignore file). I will change it to\nwhitespace. At first, I was worried about files with whitespace, and a\ncolon seemed to fit it better (since files don't have colons).\n\nOn the other hand, can you think of any character that would fit both\na glob and a strict filename (as it allows both)? I had trouble\nfiguring out what to use here.\n\n>  (2) I have to wonder why do we give such a command line exclude override\n>      to begin with.\n> \n>      (2-a) wouldn't it be easier for the user to add such a local\n>            configuration to $GIT_DIR/info/exclude once and be done with\n>            it?\n\nAs I said earlier, its generally useful for files you are only going\nto have for a few minutes and you don't want to have the clutter up\n$GIT_DIR/info/exclude with them (since they probably won't ever\nreturn).\n\n>      (2-b) if command-line override has benefit, why is it limited to only\n>            _exclude_ and not include (iow, additional ignore patterns)?\n\n\"git clean && git rm <INCLUDES>\" has the same effect as including in\nthe clean.\n"},{"id":"145806","messageId":"e257dd98b7493dcd72de9cf62d5847116e030ed0.1279564639.git.jaredhance@gmail.com","threadId":"24433","inReplyTo":"bf4ea4e83162ebf1d915b87413aad54a1162a637.1279556172.git.jaredhance@gmail.com","subject":"[PATCH v3] Add --exclude to git-clean.","fromName":"Jared Hance","fromEmail":"jaredhance@gmail.com","sentAt":"2010-07-19T18:39:46Z","receivedAt":"2010-07-19T18:39:46Z","isPatch":true,"sender":{"key":"jaredhance@gmail.com","avatar":"https://avatars.githubusercontent.com/u/170192?v=4"},"body":"With the -e/--exclude option for git-clean, a user can specify files\nthat they haven't yet told git about, but either need for a short amount\nof time or plan to tell git about them later. This allows one to still\nuse git-clean while these files are around without losing data.\n\nSigned-off-by: Jared Hance <jaredhance@gmail.com>\n---\n Documentation/git-clean.txt |    7 ++++++-\n builtin/clean.c             |   21 +++++++++++++++++++++\n 2 files changed, 27 insertions(+), 1 deletions(-)\n\ndiff --git a/Documentation/git-clean.txt b/Documentation/git-clean.txt\nindex a81cb6c..488e103 100644\n--- a/Documentation/git-clean.txt\n+++ b/Documentation/git-clean.txt\n@@ -8,7 +8,7 @@ git-clean - Remove untracked files from the working tree\n SYNOPSIS\n --------\n [verse]\n-'git clean' [-d] [-f] [-n] [-q] [-x | -X] [--] <path>...\n+'git clean' [-d] [-f] [-n] [-q] [-e] [-x | -X] [--] <path>...\n \n DESCRIPTION\n -----------\n@@ -45,6 +45,11 @@ OPTIONS\n \tBe quiet, only report errors, but not the files that are\n \tsuccessfully removed.\n \n+-e <files>::\n+--exclude=<files>::\n+\tSpecify special exceptions to not be cleaned. Separate with a space.\n+\tGlobs, like that in $GIT_DIR/info/excludes, should be used.\n+\n -x::\n \tDon't use the ignore rules.  This allows removing all untracked\n \tfiles, including build products.  This can be used (possibly in\ndiff --git a/builtin/clean.c b/builtin/clean.c\nindex fac64e6..b1da923 100644\n--- a/builtin/clean.c\n+++ b/builtin/clean.c\n@@ -13,6 +13,7 @@\n #include \"quote.h\"\n \n static int force = -1; /* unset */\n+static const char *excludes;\n \n static const char *const builtin_clean_usage[] = {\n \t\"git clean [-d] [-f] [-n] [-q] [-x | -X] [--] <paths>...\",\n@@ -36,6 +37,8 @@ int cmd_clean(int argc, const char **argv, const char *prefix)\n \tstruct dir_struct dir;\n \tstatic const char **pathspec;\n \tstruct strbuf buf = STRBUF_INIT;\n+\tstruct strbuf excludes_buf = STRBUF_INIT;\n+\tstruct strbuf **excludes_split = NULL;\n \tconst char *qname;\n \tchar *seen = NULL;\n \tstruct option options[] = {\n@@ -44,6 +47,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)\n \t\tOPT_BOOLEAN('f', \"force\", &force, \"force\"),\n \t\tOPT_BOOLEAN('d', NULL, &remove_directories,\n \t\t\t\t\"remove whole directories\"),\n+\t\tOPT_STRING('e', \"exclude\", &excludes, \"EXCLUDES\", \"specify files not to clean\"),\n \t\tOPT_BOOLEAN('x', NULL, &ignored, \"remove ignored files, too\"),\n \t\tOPT_BOOLEAN('X', NULL, &ignored_only,\n \t\t\t\t\"remove only ignored files\"),\n@@ -81,6 +85,17 @@ int cmd_clean(int argc, const char **argv, const char *prefix)\n \tif (!ignored)\n \t\tsetup_standard_excludes(&dir);\n \n+\tif (excludes) {\n+\t\tstrbuf_addstr(&excludes_buf, excludes);\n+\t\texcludes_split = strbuf_split(&excludes_buf, ' ');\n+\t\tfor (i = 0; excludes_split[i]; i++) {\n+\t\t\tif (excludes_split[i]->buf[excludes_split[i]->len - 1] == ' ') {\n+\t\t\t\tstrbuf_remove(excludes_split[i], excludes_split[i]->len - 1, 1);\n+\t\t\t}\n+\t\t\tadd_exclude(excludes_split[i]->buf, \"\", 0, dir.exclude_list);\n+\t\t}\n+\t}\n+\n \tpathspec = get_pathspec(prefix, argv);\n \n \tfill_directory(&dir, pathspec);\n@@ -167,5 +182,11 @@ int cmd_clean(int argc, const char **argv, const char *prefix)\n \tfree(seen);\n \n \tstrbuf_release(&directory);\n+\tif (excludes) {\n+\t\tstrbuf_release(&excludes_buf);\n+\t\tfor (i = 0; excludes_split[i]; i++) {\n+\t\t\tstrbuf_release(excludes_split[i]);\n+\t\t}\n+\t}\n \treturn (errors != 0);\n }\n-- \n1.7.1.1\n"},{"id":"145862","messageId":"cover.1279643093.git.jaredhance@gmail.com","threadId":"24433","inReplyTo":"e257dd98b7493dcd72de9cf62d5847116e030ed0.1279564639.git.jaredhance@gmail.com","subject":"[PATCH/RFC v4 0/2] Add -e/--exclude to git clean.","fromName":"Jared Hance","fromEmail":"jaredhance@gmail.com","sentAt":"2010-07-20T16:28:59Z","receivedAt":"2010-07-20T16:28:59Z","isPatch":true,"sender":{"key":"jaredhance@gmail.com","avatar":"https://avatars.githubusercontent.com/u/170192?v=4"},"body":"This is the fourth round of patches for git clean -e.\n\nThis round introduces a test in t/t7300-clean.sh.\n\nNo other changes were added to builtin/clean.c or\nDocumentation/git-clean.txt.\n\nSince this patch seems to be somewhat controversial, I've marked it as\nPATCH/RFC. I would like some ideas on what to use for separators as\nwell as constructive critism on the Documentation and test.\n\nJared Hance (2):\n  Add --exclude to git-clean.\n  Add test for git clean -e.\n\n Documentation/git-clean.txt |    7 ++++++-\n builtin/clean.c             |   21 +++++++++++++++++++++\n t/t7300-clean.sh            |   16 ++++++++++++++++\n 3 files changed, 43 insertions(+), 1 deletions(-)\n"},{"id":"145863","messageId":"452009b969a32d7852cd82bf9c9d8973772e1c26.1279643093.git.jaredhance@gmail.com","threadId":"24433","inReplyTo":"cover.1279643093.git.jaredhance@gmail.com","subject":"[PATCH/RFC v4 1/2] Add --exclude to git-clean.","fromName":"Jared Hance","fromEmail":"jaredhance@gmail.com","sentAt":"2010-07-20T16:29:27Z","receivedAt":"2010-07-20T16:29:27Z","isPatch":true,"sender":{"key":"jaredhance@gmail.com","avatar":"https://avatars.githubusercontent.com/u/170192?v=4"},"body":"With the -e/--exclude option for git-clean, a user can specify files\nthat they haven't yet told git about, but either need for a short amount\nof time or plan to tell git about them later. This allows one to still\nuse git-clean while these files are around without losing data.\n\nSigned-off-by: Jared Hance <jaredhance@gmail.com>\n---\n Documentation/git-clean.txt |    7 ++++++-\n builtin/clean.c             |   21 +++++++++++++++++++++\n 2 files changed, 27 insertions(+), 1 deletions(-)\n\ndiff --git a/Documentation/git-clean.txt b/Documentation/git-clean.txt\nindex a81cb6c..488e103 100644\n--- a/Documentation/git-clean.txt\n+++ b/Documentation/git-clean.txt\n@@ -8,7 +8,7 @@ git-clean - Remove untracked files from the working tree\n SYNOPSIS\n --------\n [verse]\n-'git clean' [-d] [-f] [-n] [-q] [-x | -X] [--] <path>...\n+'git clean' [-d] [-f] [-n] [-q] [-e] [-x | -X] [--] <path>...\n \n DESCRIPTION\n -----------\n@@ -45,6 +45,11 @@ OPTIONS\n \tBe quiet, only report errors, but not the files that are\n \tsuccessfully removed.\n \n+-e <files>::\n+--exclude=<files>::\n+\tSpecify special exceptions to not be cleaned. Separate with a space.\n+\tGlobs, like that in $GIT_DIR/info/excludes, should be used.\n+\n -x::\n \tDon't use the ignore rules.  This allows removing all untracked\n \tfiles, including build products.  This can be used (possibly in\ndiff --git a/builtin/clean.c b/builtin/clean.c\nindex fac64e6..b1da923 100644\n--- a/builtin/clean.c\n+++ b/builtin/clean.c\n@@ -13,6 +13,7 @@\n #include \"quote.h\"\n \n static int force = -1; /* unset */\n+static const char *excludes;\n \n static const char *const builtin_clean_usage[] = {\n \t\"git clean [-d] [-f] [-n] [-q] [-x | -X] [--] <paths>...\",\n@@ -36,6 +37,8 @@ int cmd_clean(int argc, const char **argv, const char *prefix)\n \tstruct dir_struct dir;\n \tstatic const char **pathspec;\n \tstruct strbuf buf = STRBUF_INIT;\n+\tstruct strbuf excludes_buf = STRBUF_INIT;\n+\tstruct strbuf **excludes_split = NULL;\n \tconst char *qname;\n \tchar *seen = NULL;\n \tstruct option options[] = {\n@@ -44,6 +47,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)\n \t\tOPT_BOOLEAN('f', \"force\", &force, \"force\"),\n \t\tOPT_BOOLEAN('d', NULL, &remove_directories,\n \t\t\t\t\"remove whole directories\"),\n+\t\tOPT_STRING('e', \"exclude\", &excludes, \"EXCLUDES\", \"specify files not to clean\"),\n \t\tOPT_BOOLEAN('x', NULL, &ignored, \"remove ignored files, too\"),\n \t\tOPT_BOOLEAN('X', NULL, &ignored_only,\n \t\t\t\t\"remove only ignored files\"),\n@@ -81,6 +85,17 @@ int cmd_clean(int argc, const char **argv, const char *prefix)\n \tif (!ignored)\n \t\tsetup_standard_excludes(&dir);\n \n+\tif (excludes) {\n+\t\tstrbuf_addstr(&excludes_buf, excludes);\n+\t\texcludes_split = strbuf_split(&excludes_buf, ' ');\n+\t\tfor (i = 0; excludes_split[i]; i++) {\n+\t\t\tif (excludes_split[i]->buf[excludes_split[i]->len - 1] == ' ') {\n+\t\t\t\tstrbuf_remove(excludes_split[i], excludes_split[i]->len - 1, 1);\n+\t\t\t}\n+\t\t\tadd_exclude(excludes_split[i]->buf, \"\", 0, dir.exclude_list);\n+\t\t}\n+\t}\n+\n \tpathspec = get_pathspec(prefix, argv);\n \n \tfill_directory(&dir, pathspec);\n@@ -167,5 +182,11 @@ int cmd_clean(int argc, const char **argv, const char *prefix)\n \tfree(seen);\n \n \tstrbuf_release(&directory);\n+\tif (excludes) {\n+\t\tstrbuf_release(&excludes_buf);\n+\t\tfor (i = 0; excludes_split[i]; i++) {\n+\t\t\tstrbuf_release(excludes_split[i]);\n+\t\t}\n+\t}\n \treturn (errors != 0);\n }\n-- \n1.7.1.1\n"},{"id":"145864","messageId":"4cc65cc57f6eea298401a2de0aa5fb378703fb38.1279643093.git.jaredhance@gmail.com","threadId":"24433","inReplyTo":"cover.1279643093.git.jaredhance@gmail.com","subject":"[PATCH 2/2] Add test for git clean -e.","fromName":"Jared Hance","fromEmail":"jaredhance@gmail.com","sentAt":"2010-07-20T16:30:13Z","receivedAt":"2010-07-20T16:30:13Z","isPatch":true,"sender":{"key":"jaredhance@gmail.com","avatar":"https://avatars.githubusercontent.com/u/170192?v=4"},"body":"\nSigned-off-by: Jared Hance <jaredhance@gmail.com>\n---\n t/t7300-clean.sh |   16 ++++++++++++++++\n 1 files changed, 16 insertions(+), 0 deletions(-)\n\ndiff --git a/t/t7300-clean.sh b/t/t7300-clean.sh\nindex 7d8ed68..c6df26d 100755\n--- a/t/t7300-clean.sh\n+++ b/t/t7300-clean.sh\n@@ -438,4 +438,20 @@ test_expect_success 'force removal of nested git work tree' '\n \t! test -d bar\n '\n \n+test_expect_success 'git clean -e' '\n+\trm -fr repo &&\n+\tmkdir repo &&\n+\t(\n+\t\tcd repo &&\n+\t\tgit init &&\n+\t\ttouch 1 2 3 known &&\n+\t\tgit add known &&\n+\t\tgit clean -f -e \"1 2\" &&\n+\t\ttest -e 1 &&\n+\t\ttest -e 2 &&\n+\t\t! (test -e 3) &&\n+\t\ttest -e known\n+\t)\n+'\n+\n test_done\n-- \n1.7.1.1\n"},{"id":"145869","messageId":"AANLkTinzavHKSVs4BYGtc-T1IKAS21yk-yzybn7G7IaZ@mail.gmail.com","threadId":"24433","inReplyTo":"cover.1279643093.git.jaredhance@gmail.com","subject":"Re: [PATCH/RFC v4 0/2] Add -e/--exclude to git clean.","fromName":"Aaron Crane","fromEmail":"git@aaroncrane.co.uk","sentAt":"2010-07-20T17:03:36Z","receivedAt":"2010-07-20T17:03:36Z","isPatch":true,"sender":{"key":"git@aaroncrane.co.uk","avatar":null},"body":"Jared Hance <jaredhance@gmail.com> wrote:\n> This is the fourth round of patches for git clean -e.\n> Since this patch seems to be somewhat controversial, I've marked it as\n> PATCH/RFC. I would like some ideas on what to use for separators\n\nRather than stuffing multiple exclusions into a single option, how\nabout requiring one -e option per exclusion?\n\ngit clean -e foo -e bar\n\n-- \nAaron Crane ** http://aaroncrane.co.uk/\n"},{"id":"145870","messageId":"20100720171317.GA8693@localhost.localdomain","threadId":"24433","inReplyTo":"AANLkTinzavHKSVs4BYGtc-T1IKAS21yk-yzybn7G7IaZ@mail.gmail.com","subject":"Re: [PATCH/RFC v4 0/2] Add -e/--exclude to git clean.","fromName":"Jared Hance","fromEmail":"jaredhance@gmail.com","sentAt":"2010-07-20T17:13:17Z","receivedAt":"2010-07-20T17:13:17Z","isPatch":true,"sender":{"key":"jaredhance@gmail.com","avatar":"https://avatars.githubusercontent.com/u/170192?v=4"},"body":"On Tue, Jul 20, 2010 at 06:03:36PM +0100, Aaron Crane wrote:\n> Rather than stuffing multiple exclusions into a single option, how\n> about requiring one -e option per exclusion?\n> \n> git clean -e foo -e bar\n\nI actually considered that - However,\nDocumentation/technical/api-parse-options.txt does not document how to\ndo this type of thing with the the parse options api. I will look into\nthe code for some examples to see if I can figure it out.\n"},{"id":"145877","messageId":"7vaapmm3ow.fsf@alter.siamese.dyndns.org","threadId":"24433","inReplyTo":"AANLkTinzavHKSVs4BYGtc-T1IKAS21yk-yzybn7G7IaZ@mail.gmail.com","subject":"Re: [PATCH/RFC v4 0/2] Add -e/--exclude to git clean.","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-07-20T18:02:55Z","receivedAt":"2010-07-20T18:02:55Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Aaron Crane <git@aaroncrane.co.uk> writes:\n\n> Jared Hance <jaredhance@gmail.com> wrote:\n>> This is the fourth round of patches for git clean -e.\n>> Since this patch seems to be somewhat controversial, I've marked it as\n>> PATCH/RFC. I would like some ideas on what to use for separators\n>\n> Rather than stuffing multiple exclusions into a single option, how\n> about requiring one -e option per exclusion?\n>\n> git clean -e foo -e bar\n\nI find it a lot saner.\n\nSorry, Jared, I should have thought of it and suggested it during the\nfirst review round.\n"},{"id":"145881","messageId":"7v630am2qt.fsf@alter.siamese.dyndns.org","threadId":"24433","inReplyTo":"7vaapmm3ow.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH/RFC v4 0/2] Add -e/--exclude to git clean.","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-07-20T18:23:22Z","receivedAt":"2010-07-20T18:23:22Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Aaron Crane <git@aaroncrane.co.uk> writes:\n>\n>> Jared Hance <jaredhance@gmail.com> wrote:\n>>> This is the fourth round of patches for git clean -e.\n>>> Since this patch seems to be somewhat controversial, I've marked it as\n>>> PATCH/RFC. I would like some ideas on what to use for separators\n>>\n>> Rather than stuffing multiple exclusions into a single option, how\n>> about requiring one -e option per exclusion?\n>>\n>> git clean -e foo -e bar\n>\n> I find it a lot saner.\n>\n> Sorry, Jared, I should have thought of it and suggested it during the\n> first review round.\n\nThe fix-up should look something like this, on top of your patch.\n\nNote that I did this on top of applying your patch to 'maint', and you may\nneed to adjust the parameter order of string-list functions if you want to\nforward port it to 'master'.\n\nUntested, of course ;-)\n\n\n Documentation/git-clean.txt |   11 ++++++-----\n builtin/clean.c             |   36 +++++++++++++++---------------------\n 2 files changed, 21 insertions(+), 26 deletions(-)\n\ndiff --git a/Documentation/git-clean.txt b/Documentation/git-clean.txt\nindex 488e103..60e38e6 100644\n--- a/Documentation/git-clean.txt\n+++ b/Documentation/git-clean.txt\n@@ -8,7 +8,7 @@ git-clean - Remove untracked files from the working tree\n SYNOPSIS\n --------\n [verse]\n-'git clean' [-d] [-f] [-n] [-q] [-e] [-x | -X] [--] <path>...\n+'git clean' [-d] [-f] [-n] [-q] [-e <pattern>] [-x | -X] [--] <path>...\n \n DESCRIPTION\n -----------\n@@ -45,10 +45,11 @@ OPTIONS\n \tBe quiet, only report errors, but not the files that are\n \tsuccessfully removed.\n \n--e <files>::\n---exclude=<files>::\n-\tSpecify special exceptions to not be cleaned. Separate with a space.\n-\tGlobs, like that in $GIT_DIR/info/excludes, should be used.\n+-e <pattern>::\n+--exclude=<pattern>::\n+\tSpecify special exceptions to not be cleaned.  Each <pattern> is\n+\tthe same form as in $GIT_DIR/info/excludes and this option can be\n+\tgiven multiple times.\n \n -x::\n \tDon't use the ignore rules.  This allows removing all untracked\ndiff --git a/builtin/clean.c b/builtin/clean.c\nindex b1da923..58c9c06 100644\n--- a/builtin/clean.c\n+++ b/builtin/clean.c\n@@ -10,13 +10,13 @@\n #include \"cache.h\"\n #include \"dir.h\"\n #include \"parse-options.h\"\n+#include \"string-list.h\"\n #include \"quote.h\"\n \n static int force = -1; /* unset */\n-static const char *excludes;\n \n static const char *const builtin_clean_usage[] = {\n-\t\"git clean [-d] [-f] [-n] [-q] [-x | -X] [--] <paths>...\",\n+\t\"git clean [-d] [-f] [-n] [-q] [-e <pattern>] [-x | -X] [--] <paths>...\",\n \tNULL\n };\n \n@@ -27,6 +27,13 @@ static int git_clean_config(const char *var, const char *value, void *cb)\n \treturn git_default_config(var, value, cb);\n }\n \n+static int exclude_cb(const struct option *opt, const char *arg, int unset)\n+{\n+\tstruct string_list *exclude_list = opt->value;\n+\tstring_list_append(arg, exclude_list);\n+\treturn 0;\n+}\n+\n int cmd_clean(int argc, const char **argv, const char *prefix)\n {\n \tint i;\n@@ -37,8 +44,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)\n \tstruct dir_struct dir;\n \tstatic const char **pathspec;\n \tstruct strbuf buf = STRBUF_INIT;\n-\tstruct strbuf excludes_buf = STRBUF_INIT;\n-\tstruct strbuf **excludes_split = NULL;\n+\tstruct string_list exclude_list = { NULL, 0, 0, 0 };\n \tconst char *qname;\n \tchar *seen = NULL;\n \tstruct option options[] = {\n@@ -47,7 +53,8 @@ int cmd_clean(int argc, const char **argv, const char *prefix)\n \t\tOPT_BOOLEAN('f', \"force\", &force, \"force\"),\n \t\tOPT_BOOLEAN('d', NULL, &remove_directories,\n \t\t\t\t\"remove whole directories\"),\n-\t\tOPT_STRING('e', \"exclude\", &excludes, \"EXCLUDES\", \"specify files not to clean\"),\n+\t\t{ OPTION_CALLBACK, 'e', \"exclude\", &exclude_list, \"pattern\",\n+\t\t  \"exclude <pattern>\", PARSE_OPT_NONEG, exclude_cb },\n \t\tOPT_BOOLEAN('x', NULL, &ignored, \"remove ignored files, too\"),\n \t\tOPT_BOOLEAN('X', NULL, &ignored_only,\n \t\t\t\t\"remove only ignored files\"),\n@@ -85,16 +92,8 @@ int cmd_clean(int argc, const char **argv, const char *prefix)\n \tif (!ignored)\n \t\tsetup_standard_excludes(&dir);\n \n-\tif (excludes) {\n-\t\tstrbuf_addstr(&excludes_buf, excludes);\n-\t\texcludes_split = strbuf_split(&excludes_buf, ' ');\n-\t\tfor (i = 0; excludes_split[i]; i++) {\n-\t\t\tif (excludes_split[i]->buf[excludes_split[i]->len - 1] == ' ') {\n-\t\t\t\tstrbuf_remove(excludes_split[i], excludes_split[i]->len - 1, 1);\n-\t\t\t}\n-\t\t\tadd_exclude(excludes_split[i]->buf, \"\", 0, dir.exclude_list);\n-\t\t}\n-\t}\n+\tfor (i = 0; i < exclude_list.nr; i++)\n+\t\tadd_exclude(exclude_list.items[i].string, \"\", 0, dir.exclude_list);\n \n \tpathspec = get_pathspec(prefix, argv);\n \n@@ -182,11 +181,6 @@ int cmd_clean(int argc, const char **argv, const char *prefix)\n \tfree(seen);\n \n \tstrbuf_release(&directory);\n-\tif (excludes) {\n-\t\tstrbuf_release(&excludes_buf);\n-\t\tfor (i = 0; excludes_split[i]; i++) {\n-\t\t\tstrbuf_release(excludes_split[i]);\n-\t\t}\n-\t}\n+\tstring_list_clear(&exclude_list, 0);\n \treturn (errors != 0);\n }\n"},{"id":"145890","messageId":"20100720191131.GA2688@localhost.localdomain","threadId":"24433","inReplyTo":"7v630am2qt.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH/RFC v4 0/2] Add -e/--exclude to git clean.","fromName":"Jared Hance","fromEmail":"jaredhance@gmail.com","sentAt":"2010-07-20T19:11:31Z","receivedAt":"2010-07-20T19:11:31Z","isPatch":true,"sender":{"key":"jaredhance@gmail.com","avatar":"https://avatars.githubusercontent.com/u/170192?v=4"},"body":"On Tue, Jul 20, 2010 at 11:23:22AM -0700, Junio C Hamano wrote:\n> The fix-up should look something like this, on top of your patch.\n> \n> Note that I did this on top of applying your patch to 'maint', and you may\n> need to adjust the parameter order of string-list functions if you want to\n> forward port it to 'master'.\n> \n> Untested, of course ;-)\n\nOkay. Do you want to me to create a rebased version to combine this\nand my first patch?\n"},{"id":"151352","messageId":"loom.20100923T103502-148@post.gmane.org","threadId":"24433","inReplyTo":"20100720191131.GA2688@localhost.localdomain","subject":"Re: [PATCH/RFC v4 0/2] Add -e/--exclude to git clean.","fromName":"Louis Strous","fromEmail":"louis.strous@gmail.com","sentAt":"2010-09-23T09:05:05Z","receivedAt":"2010-09-23T09:05:05Z","isPatch":true,"sender":{"key":"louis.strous@gmail.com","avatar":null},"body":"The git clean -e option is more useful than just for stuff that you plan to\nbring under git control later.  It also allows to retain per-user configurations\nof external tools when using git clean to remove all build results and\nintermediate files.  This leads to the enhancement request described below.\n\nMost IDEs (integrated development environments) allow the user to configure\nvarious display and debugger options, and store those options in some\nconfiguration file.  Such user option files should not be under git control in a\nmulti-user environment, because then all users are forced to use the same\noptions.  Yet these user option files should not be deleted when the rest of the\nuntracked files are deleted (through git clean), otherwise the user options are\nlost.\n\ngit clean -x -d -f -e \"pattern\" removes all untracked files except those\nmatching the pattern.  However, it is cumbersome to specify these patterns every\ntime.  It would be more convenient if git clean would read such patterns from a\nfile similar to .gitignore (maybe .gitignoreclean?).  Then that file itself\ncould be put under git control and shared with the other developers.\n\nI request implementation of this feature.\n\nBest regards,\n\nLouis Strous\n"}]}