{"thread":{"id":"10649","subject":"[PATCH] Add more tests for git-clean","startedAt":"2007-11-04T19:02:19Z","lastAt":"2007-11-06T05:30:52Z","messageCount":15,"participants":["Shawn Bohrer","Pierre Habouzit","Johannes Schindelin","Junio C Hamano","Carlos Rica"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"58294","messageId":"1194202941253-git-send-email-shawn.bohrer@gmail.com","threadId":"10649","inReplyTo":null,"subject":"[RFC] Second attempt at making git-clean a builtin","fromName":"Shawn Bohrer","fromEmail":"shawn.bohrer@gmail.com","sentAt":"2007-11-04T19:02:19Z","receivedAt":"2007-11-04T19:02:19Z","isPatch":false,"sender":{"key":"shawn.bohrer@gmail.com","avatar":"https://gravatar.com/avatar/6eb093ef7d276306d18366254e0c95ff6a5db58231ac7e82fe78c2800aaae1b6?d=mp&s=160"},"body":"\nI've taken all of the comments I received from my previous attempt see:\n\nhttp://marc.info/?l=git&m=119181975419521&w=2\n\nWith these new changes in place my new git-clean passes all of the\noriginal tests as well as the new tests I've added.  While looking at\nhow git-ls-files walks the tree there were some things that didn't quite\nunderstand, or thought might be unnecessary so there may be some things I\nmissed.  For example I'm still not quite sure what verify_pathspec()\ndoes.\n\nI did however notice what I would call a bug in the behavior of\ngit-ls-files and therefore the current git-clean.sh.  With the current\ngit-clean if you have two directories that contain only untracked files,\nfor example docs/ and examples/ running:\n\ngit clean docs/ examples/\n\nwill not remove either directory.  Instead you must use the -d\nparameter.  To me this makes sense, however if you run:\n\ngit clean docs/\n\nit will remove the docs directory without using the -d parameter.  My\npatch is at least consistent in that it requires the -d in both cases.\n"},{"id":"58292","messageId":"11942029442710-git-send-email-shawn.bohrer@gmail.com","threadId":"10649","inReplyTo":"1194202941253-git-send-email-shawn.bohrer@gmail.com","subject":"[PATCH] Add more tests for git-clean","fromName":"Shawn Bohrer","fromEmail":"shawn.bohrer@gmail.com","sentAt":"2007-11-04T19:02:20Z","receivedAt":"2007-11-04T19:02:20Z","isPatch":true,"sender":{"key":"shawn.bohrer@gmail.com","avatar":"https://gravatar.com/avatar/6eb093ef7d276306d18366254e0c95ff6a5db58231ac7e82fe78c2800aaae1b6?d=mp&s=160"},"body":"Signed-off-by: Shawn Bohrer <shawn.bohrer@gmail.com>\n---\n t/t7300-clean.sh |  109 ++++++++++++++++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 109 insertions(+), 0 deletions(-)\n\ndiff --git a/t/t7300-clean.sh b/t/t7300-clean.sh\nindex 8697213..d74c11c 100755\n--- a/t/t7300-clean.sh\n+++ b/t/t7300-clean.sh\n@@ -39,6 +39,97 @@ test_expect_success 'git-clean' '\n \n '\n \n+test_expect_success 'git-clean src/' '\n+\n+\tmkdir -p build docs &&\n+\ttouch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&\n+\tgit-clean src/ &&\n+\ttest -f Makefile &&\n+\ttest -f README &&\n+\ttest -f src/part1.c &&\n+\ttest -f src/part2.c &&\n+\ttest -f a.out &&\n+\ttest ! -f src/part3.c &&\n+\ttest -f docs/manual.txt &&\n+\ttest -f obj.o &&\n+\ttest -f build/lib.so\n+\n+'\n+\n+test_expect_success 'git-clean src/ src/' '\n+\n+\tmkdir -p build docs &&\n+\ttouch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&\n+\tgit-clean src/ src/ &&\n+\ttest -f Makefile &&\n+\ttest -f README &&\n+\ttest -f src/part1.c &&\n+\ttest -f src/part2.c &&\n+\ttest -f a.out &&\n+\ttest ! -f src/part3.c &&\n+\ttest -f docs/manual.txt &&\n+\ttest -f obj.o &&\n+\ttest -f build/lib.so\n+\n+'\n+\n+test_expect_success 'git-clean with prefix' '\n+\n+\tmkdir -p build docs &&\n+\ttouch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&\n+\tcd src/ &&\n+\tgit-clean &&\n+\tcd - &&\n+\ttest -f Makefile &&\n+\ttest -f README &&\n+\ttest -f src/part1.c &&\n+\ttest -f src/part2.c &&\n+\ttest -f a.out &&\n+\ttest ! -f src/part3.c &&\n+\ttest -f docs/manual.txt &&\n+\ttest -f obj.o &&\n+\ttest -f build/lib.so\n+\n+'\n+test_expect_success 'git-clean -d with prefix and path' '\n+\n+\tmkdir -p build docs src/feature &&\n+\ttouch a.out src/part3.c src/feature/file.c docs/manual.txt obj.o build/lib.so &&\n+\tcd src/ &&\n+\tgit-clean -d feature/ &&\n+\tcd - &&\n+\ttest -f Makefile &&\n+\ttest -f README &&\n+\ttest -f src/part1.c &&\n+\ttest -f src/part2.c &&\n+\ttest -f a.out &&\n+\ttest -f src/part3.c &&\n+\ttest ! -f src/feature/file.c &&\n+\ttest -f docs/manual.txt &&\n+\ttest -f obj.o &&\n+\ttest -f build/lib.so\n+\n+'\n+\n+test_expect_success 'git-clean symbolic link' '\n+\n+\tmkdir -p build docs &&\n+\ttouch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&\n+\tln -s docs/manual.txt src/part4.c\n+\tgit-clean &&\n+\ttest -f Makefile &&\n+\ttest -f README &&\n+\ttest -f src/part1.c &&\n+\ttest -f src/part2.c &&\n+\ttest ! -f a.out &&\n+\ttest ! -f src/part3.c &&\n+\ttest ! -f src/part4.c &&\n+\ttest -f docs/manual.txt &&\n+\ttest -f obj.o &&\n+\ttest -f build/lib.so\n+\n+'\n+\n test_expect_success 'git-clean -n' '\n \n \tmkdir -p build docs &&\n@@ -73,6 +164,24 @@ test_expect_success 'git-clean -d' '\n \n '\n \n+test_expect_success 'git-clean -d src/ examples/' '\n+\n+\tmkdir -p build docs examples &&\n+\ttouch a.out src/part3.c docs/manual.txt obj.o build/lib.so examples/1.c &&\n+\tgit-clean -d src/ examples/ &&\n+\ttest -f Makefile &&\n+\ttest -f README &&\n+\ttest -f src/part1.c &&\n+\ttest -f src/part2.c &&\n+\ttest -f a.out &&\n+\ttest ! -f src/part3.c &&\n+\ttest ! -f examples/1.c &&\n+\ttest -f docs/manual.txt &&\n+\ttest -f obj.o &&\n+\ttest -f build/lib.so\n+\n+'\n+\n test_expect_success 'git-clean -x' '\n \n \tmkdir -p build docs &&\n-- \n1.5.3.GIT\n"},{"id":"58293","messageId":"11942029474058-git-send-email-shawn.bohrer@gmail.com","threadId":"10649","inReplyTo":"11942029442710-git-send-email-shawn.bohrer@gmail.com","subject":"[PATCH] Make git-clean a builtin","fromName":"Shawn Bohrer","fromEmail":"shawn.bohrer@gmail.com","sentAt":"2007-11-04T19:02:21Z","receivedAt":"2007-11-04T19:02:21Z","isPatch":true,"sender":{"key":"shawn.bohrer@gmail.com","avatar":"https://gravatar.com/avatar/6eb093ef7d276306d18366254e0c95ff6a5db58231ac7e82fe78c2800aaae1b6?d=mp&s=160"},"body":"This replaces git-clean.sh with builtin-clean.c, and moves git-clean.sh to\nthe examples.\n\nSigned-off-by: Shawn Bohrer <shawn.bohrer@gmail.com>\n---\n Makefile                                      |    3 +-\n builtin-clean.c                               |  157 +++++++++++++++++++++++++\n builtin.h                                     |    1 +\n git-clean.sh => contrib/examples/git-clean.sh |    0 \n git.c                                         |    1 +\n 5 files changed, 161 insertions(+), 1 deletions(-)\n create mode 100644 builtin-clean.c\n rename git-clean.sh => contrib/examples/git-clean.sh (100%)\n\ndiff --git a/Makefile b/Makefile\nindex 3ec1876..fad49b2 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -209,7 +209,7 @@ BASIC_LDFLAGS =\n \n SCRIPT_SH = \\\n \tgit-bisect.sh git-checkout.sh \\\n-\tgit-clean.sh git-clone.sh git-commit.sh \\\n+\tgit-clone.sh git-commit.sh \\\n \tgit-ls-remote.sh \\\n \tgit-merge-one-file.sh git-mergetool.sh git-parse-remote.sh \\\n \tgit-pull.sh git-rebase.sh git-rebase--interactive.sh \\\n@@ -326,6 +326,7 @@ BUILTIN_OBJS = \\\n \tbuiltin-check-attr.o \\\n \tbuiltin-checkout-index.o \\\n \tbuiltin-check-ref-format.o \\\n+\tbuiltin-clean.o \\\n \tbuiltin-commit-tree.o \\\n \tbuiltin-count-objects.o \\\n \tbuiltin-describe.o \\\ndiff --git a/builtin-clean.c b/builtin-clean.c\nnew file mode 100644\nindex 0000000..4141eb4\n--- /dev/null\n+++ b/builtin-clean.c\n@@ -0,0 +1,157 @@\n+/*\n+ * \"git clean\" builtin command\n+ *\n+ * Copyright (C) 2007 Shawn Bohrer\n+ *\n+ * Based on git-clean.sh by Pavel Roskin\n+ */\n+\n+#include \"builtin.h\"\n+#include \"cache.h\"\n+#include \"dir.h\"\n+\n+static int disabled = 1;\n+static int show_only = 0;\n+static int remove_directories = 0;\n+static int quiet = 0;\n+static int ignored = 0;\n+static int ignored_only = 0;\n+\n+static const char builtin_clean_usage[] =\n+\"git-clean [-d] [-f] [-n] [-q] [-x | -X] [--] <paths>...\";\n+\n+static int git_clean_config(const char *var, const char *value)\n+{\n+\tif (!strcmp(var, \"clean.requireforce\")) {\n+\t\tdisabled = git_config_bool(var, value);\n+\t}\n+\treturn 0;\n+}\n+\n+int cmd_clean(int argc, const char **argv, const char *prefix)\n+{\n+\tint i, j;\n+\tstruct strbuf directory;\n+\tstruct dir_struct dir;\n+\tconst char *path = \".\";\n+\tconst char *base = \"\";\n+\tint baselen = 0;\n+\tstatic const char **pathspec;\n+\n+\tmemset(&dir, 0, sizeof(dir));\n+\tgit_config(git_clean_config);\n+\n+\tfor (i = 1; i < argc; i++) {\n+\t\tconst char *arg = argv[i];\n+\n+\t\tif (arg[0] != '-')\n+\t\t\tbreak;\n+\t\tif (!strcmp(arg, \"--\")) {\n+\t\t\ti++;\n+\t\t\tbreak;\n+\t\t}\n+\t\tif (!strcmp(arg, \"-n\")) {\n+\t\t\tshow_only = 1;\n+\t\t\tdisabled = 0;\n+\t\t\tcontinue;\n+\t\t}\n+\t\tif (!strcmp(arg, \"-f\")) {\n+\t\t\tdisabled = 0;\n+\t\t\tcontinue;\n+\t\t}\n+\t\tif (!strcmp(arg, \"-d\")) {\n+\t\t\tremove_directories = 1;\n+\t\t\tcontinue;\n+\t\t}\n+\t\tif (!strcmp(arg, \"-q\")) {\n+\t\t\tquiet = 1;\n+\t\t\tcontinue;\n+\t\t}\n+\t\tif (!strcmp(arg, \"-x\")) {\n+\t\t\tignored = 1;\n+\t\t\tcontinue;\n+\t\t}\n+\t\tif (!strcmp(arg, \"-X\")) {\n+\t\t\tignored_only = 1;\n+\t\t\tdir.show_ignored =1;\n+\t\t\tdir.exclude_per_dir = \".gitignore\";\n+\t\t\tcontinue;\n+\t\t}\n+\t\tusage(builtin_clean_usage);\n+\t}\n+\n+\tif (ignored && ignored_only)\n+\t\tdie(\"-x and -X cannot be used together\");\n+\n+\tif (disabled)\n+\t\tdie(\"clean.requireForce set and -n or -f not given; refusing to clean\");\n+\n+\tdir.show_other_directories = 1;\n+\n+\tif (!ignored) {\n+\t\tdir.exclude_per_dir = \".gitignore\";\n+\t\tif (!access(git_path(\"info/exclude\"), F_OK)) {\n+\t\t\tchar *exclude_path = git_path(\"info/exclude\");\n+\t\t\tadd_excludes_from_file(&dir, exclude_path);\n+\t\t}\n+\t}\n+\n+\tpathspec = get_pathspec(prefix, argv + i);\n+\tread_cache();\n+\tread_directory(&dir, path, base, baselen, pathspec);\n+\tstrbuf_init(&directory, 0);\n+\n+\tfor (j = 0; j < dir.nr; ++j) {\n+\t\tstruct dir_entry *ent = dir.entries[j];\n+\t\tint len, pos;\n+\t\tstruct cache_entry *ce;\n+\t\tstruct stat st;\n+\n+\t\t/*\n+\t\t * Remove the '/' at the end that directory\n+\t\t * walking adds for directory entries.\n+\t\t */\n+\t\tlen = ent->len;\n+\t\tif (len && ent->name[len-1] == '/')\n+\t\t\tlen--;\n+\t\tpos = cache_name_pos(ent->name, len);\n+\t\tif (0 <= pos)\n+\t\t\tcontinue;\t/* exact match */\n+\t\tpos = -pos - 1;\n+\t\tif (pos < active_nr) {\n+\t\t\tce = active_cache[pos];\n+\t\t\tif (ce_namelen(ce) == len &&\n+\t\t\t    !memcmp(ce->name, ent->name, len))\n+\t\t\t\tcontinue; /* Yup, this one exists unmerged */\n+\t\t}\n+\n+\t\t/* remove the files */\n+\t\tif (!lstat(ent->name, &st) && (S_ISDIR(st.st_mode))) {\n+\t\t\tstrbuf_addstr(&directory, ent->name);\n+\t\t\tif (show_only && remove_directories) {\n+\t\t\t\tprintf(\"Would remove %s\\n\", directory.buf);\n+\t\t\t} else if (quiet && remove_directories) {\n+\t\t\t\tremove_dir_recursively(&directory, 0);\n+\t\t\t} else if (remove_directories) {\n+\t\t\t\tprintf(\"Removing %s\\n\", ent->name);\n+\t\t\t\tremove_dir_recursively(&directory, 0);\n+\t\t\t} else if (show_only) {\n+\t\t\t\tprintf(\"Would not remove %s\\n\", directory.buf);\n+\t\t\t} else {\n+\t\t\t\tprintf(\"Not removing %s\\n\", directory.buf);\n+\t\t\t}\n+\t\t\tstrbuf_reset(&directory);\n+\t\t} else {\n+\t\t\tif (show_only) {\n+\t\t\t\tprintf(\"Would remove %s\\n\", ent->name);\n+\t\t\t\tcontinue;\n+\t\t\t} else if (!quiet) {\n+\t\t\t\tprintf(\"Removing %s\\n\", ent->name);\n+\t\t\t}\n+\t\t\tunlink(ent->name);\n+\t\t}\n+\t}\n+\n+\tstrbuf_release(&directory);\n+\treturn 0;\n+}\ndiff --git a/builtin.h b/builtin.h\nindex 2335c01..0cbd685 100644\n--- a/builtin.h\n+++ b/builtin.h\n@@ -24,6 +24,7 @@ extern int cmd_check_attr(int argc, const char **argv, const char *prefix);\n extern int cmd_check_ref_format(int argc, const char **argv, const char *prefix);\n extern int cmd_cherry(int argc, const char **argv, const char *prefix);\n extern int cmd_cherry_pick(int argc, const char **argv, const char *prefix);\n+extern int cmd_clean(int argc, const char **argv, const char *prefix);\n extern int cmd_commit_tree(int argc, const char **argv, const char *prefix);\n extern int cmd_count_objects(int argc, const char **argv, const char *prefix);\n extern int cmd_describe(int argc, const char **argv, const char *prefix);\ndiff --git a/git-clean.sh b/contrib/examples/git-clean.sh\nsimilarity index 100%\nrename from git-clean.sh\nrename to contrib/examples/git-clean.sh\ndiff --git a/git.c b/git.c\nindex 19a2172..30b7c22 100644\n--- a/git.c\n+++ b/git.c\n@@ -298,6 +298,7 @@ static void handle_internal_command(int argc, const char **argv)\n \t\t{ \"check-attr\", cmd_check_attr, RUN_SETUP | NEED_WORK_TREE },\n \t\t{ \"cherry\", cmd_cherry, RUN_SETUP },\n \t\t{ \"cherry-pick\", cmd_cherry_pick, RUN_SETUP | NEED_WORK_TREE },\n+\t\t{ \"clean\", cmd_clean, RUN_SETUP | NEED_WORK_TREE },\n \t\t{ \"commit-tree\", cmd_commit_tree, RUN_SETUP },\n \t\t{ \"config\", cmd_config },\n \t\t{ \"count-objects\", cmd_count_objects, RUN_SETUP },\n-- \n1.5.3.GIT\n"},{"id":"58299","messageId":"20071104194129.GA4207@artemis.corp","threadId":"10649","inReplyTo":"11942029474058-git-send-email-shawn.bohrer@gmail.com","subject":"Re: [PATCH] Make git-clean a builtin","fromName":"Pierre Habouzit","fromEmail":"madcoder@debian.org","sentAt":"2007-11-04T19:41:29Z","receivedAt":"2007-11-04T19:41:29Z","isPatch":true,"sender":{"key":"madcoder@debian.org","avatar":"https://avatars.githubusercontent.com/u/44708?v=4"},"body":"On Sun, Nov 04, 2007 at 07:02:21PM +0000, Shawn Bohrer wrote:\n\n> +\tfor (i = 1; i < argc; i++) {\n> +\t\tconst char *arg = argv[i];\n> +\n> +\t\tif (arg[0] != '-')\n> +\t\t\tbreak;\n> +\t\tif (!strcmp(arg, \"--\")) {\n> +\t\t\ti++;\n> +\t\t\tbreak;\n> +\t\t}\n> +\t\tif (!strcmp(arg, \"-n\")) {\n> +\t\t\tshow_only = 1;\n> +\t\t\tdisabled = 0;\n> +\t\t\tcontinue;\n> +\t\t}\n> +\t\tif (!strcmp(arg, \"-f\")) {\n> +\t\t\tdisabled = 0;\n> +\t\t\tcontinue;\n> +\t\t}\n> +\t\tif (!strcmp(arg, \"-d\")) {\n> +\t\t\tremove_directories = 1;\n> +\t\t\tcontinue;\n> +\t\t}\n> +\t\tif (!strcmp(arg, \"-q\")) {\n> +\t\t\tquiet = 1;\n> +\t\t\tcontinue;\n> +\t\t}\n> +\t\tif (!strcmp(arg, \"-x\")) {\n> +\t\t\tignored = 1;\n> +\t\t\tcontinue;\n> +\t\t}\n> +\t\tif (!strcmp(arg, \"-X\")) {\n> +\t\t\tignored_only = 1;\n> +\t\t\tdir.show_ignored =1;\n> +\t\t\tdir.exclude_per_dir = \".gitignore\";\n> +\t\t\tcontinue;\n> +\t\t}\n> +\t\tusage(builtin_clean_usage);\n\n  Please, parse-options.c is now in next, please use it.\n\n-- \n·O·  Pierre Habouzit\n··O                                                madcoder@debian.org\nOOO                                                http://www.madism.org\n"},{"id":"58302","messageId":"Pine.LNX.4.64.0711042023440.4362@racer.site","threadId":"10649","inReplyTo":"20071104194129.GA4207@artemis.corp","subject":"[PATCH 3/2] Use parse-options in builtin-clean","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-11-04T20:24:31Z","receivedAt":"2007-11-04T20:24:31Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n\n\tOn Sun, 4 Nov 2007, Pierre Habouzit wrote:\n\n\t> On Sun, Nov 04, 2007 at 07:02:21PM +0000, Shawn Bohrer wrote:\n\t> \n\t> > +\tfor (i = 1; i < argc; i++) {\n\t> > +\t\tconst char *arg = argv[i];\n\t> > [...]\n\t> \n\t>   Please, parse-options.c is now in next, please use it.\n\n\tSomething like this?\n\n builtin-clean.c |   71 ++++++++++++++++++++----------------------------------\n 1 files changed, 26 insertions(+), 45 deletions(-)\n\ndiff --git a/builtin-clean.c b/builtin-clean.c\nindex 4141eb4..d6fc2ad 100644\n--- a/builtin-clean.c\n+++ b/builtin-clean.c\n@@ -9,81 +9,62 @@\n #include \"builtin.h\"\n #include \"cache.h\"\n #include \"dir.h\"\n+#include \"parse-options.h\"\n \n-static int disabled = 1;\n+static int force = 0;\n static int show_only = 0;\n static int remove_directories = 0;\n static int quiet = 0;\n static int ignored = 0;\n static int ignored_only = 0;\n \n-static const char builtin_clean_usage[] =\n-\"git-clean [-d] [-f] [-n] [-q] [-x | -X] [--] <paths>...\";\n+static const char *const builtin_clean_usage[] = {\n+\t\"git-clean [-d] [-f] [-n] [-q] [-x | -X] [--] <paths>...\",\n+\tNULL\n+};\n \n static int git_clean_config(const char *var, const char *value)\n {\n \tif (!strcmp(var, \"clean.requireforce\")) {\n-\t\tdisabled = git_config_bool(var, value);\n+\t\tforce = !git_config_bool(var, value);\n \t}\n \treturn 0;\n }\n \n int cmd_clean(int argc, const char **argv, const char *prefix)\n {\n-\tint i, j;\n+\tint j;\n \tstruct strbuf directory;\n \tstruct dir_struct dir;\n \tconst char *path = \".\";\n \tconst char *base = \"\";\n \tint baselen = 0;\n \tstatic const char **pathspec;\n+\tstruct option options[] = {\n+\t\tOPT__QUIET(&quiet),\n+\t\tOPT__DRY_RUN(&show_only),\n+\t\tOPT_BOOLEAN('f', NULL, &force, \"force\"),\n+\t\tOPT_BOOLEAN('d', NULL, &remove_directories,\n+\t\t\t\t\"remove whole directories\"),\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+\t\tOPT_END()\n+\t};\n \n-\tmemset(&dir, 0, sizeof(dir));\n \tgit_config(git_clean_config);\n+\targc = parse_options(argc, argv, options, builtin_clean_usage, 0);\n \n-\tfor (i = 1; i < argc; i++) {\n-\t\tconst char *arg = argv[i];\n-\n-\t\tif (arg[0] != '-')\n-\t\t\tbreak;\n-\t\tif (!strcmp(arg, \"--\")) {\n-\t\t\ti++;\n-\t\t\tbreak;\n-\t\t}\n-\t\tif (!strcmp(arg, \"-n\")) {\n-\t\t\tshow_only = 1;\n-\t\t\tdisabled = 0;\n-\t\t\tcontinue;\n-\t\t}\n-\t\tif (!strcmp(arg, \"-f\")) {\n-\t\t\tdisabled = 0;\n-\t\t\tcontinue;\n-\t\t}\n-\t\tif (!strcmp(arg, \"-d\")) {\n-\t\t\tremove_directories = 1;\n-\t\t\tcontinue;\n-\t\t}\n-\t\tif (!strcmp(arg, \"-q\")) {\n-\t\t\tquiet = 1;\n-\t\t\tcontinue;\n-\t\t}\n-\t\tif (!strcmp(arg, \"-x\")) {\n-\t\t\tignored = 1;\n-\t\t\tcontinue;\n-\t\t}\n-\t\tif (!strcmp(arg, \"-X\")) {\n-\t\t\tignored_only = 1;\n-\t\t\tdir.show_ignored =1;\n-\t\t\tdir.exclude_per_dir = \".gitignore\";\n-\t\t\tcontinue;\n-\t\t}\n-\t\tusage(builtin_clean_usage);\n+\tmemset(&dir, 0, sizeof(dir));\n+\tif (ignored_only) {\n+\t\tdir.show_ignored =1;\n+\t\tdir.exclude_per_dir = \".gitignore\";\n \t}\n \n \tif (ignored && ignored_only)\n \t\tdie(\"-x and -X cannot be used together\");\n \n-\tif (disabled)\n+\tif (!show_only && !force)\n \t\tdie(\"clean.requireForce set and -n or -f not given; refusing to clean\");\n \n \tdir.show_other_directories = 1;\n@@ -96,7 +77,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)\n \t\t}\n \t}\n \n-\tpathspec = get_pathspec(prefix, argv + i);\n+\tpathspec = get_pathspec(prefix, argv);\n \tread_cache();\n \tread_directory(&dir, path, base, baselen, pathspec);\n \tstrbuf_init(&directory, 0);\n-- \n1.5.3.5.1549.g91a3\n"},{"id":"58306","messageId":"20071104211637.GB4207@artemis.corp","threadId":"10649","inReplyTo":"Pine.LNX.4.64.0711042023440.4362@racer.site","subject":"Re: [PATCH 3/2] Use parse-options in builtin-clean","fromName":"Pierre Habouzit","fromEmail":"madcoder@debian.org","sentAt":"2007-11-04T21:16:37Z","receivedAt":"2007-11-04T21:16:37Z","isPatch":true,"sender":{"key":"madcoder@debian.org","avatar":"https://avatars.githubusercontent.com/u/44708?v=4"},"body":"On Sun, Nov 04, 2007 at 08:24:31PM +0000, Johannes Schindelin wrote:\n> \n> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> ---\n> \n> \tOn Sun, 4 Nov 2007, Pierre Habouzit wrote:\n> \n> \t> On Sun, Nov 04, 2007 at 07:02:21PM +0000, Shawn Bohrer wrote:\n> \t> \n> \t> > +\tfor (i = 1; i < argc; i++) {\n> \t> > +\t\tconst char *arg = argv[i];\n> \t> > [...]\n> \t> \n> \t>   Please, parse-options.c is now in next, please use it.\n> \n> \tSomething like this?\n\n  something like this works for me :)\n\n-- \n·O·  Pierre Habouzit\n··O                                                madcoder@debian.org\nOOO                                                http://www.madism.org\n"},{"id":"58322","messageId":"7vve8hr3ch.fsf@gitster.siamese.dyndns.org","threadId":"10649","inReplyTo":"11942029442710-git-send-email-shawn.bohrer@gmail.com","subject":"Re: [PATCH] Add more tests for git-clean","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-11-04T23:35:42Z","receivedAt":"2007-11-04T23:35:42Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Shawn Bohrer <shawn.bohrer@gmail.com> writes:\n\n> +test_expect_success 'git-clean with prefix' '\n> +\n> +\tmkdir -p build docs &&\n> +\ttouch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&\n> +\tcd src/ &&\n> +\tgit-clean &&\n> +\tcd - &&\n\nThis is wrong for two reasons.\n\n - Is \"cd -\" portable?\n\n - What happens when git-clean fails?  This test fails, and then\n   it goes on to the next test without cd'ing back.\n"},{"id":"58323","messageId":"20071104234617.GG4207@artemis.corp","threadId":"10649","inReplyTo":"7vve8hr3ch.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH] Add more tests for git-clean","fromName":"Pierre Habouzit","fromEmail":"madcoder@debian.org","sentAt":"2007-11-04T23:46:17Z","receivedAt":"2007-11-04T23:46:17Z","isPatch":true,"sender":{"key":"madcoder@debian.org","avatar":"https://avatars.githubusercontent.com/u/44708?v=4"},"body":"On Sun, Nov 04, 2007 at 11:35:42PM +0000, Junio C Hamano wrote:\n> Shawn Bohrer <shawn.bohrer@gmail.com> writes:\n> \n> > +test_expect_success 'git-clean with prefix' '\n> > +\n> > +\tmkdir -p build docs &&\n> > +\ttouch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&\n> > +\tcd src/ &&\n> > +\tgit-clean &&\n> > +\tcd - &&\n> \n> This is wrong for two reasons.\n> \n>  - Is \"cd -\" portable?\n\n  this is POSIX:\n\n8910 − When a hyphen is used as the operand, this shall be equivalent to the command:\n8911   cd \"$OLDPWD\" && pwd\n8912   which changes to the previous working directory and then writes its name.\n\n  Meaning that cd $OLDPWD should work, and won't print $OLDPWD.\n\n-- \n·O·  Pierre Habouzit\n··O                                                madcoder@debian.org\nOOO                                                http://www.madism.org\n"},{"id":"58325","messageId":"Pine.LNX.4.64.0711042348540.4362@racer.site","threadId":"10649","inReplyTo":"7vve8hr3ch.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH] Add more tests for git-clean","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-11-04T23:49:50Z","receivedAt":"2007-11-04T23:49:50Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Sun, 4 Nov 2007, Junio C Hamano wrote:\n\n> Shawn Bohrer <shawn.bohrer@gmail.com> writes:\n> \n> > +test_expect_success 'git-clean with prefix' '\n> > +\n> > +\tmkdir -p build docs &&\n> > +\ttouch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&\n> > +\tcd src/ &&\n> > +\tgit-clean &&\n> > +\tcd - &&\n> \n> This is wrong for two reasons.\n> \n>  - Is \"cd -\" portable?\n> \n>  - What happens when git-clean fails?  This test fails, and then\n>    it goes on to the next test without cd'ing back.\n\nSo it should be\n\n\t(cd src/ && git clean) &&\n\nright?  (Note that I also removed the dash, since it will be a builtin \nafter the next commit.)\n\nCiao,\nDscho\n"},{"id":"58326","messageId":"7vr6j5r1ec.fsf@gitster.siamese.dyndns.org","threadId":"10649","inReplyTo":"20071104234617.GG4207@artemis.corp","subject":"Re: [PATCH] Add more tests for git-clean","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-11-05T00:17:47Z","receivedAt":"2007-11-05T00:17:47Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Pierre Habouzit <madcoder@debian.org> writes:\n\n> On Sun, Nov 04, 2007 at 11:35:42PM +0000, Junio C Hamano wrote:\n>> Shawn Bohrer <shawn.bohrer@gmail.com> writes:\n>> \n>> > +test_expect_success 'git-clean with prefix' '\n>> > +\n>> > +\tmkdir -p build docs &&\n>> > +\ttouch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&\n>> > +\tcd src/ &&\n>> > +\tgit-clean &&\n>> > +\tcd - &&\n>> \n>> This is wrong for two reasons.\n>> \n>>  - Is \"cd -\" portable?\n>\n>   this is POSIX:\n\nThat actually doesn't matter.  What the real world shells do\nmatters more.\n\nIn addition, \"cd -\" is a nice shorthand for interactive use but\nit is a bad discipline to use it in a script anyway.\n\n\t...\n\t( cd src && git-clean ) &&\n\t...\n\nwould be the best way to write this.\n"},{"id":"58415","messageId":"7vejf4pf7r.fsf@gitster.siamese.dyndns.org","threadId":"10649","inReplyTo":"11942029474058-git-send-email-shawn.bohrer@gmail.com","subject":"Re: [PATCH] Make git-clean a builtin","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-11-05T21:14:32Z","receivedAt":"2007-11-05T21:14:32Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Shawn Bohrer <shawn.bohrer@gmail.com> writes:\n\n> This replaces git-clean.sh with builtin-clean.c, and moves git-clean.sh to\n> the examples.\n>\n> Signed-off-by: Shawn Bohrer <shawn.bohrer@gmail.com>\n> ---\n> diff --git a/builtin-clean.c b/builtin-clean.c\n> new file mode 100644\n> index 0000000..4141eb4\n> --- /dev/null\n> +++ b/builtin-clean.c\n> @@ -0,0 +1,157 @@\n> +/*\n> + * \"git clean\" builtin command\n> + *\n> + * Copyright (C) 2007 Shawn Bohrer\n> + *\n> + * Based on git-clean.sh by Pavel Roskin\n> + */\n> +\n> +#include \"builtin.h\"\n> +#include \"cache.h\"\n> +#include \"dir.h\"\n> +\n> +static int disabled = 1;\n\nThis means we are committed to make clean.requireForce default\nto true, which is fine by me.  I need to warn the users about\nthis early.\n\n> +static int show_only = 0;\n> +static int remove_directories = 0;\n> +static int quiet = 0;\n> +static int ignored = 0;\n> +static int ignored_only = 0;\n\nPlease do not explicitly initialize static variables to zero.\n"},{"id":"58433","messageId":"1b46aba20711051410h370072e7he9cbebb54a789dac@mail.gmail.com","threadId":"10649","inReplyTo":"7vejf4pf7r.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH] Make git-clean a builtin","fromName":"Carlos Rica","fromEmail":"jasampler@gmail.com","sentAt":"2007-11-05T22:10:13Z","receivedAt":"2007-11-05T22:10:13Z","isPatch":true,"sender":{"key":"jasampler@gmail.com","avatar":null},"body":"2007/11/5, Junio C Hamano <gitster@pobox.com>:\n> Shawn Bohrer <shawn.bohrer@gmail.com> writes:\n>\n> > +static int show_only = 0;\n> > +static int remove_directories = 0;\n> > +static int quiet = 0;\n> > +static int ignored = 0;\n> > +static int ignored_only = 0;\n>\n> Please do not explicitly initialize static variables to zero.\n\nIs it really needed to declare those variables outside of a function\nin this case? This scheme makes difficult reusing the code from other\nbuiltins, rewriting it for libification, calling it many times, or\neven understand if they were declared that way with a purpose or not.\nI just don't know why they are that way in this case, is there a\nreason for it?\n"},{"id":"58459","messageId":"7v4pg0meol.fsf@gitster.siamese.dyndns.org","threadId":"10649","inReplyTo":"1b46aba20711051410h370072e7he9cbebb54a789dac@mail.gmail.com","subject":"Re: [PATCH] Make git-clean a builtin","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-11-05T23:54:18Z","receivedAt":"2007-11-05T23:54:18Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Carlos Rica\" <jasampler@gmail.com> writes:\n\n> 2007/11/5, Junio C Hamano <gitster@pobox.com>:\n>> Shawn Bohrer <shawn.bohrer@gmail.com> writes:\n>>\n>> > +static int show_only = 0;\n>> > +static int remove_directories = 0;\n>> > +static int quiet = 0;\n>> > +static int ignored = 0;\n>> > +static int ignored_only = 0;\n>>\n>> Please do not explicitly initialize static variables to zero.\n>\n> Is it really needed to declare those variables outside of a function\n> in this case?\n\nI do not think so --- I suspect that this is a simple cut &\npaste from the standalone ls-files implementation.\n"},{"id":"58490","messageId":"20071106050512.GA6768@mediacenter.austin.rr.com","threadId":"10649","inReplyTo":"7vejf4pf7r.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH] Make git-clean a builtin","fromName":"Shawn Bohrer","fromEmail":"shawn.bohrer@gmail.com","sentAt":"2007-11-06T05:05:12Z","receivedAt":"2007-11-06T05:05:12Z","isPatch":true,"sender":{"key":"shawn.bohrer@gmail.com","avatar":"https://gravatar.com/avatar/6eb093ef7d276306d18366254e0c95ff6a5db58231ac7e82fe78c2800aaae1b6?d=mp&s=160"},"body":"On Mon, Nov 05, 2007 at 01:14:32PM -0800, Junio C Hamano wrote:\n> Shawn Bohrer <shawn.bohrer@gmail.com> writes:\n> [...]\n> > +static int disabled = 1;\n> \n> This means we are committed to make clean.requireForce default\n> to true, which is fine by me.  I need to warn the users about\n> this early.\n\nActually I don't care either way, but in my last rebase on next this\nchange was already made to git-clean.sh so I adjusted accordingly.\n\n> > +static int show_only = 0;\n> > +static int remove_directories = 0;\n> > +static int quiet = 0;\n> > +static int ignored = 0;\n> > +static int ignored_only = 0;\n> \n> Please do not explicitly initialize static variables to zero.\n\nI realize that static variables will be automatically initialized to\nzero so this is unnecessary, but is there some technical reason not to\ninitialize explicitly?  If the answer is simply a style preference that\nis fine, I'm just here to learn.\n\nOf course as already pointed out these don't actually need to be static\nin the first place so I'll simply move them into cmd_clean().  This does\nlead me to another question though.  Now that Dscho has converted my\npatch to use parse-options, what is the best way to update my patch\nwhile still giving credit to Dscho?\n"},{"id":"58492","messageId":"7vbqa8j5yr.fsf@gitster.siamese.dyndns.org","threadId":"10649","inReplyTo":"20071106050512.GA6768@mediacenter.austin.rr.com","subject":"Re: [PATCH] Make git-clean a builtin","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-11-06T05:30:52Z","receivedAt":"2007-11-06T05:30:52Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Shawn Bohrer <shawn.bohrer@gmail.com> writes:\n\n> On Mon, Nov 05, 2007 at 01:14:32PM -0800, Junio C Hamano wrote:\n>> Shawn Bohrer <shawn.bohrer@gmail.com> writes:\n>> [...]\n>> > +static int disabled = 1;\n>> \n>> This means we are committed to make clean.requireForce default\n>> to true, which is fine by me.  I need to warn the users about\n>> this early.\n>\n> Actually I don't care either way, but in my last rebase on next this\n> change was already made to git-clean.sh so I adjusted accordingly.\n\nOh, that was not a question to you, but a note to me.\n\n>> > +static int show_only = 0;\n>> > +static int remove_directories = 0;\n>> > +static int quiet = 0;\n>> > +static int ignored = 0;\n>> > +static int ignored_only = 0;\n>> \n>> Please do not explicitly initialize static variables to zero.\n>\n> I realize that static variables will be automatically initialized to\n> zero so this is unnecessary, but is there some technical reason not to\n> initialize explicitly?  If the answer is simply a style preference that\n> is fine, I'm just here to learn.\n\nBoth readability and style have to do much with this.\n\nThe style has a historical background which is a slight\ntechnical merit.  It results in a smaller executable file, as C\ncompilers traditionally placed file-scope static variables that\nare not explicitly initialized in the BSS section, instead of\nexplicitly storing N-bytes of zero as the the initial data in it\n(although I do not see a reason for compilers not to do the same\nfor variables explicitly initialized to zero.  In fact, I think\nmodern gcc produces the same allocation with or without \"= 0\"\ninitialization).\n\n> Of course as already pointed out these don't actually need to be static\n> in the first place so I'll simply move them into cmd_clean().  This does\n> lead me to another question though.  Now that Dscho has converted my\n> patch to use parse-options, what is the best way to update my patch\n> while still giving credit to Dscho?\n\nPlease send a rewritten replacement version as a single patch\nthat is cleanly applicable to 'next', and mention people whose\ninput helped you in polishing the patch in the proposed commit\nlog message.\n"}]}