{"thread":{"id":"30249","subject":"[PATCH v2] clean: add --null option","startedAt":"2012-04-15T09:09:22Z","lastAt":"2012-04-18T16:59:14Z","messageCount":3,"participants":["Ross Lagerwall","Junio C Hamano"],"isPatch":true,"patchVersion":2,"patchTotal":null},"messages":[{"id":"189319","messageId":"1334480962-18778-1-git-send-email-rosslagerwall@gmail.com","threadId":"30249","inReplyTo":null,"subject":"[PATCH v2] clean: add --null option","fromName":"Ross Lagerwall","fromEmail":"rosslagerwall@gmail.com","sentAt":"2012-04-15T09:09:22Z","receivedAt":"2012-04-15T09:09:22Z","isPatch":true,"sender":{"key":"rosslagerwall@gmail.com","avatar":"https://avatars.githubusercontent.com/u/878055?v=4"},"body":"Add a --null (-z) option to git-clean which prints out the files\nand directories separated with a NUL character rather than '\\n'.\nThis makes it useful in conjunction with xargs -0.\n\nSigned-off-by: Ross Lagerwall <rosslagerwall@gmail.com>\n---\nThis updated patch converts use_nul to a static variable and reformats\nsome lines.\n\n Documentation/git-clean.txt |    7 ++++++-\n builtin/clean.c             |   28 +++++++++++++++++++++-------\n 2 files changed, 27 insertions(+), 8 deletions(-)\n\ndiff --git a/Documentation/git-clean.txt b/Documentation/git-clean.txt\nindex 79fb984..0150484 100644\n--- a/Documentation/git-clean.txt\n+++ b/Documentation/git-clean.txt\n@@ -8,7 +8,8 @@ git-clean - Remove untracked files from the working tree\n SYNOPSIS\n --------\n [verse]\n-'git clean' [-d] [-f] [-n] [-q] [-e <pattern>] [-x | -X] [--] <path>...\n+'git clean' [-d] [-f] [-n] [-z] [-q] [-e <pattern>] [-x | -X]\n+\t    [--] <path>...\n \n DESCRIPTION\n -----------\n@@ -40,6 +41,10 @@ OPTIONS\n --dry-run::\n \tDon't actually remove anything, just show what would be done.\n \n+-z::\n+--null::\n+\tSeparate paths with the NUL character.\n+\n -q::\n --quiet::\n \tBe quiet, only report errors, but not the files that are\ndiff --git a/builtin/clean.c b/builtin/clean.c\nindex 0c7b3d0..9ce01d1 100644\n--- a/builtin/clean.c\n+++ b/builtin/clean.c\n@@ -14,9 +14,10 @@\n #include \"quote.h\"\n \n static int force = -1; /* unset */\n+static int use_nul;\n \n static const char *const builtin_clean_usage[] = {\n-\t\"git clean [-d] [-f] [-n] [-q] [-e <pattern>] [-x | -X] [--] <paths>...\",\n+\t\"git clean [-d] [-f] [-n] [-z] [-q] [-e <pattern>] [-x | -X] [--] <paths>...\",\n \tNULL\n };\n \n@@ -34,6 +35,15 @@ static int exclude_cb(const struct option *opt, const char *arg, int unset)\n \treturn 0;\n }\n \n+static void print_path(const char *msg, const char *name)\n+{\n+\tif (use_nul) {\n+\t\tfputs(name, stdout);\n+\t\tputchar('\\0');\n+\t} else\n+\t\tprintf(msg, name);\n+}\n+\n int cmd_clean(int argc, const char **argv, const char *prefix)\n {\n \tint i;\n@@ -50,6 +60,8 @@ int cmd_clean(int argc, const char **argv, const char *prefix)\n \tstruct option options[] = {\n \t\tOPT__QUIET(&quiet, \"do not print names of files removed\"),\n \t\tOPT__DRY_RUN(&show_only, \"dry run\"),\n+\t\tOPT_BOOLEAN('z', \"null\", &use_nul,\n+\t\t\t    \"paths are separated with NUL character\"),\n \t\tOPT__FORCE(&force, \"force\"),\n \t\tOPT_BOOLEAN('d', NULL, &remove_directories,\n \t\t\t\t\"remove whole directories\"),\n@@ -152,20 +164,22 @@ int cmd_clean(int argc, const char **argv, const char *prefix)\n \t\t\tqname = quote_path_relative(directory.buf, directory.len, &buf, prefix);\n \t\t\tif (show_only && (remove_directories ||\n \t\t\t    (matches == MATCHED_EXACTLY))) {\n-\t\t\t\tprintf(_(\"Would remove %s\\n\"), qname);\n+\t\t\t\tprint_path(_(\"Would remove %s\\n\"), qname);\n \t\t\t} else if (remove_directories ||\n \t\t\t\t   (matches == MATCHED_EXACTLY)) {\n \t\t\t\tif (!quiet)\n-\t\t\t\t\tprintf(_(\"Removing %s\\n\"), qname);\n+\t\t\t\t\tprint_path(_(\"Removing %s\\n\"), qname);\n \t\t\t\tif (remove_dir_recursively(&directory,\n \t\t\t\t\t\t\t   rm_flags) != 0) {\n \t\t\t\t\twarning(_(\"failed to remove %s\"), qname);\n \t\t\t\t\terrors++;\n \t\t\t\t}\n \t\t\t} else if (show_only) {\n-\t\t\t\tprintf(_(\"Would not remove %s\\n\"), qname);\n+\t\t\t\tif (!use_nul)\n+\t\t\t\t\tprintf(_(\"Would not remove %s\\n\"), qname);\n \t\t\t} else {\n-\t\t\t\tprintf(_(\"Not removing %s\\n\"), qname);\n+\t\t\t\tif (!use_nul)\n+\t\t\t\t\tprintf(_(\"Not removing %s\\n\"), qname);\n \t\t\t}\n \t\t\tstrbuf_reset(&directory);\n \t\t} else {\n@@ -173,10 +187,10 @@ int cmd_clean(int argc, const char **argv, const char *prefix)\n \t\t\t\tcontinue;\n \t\t\tqname = quote_path_relative(ent->name, -1, &buf, prefix);\n \t\t\tif (show_only) {\n-\t\t\t\tprintf(_(\"Would remove %s\\n\"), qname);\n+\t\t\t\tprint_path(_(\"Would remove %s\\n\"), qname);\n \t\t\t\tcontinue;\n \t\t\t} else if (!quiet) {\n-\t\t\t\tprintf(_(\"Removing %s\\n\"), qname);\n+\t\t\t\tprint_path(_(\"Removing %s\\n\"), qname);\n \t\t\t}\n \t\t\tif (unlink(ent->name) != 0) {\n \t\t\t\twarning(_(\"failed to remove %s\"), qname);\n-- \n1.7.10\n"},{"id":"189455","messageId":"7vehrntowg.fsf@alter.siamese.dyndns.org","threadId":"30249","inReplyTo":"1334480962-18778-1-git-send-email-rosslagerwall@gmail.com","subject":"Re: [PATCH v2] clean: add --null option","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-04-16T20:14:39Z","receivedAt":"2012-04-16T20:14:39Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ross Lagerwall <rosslagerwall@gmail.com> writes:\n\n> Add a --null (-z) option to git-clean which prints out the files\n> and directories separated with a NUL character rather than '\\n'.\n> This makes it useful in conjunction with xargs -0.\n\nHrm, I do not like this at all.\n\nThe parameters to print_path() are all _(\"l10n-ready string\"). Isn't it a\nclue already that they are not meant for machine consumption?  Why are we\nmoving to cast the output from an end-user facing Porcelain command in\nstone?\n\nI suspect that older days \"git clean\" was a scripted Porcelain around a\nplumbing (perhaps ls-files?---I didn't bother digging its history as I do\nnot care too deeply about \"git clean\" which I do not use myself).  If we\nhave piled so many features into \"git clean\" after the rewrite-to-C to\nmake it impossible to express what \"git clean\" _would_ do in terms of\n\"ls-files\", perhaps that is what needs to be fixed, so that we can express\n\"git clean --some-set-of-options\" as:\n\n    git ls-files -z --set-of-options-equivalent-to-what-is-given-to-clean |\n    xargs -0 rm -fr\n"},{"id":"189635","messageId":"4F8EF2E2.2080807@gmail.com","threadId":"30249","inReplyTo":"7vehrntowg.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH v2] clean: add --null option","fromName":"Ross Lagerwall","fromEmail":"rosslagerwall@gmail.com","sentAt":"2012-04-18T16:59:14Z","receivedAt":"2012-04-18T16:59:14Z","isPatch":true,"sender":{"key":"rosslagerwall@gmail.com","avatar":"https://avatars.githubusercontent.com/u/878055?v=4"},"body":"On 04/16/2012 10:14 PM, Junio C Hamano wrote:\n> I suspect that older days \"git clean\" was a scripted Porcelain around a\n> plumbing (perhaps ls-files?---I didn't bother digging its history as I do\n> not care too deeply about \"git clean\" which I do not use myself).\n\nDo you just use ls-files directly?\n\n>  If we\n> have piled so many features into \"git clean\" after the rewrite-to-C to\n> make it impossible to express what \"git clean\" _would_ do in terms of\n> \"ls-files\", perhaps that is what needs to be fixed, so that we can express\n> \"git clean --some-set-of-options\" as:\n> \n>     git ls-files -z --set-of-options-equivalent-to-what-is-given-to-clean |\n>     xargs -0 rm -fr\n> \n\nI agree that a --null option to git-clean is unnecessary if git-ls-files\nis used. It seems like they can be made pretty much equivalent except\nthat git-ls-files doesn't seem to have a way of listing \"only files\" or\n\"only directories\"?\n\n-- \nRoss Lagerwall\n"}]}