{"thread":{"id":"12823","subject":"[PATCH 2/2] builtin-prune.c: fix object parsing and use parse_options()","startedAt":"2008-03-23T20:50:29Z","lastAt":"2008-03-27T21:11:43Z","messageCount":22,"participants":["Michele Ballabio","Johannes Schindelin","Junio C Hamano","Johannes Sixt"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"72812","messageId":"200803232150.29971.barra_cuda@katamail.com","threadId":"12823","inReplyTo":null,"subject":"[PATCH 2/2] builtin-prune.c: fix object parsing and use parse_options()","fromName":"Michele Ballabio","fromEmail":"barra_cuda@katamail.com","sentAt":"2008-03-23T20:50:29Z","receivedAt":"2008-03-23T20:50:29Z","isPatch":true,"sender":{"key":"barra_cuda@katamail.com","avatar":"https://avatars.githubusercontent.com/u/16371673?v=4"},"body":"git-prune used to remove loose objects whether they were specified in\nthe command line or not. This patch makes git-prune behave as stated\nin the manpage: it does not prune any listed head nor reachable objects;\nthe parsing machinery now uses parse_options().\n\nSigned-off-by: Michele Ballabio <barra_cuda@katamail.com>\n---\n builtin-prune.c  |   50 ++++++++++++++++++++++++++++++--------------------\n t/t5304-prune.sh |    2 +-\n 2 files changed, 31 insertions(+), 21 deletions(-)\n\ndiff --git a/builtin-prune.c b/builtin-prune.c\nindex bb8ead9..7b3e15d 100644\n--- a/builtin-prune.c\n+++ b/builtin-prune.c\n@@ -4,8 +4,12 @@\n #include \"revision.h\"\n #include \"builtin.h\"\n #include \"reachable.h\"\n+#include \"parse-options.h\"\n \n-static const char prune_usage[] = \"git-prune [-n]\";\n+static const char * const prune_usage[] = {\n+\t\"git-prune [-n] [--expire <time>] [--] [<head>...]\",\n+\tNULL\n+};\n static int show_only;\n static unsigned long expire;\n \n@@ -121,32 +125,38 @@ static void remove_temporary_files(void)\n \tclosedir(dir);\n }\n \n+static int parse_opt_expire(const struct option *opt, const char *arg,\n+\t\tint unset)\n+{\n+\texpire = approxidate(arg);\n+\treturn 0;\n+}\n+\n int cmd_prune(int argc, const char **argv, const char *prefix)\n {\n-\tint i;\n \tstruct rev_info revs;\n \n-\tfor (i = 1; i < argc; i++) {\n-\t\tconst char *arg = argv[i];\n-\t\tif (!strcmp(arg, \"-n\")) {\n-\t\t\tshow_only = 1;\n-\t\t\tcontinue;\n-\t\t}\n-\t\tif (!strcmp(arg, \"--expire\")) {\n-\t\t\tif (++i < argc) {\n-\t\t\t\texpire = approxidate(argv[i]);\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t}\n-\t\telse if (!prefixcmp(arg, \"--expire=\")) {\n-\t\t\texpire = approxidate(arg + 9);\n-\t\t\tcontinue;\n-\t\t}\n-\t\tusage(prune_usage);\n-\t}\n+\tconst struct option options[] = {\n+\t\tOPT_BOOLEAN('n', NULL, &show_only,\n+\t\t\t\t\"do not remove, show only\"),\n+\t\tOPT_CALLBACK(0, \"expire\", &expire, \"time\",\n+\t\t\t\t\"expire objects older than <time>\",\n+\t\t\t\tparse_opt_expire),\n+\t\tOPT_END()\n+\t};\n+\n+\targc = parse_options(argc, argv, options, prune_usage,\n+\t\t\tPARSE_OPT_STOP_AT_NON_OPTION |\n+\t\t\tPARSE_OPT_KEEP_DASHDASH);\n \n \tsave_commit_buffer = 0;\n \tinit_revisions(&revs, prefix);\n+\n+\tif (argc > 1)\n+\t\targc = setup_revisions(argc, argv, &revs, NULL);\n+\tif (argc > 1)\n+\t\tdie (\"unrecognized argument: %s\", argv[1]);\n+\n \tmark_reachable_objects(&revs, 1);\n \n \tprune_object_dir(get_object_directory());\ndiff --git a/t/t5304-prune.sh b/t/t5304-prune.sh\nindex d5f12f7..0638297 100644\n--- a/t/t5304-prune.sh\n+++ b/t/t5304-prune.sh\n@@ -92,7 +92,7 @@ test_expect_success 'prune: prune unreachable heads' '\n \n '\n \n-test_expect_failure 'prune: do not prune heads listed as an argument' '\n+test_expect_success 'prune: do not prune heads listed as an argument' '\n \n \t: > file2 &&\n \tgit add file2 &&\n-- \n1.5.4.3\n"},{"id":"72819","messageId":"alpine.LSU.1.00.0803232319130.4353@racer.site","threadId":"12823","inReplyTo":"200803232150.29971.barra_cuda@katamail.com","subject":"Re: [PATCH 2/2] builtin-prune.c: fix object parsing and use parse_options()","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2008-03-23T22:21:49Z","receivedAt":"2008-03-23T22:21:49Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Sun, 23 Mar 2008, Michele Ballabio wrote:\n\n> -static const char prune_usage[] = \"git-prune [-n]\";\n> +static const char * const prune_usage[] = {\n> +\t\"git-prune [-n] [--expire <time>] [--] [<head>...]\",\n> +\tNULL\n> +};\n\nAs you already use parse-options, should this not be rather\n\nstatic const char * const prune_usage[] = {\n\t\"git-prune [options] [--] [<commit>...]\",\n\nHmm?\n\n> +static int parse_opt_expire(const struct option *opt, const char *arg,\n> +\t\tint unset)\n> +{\n> +\texpire = approxidate(arg);\n> +\treturn 0;\n> +}\n\nThis would probably be a good candidate to live in parse-options.[ch], no?\n\nBut yes, the patch is good!\n\nCiao,\nDscho\n"},{"id":"72879","messageId":"200803241331.17986.barra_cuda@katamail.com","threadId":"12823","inReplyTo":"alpine.LSU.1.00.0803232319130.4353@racer.site","subject":"Re: [PATCH 2/2] builtin-prune.c: fix object parsing and use parse_options()","fromName":"Michele Ballabio","fromEmail":"barra_cuda@katamail.com","sentAt":"2008-03-24T12:31:17Z","receivedAt":"2008-03-24T12:31:17Z","isPatch":true,"sender":{"key":"barra_cuda@katamail.com","avatar":"https://avatars.githubusercontent.com/u/16371673?v=4"},"body":"On Sunday 23 March 2008, Johannes Schindelin wrote:\n> On Sun, 23 Mar 2008, Michele Ballabio wrote:\n> \n> > -static const char prune_usage[] = \"git-prune [-n]\";\n> > +static const char * const prune_usage[] = {\n> > +\t\"git-prune [-n] [--expire <time>] [--] [<head>...]\",\n> > +\tNULL\n> > +};\n> \n> As you already use parse-options, should this not be rather\n> \n> static const char * const prune_usage[] = {\n> \t\"git-prune [options] [--] [<commit>...]\",\n> \n> Hmm?\n\nOk, but the usage string is quite short anyway... and other commands\nshow a similar quite detailed usage string. Not that I care strongly\nabout this, though.\n\n> > +static int parse_opt_expire(const struct option *opt, const char *arg,\n> > +\t\tint unset)\n> > +{\n> > +\texpire = approxidate(arg);\n> > +\treturn 0;\n> > +}\n> \n> This would probably be a good candidate to live in parse-options.[ch], no?\n\nUhm, probably, yes. See the patch below.\n\n> But yes, the patch is good!\n\nThank you.\n\n-- >8 --\nparse-options.c: introduce callback function for approxidate()\n\nThere are quite a few places that will need to call approxidate(),\nwhen they'll adopt the parse-options system, so this patch adds the\nfunction parse_opt_approxidate_cb(), to be used within\nOPT_CALLBACK, and converts the only user so far.\n\nSigned-off-by: Michele Ballabio <barra_cuda@katamail.com>\n---\n builtin-prune.c |    9 +--------\n parse-options.c |    7 +++++++\n parse-options.h |    2 ++\n 3 files changed, 10 insertions(+), 8 deletions(-)\n\ndiff --git a/builtin-prune.c b/builtin-prune.c\nindex 7b3e15d..a5d6fe5 100644\n--- a/builtin-prune.c\n+++ b/builtin-prune.c\n@@ -125,13 +125,6 @@ static void remove_temporary_files(void)\n \tclosedir(dir);\n }\n \n-static int parse_opt_expire(const struct option *opt, const char *arg,\n-\t\tint unset)\n-{\n-\texpire = approxidate(arg);\n-\treturn 0;\n-}\n-\n int cmd_prune(int argc, const char **argv, const char *prefix)\n {\n \tstruct rev_info revs;\n@@ -141,7 +134,7 @@ int cmd_prune(int argc, const char **argv, const char *prefix)\n \t\t\t\t\"do not remove, show only\"),\n \t\tOPT_CALLBACK(0, \"expire\", &expire, \"time\",\n \t\t\t\t\"expire objects older than <time>\",\n-\t\t\t\tparse_opt_expire),\n+\t\t\t\tparse_opt_approxidate_cb),\n \t\tOPT_END()\n \t};\n \ndiff --git a/parse-options.c b/parse-options.c\nindex 8e64316..6ec7fe8 100644\n--- a/parse-options.c\n+++ b/parse-options.c\n@@ -409,3 +409,10 @@ int parse_opt_abbrev_cb(const struct option *opt, const char *arg, int unset)\n \t*(int *)(opt->value) = v;\n \treturn 0;\n }\n+\n+int parse_opt_approxidate_cb(const struct option *opt, const char *arg,\n+\t\tint unset)\n+{\n+\t*(unsigned int *)(opt->value) = approxidate(arg);\n+\treturn 0;\n+}\ndiff --git a/parse-options.h b/parse-options.h\nindex 1af62b0..e6976ed 100644\n--- a/parse-options.h\n+++ b/parse-options.h\n@@ -110,6 +110,8 @@ extern NORETURN void usage_with_options(const char * const *usagestr,\n \n /*----- some often used options -----*/\n extern int parse_opt_abbrev_cb(const struct option *, const char *, int);\n+extern int parse_opt_approxidate_cb(const struct option *, const char *,\n+\t\tint);\n \n #define OPT__VERBOSE(var)  OPT_BOOLEAN('v', \"verbose\", (var), \"be verbose\")\n #define OPT__QUIET(var)    OPT_BOOLEAN('q', \"quiet\",   (var), \"be quiet\")\n-- \n1.5.4.3\n"},{"id":"72883","messageId":"alpine.LSU.1.00.0803241409400.4353@racer.site","threadId":"12823","inReplyTo":"200803241331.17986.barra_cuda@katamail.com","subject":"Re: [PATCH 2/2] builtin-prune.c: fix object parsing and use parse_options()","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2008-03-24T13:13:19Z","receivedAt":"2008-03-24T13:13:19Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Mon, 24 Mar 2008, Michele Ballabio wrote:\n\n> diff --git a/parse-options.h b/parse-options.h\n> index 1af62b0..e6976ed 100644\n> --- a/parse-options.h\n> +++ b/parse-options.h\n> @@ -110,6 +110,8 @@ extern NORETURN void usage_with_options(const char * const *usagestr,\n>  \n>  /*----- some often used options -----*/\n>  extern int parse_opt_abbrev_cb(const struct option *, const char *, int);\n> +extern int parse_opt_approxidate_cb(const struct option *, const char *,\n> +\t\tint);\n>  \n>  #define OPT__VERBOSE(var)  OPT_BOOLEAN('v', \"verbose\", (var), \"be verbose\")\n>  #define OPT__QUIET(var)    OPT_BOOLEAN('q', \"quiet\",   (var), \"be quiet\")\n\nAnd maybe a\n\n#define OPT_DATE(s, l, v, h)\t{ OPTION_CALLBACK, (s), (l), (v), \"time\", \n(h), 0, parse_opt_approxidate_cb }\n\nHmm?\n\nCiao,\nDscho\n"},{"id":"72890","messageId":"alpine.LSU.1.00.0803241458430.4353@racer.site","threadId":"12823","inReplyTo":"200803241502.21465.barra_cuda@katamail.com","subject":"Re: [PATCH 3/2] parse-options.c: introduce OPT_DATE","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2008-03-24T13:59:03Z","receivedAt":"2008-03-24T13:59:03Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Mon, 24 Mar 2008, Michele Ballabio wrote:\n\n> There are quite a few places that will need to call approxidate(), when \n> they'll adopt the parse-options system, so this patch adds the function \n> parse_opt_approxidate_cb(), used by OPT_DATE, and converts the only user \n> so far.\n\nThanks!\n\nCiao,\nDscho\n"},{"id":"72888","messageId":"200803241502.21465.barra_cuda@katamail.com","threadId":"12823","inReplyTo":"alpine.LSU.1.00.0803241409400.4353@racer.site","subject":"[PATCH 3/2] parse-options.c: introduce OPT_DATE","fromName":"Michele Ballabio","fromEmail":"barra_cuda@katamail.com","sentAt":"2008-03-24T14:02:21Z","receivedAt":"2008-03-24T14:02:21Z","isPatch":true,"sender":{"key":"barra_cuda@katamail.com","avatar":"https://avatars.githubusercontent.com/u/16371673?v=4"},"body":"There are quite a few places that will need to call approxidate(),\nwhen they'll adopt the parse-options system, so this patch adds the\nfunction parse_opt_approxidate_cb(), used by OPT_DATE, and converts\nthe only user so far.\n\nSigned-off-by: Michele Ballabio <barra_cuda@katamail.com>\n---\nOn Monday 24 March 2008, Johannes Schindelin wrote:\n> And maybe a\n> \n> #define OPT_DATE(s, l, v, h)    { OPTION_CALLBACK, (s), (l), (v), \"time\", \n> (h), 0, parse_opt_approxidate_cb }\n\nOh, right. Somehow I thought it was simpler not to do this.\n\nThank you for your review and suggestions.\n\nThis is on top of\n[PATCH 2/2] builtin-prune.c: fix object parsing and use parse_options()\n\n builtin-prune.c |   12 ++----------\n parse-options.c |    7 +++++++\n parse-options.h |    5 +++++\n 3 files changed, 14 insertions(+), 10 deletions(-)\n\ndiff --git a/builtin-prune.c b/builtin-prune.c\nindex 7b3e15d..40581df 100644\n--- a/builtin-prune.c\n+++ b/builtin-prune.c\n@@ -125,13 +125,6 @@ static void remove_temporary_files(void)\n \tclosedir(dir);\n }\n \n-static int parse_opt_expire(const struct option *opt, const char *arg,\n-\t\tint unset)\n-{\n-\texpire = approxidate(arg);\n-\treturn 0;\n-}\n-\n int cmd_prune(int argc, const char **argv, const char *prefix)\n {\n \tstruct rev_info revs;\n@@ -139,9 +132,8 @@ int cmd_prune(int argc, const char **argv, const char *prefix)\n \tconst struct option options[] = {\n \t\tOPT_BOOLEAN('n', NULL, &show_only,\n \t\t\t\t\"do not remove, show only\"),\n-\t\tOPT_CALLBACK(0, \"expire\", &expire, \"time\",\n-\t\t\t\t\"expire objects older than <time>\",\n-\t\t\t\tparse_opt_expire),\n+\t\tOPT_DATE(0, \"expire\", &expire,\n+\t\t\t\t\"expire objects older than <time>\"),\n \t\tOPT_END()\n \t};\n \ndiff --git a/parse-options.c b/parse-options.c\nindex 8e64316..6ec7fe8 100644\n--- a/parse-options.c\n+++ b/parse-options.c\n@@ -409,3 +409,10 @@ int parse_opt_abbrev_cb(const struct option *opt, const char *arg, int unset)\n \t*(int *)(opt->value) = v;\n \treturn 0;\n }\n+\n+int parse_opt_approxidate_cb(const struct option *opt, const char *arg,\n+\t\tint unset)\n+{\n+\t*(unsigned int *)(opt->value) = approxidate(arg);\n+\treturn 0;\n+}\ndiff --git a/parse-options.h b/parse-options.h\nindex 1af62b0..c98f89e 100644\n--- a/parse-options.h\n+++ b/parse-options.h\n@@ -110,6 +110,8 @@ extern NORETURN void usage_with_options(const char * const *usagestr,\n \n /*----- some often used options -----*/\n extern int parse_opt_abbrev_cb(const struct option *, const char *, int);\n+extern int parse_opt_approxidate_cb(const struct option *, const char *,\n+\t\tint);\n \n #define OPT__VERBOSE(var)  OPT_BOOLEAN('v', \"verbose\", (var), \"be verbose\")\n #define OPT__QUIET(var)    OPT_BOOLEAN('q', \"quiet\",   (var), \"be quiet\")\n@@ -118,5 +120,8 @@ extern int parse_opt_abbrev_cb(const struct option *, const char *, int);\n \t{ OPTION_CALLBACK, 0, \"abbrev\", (var), \"n\", \\\n \t  \"use <n> digits to display SHA-1s\", \\\n \t  PARSE_OPT_OPTARG, &parse_opt_abbrev_cb, 0 }\n+#define OPT_DATE(s, l, v, h) \\\n+\t{ OPTION_CALLBACK, (s), (l), (v), \"time\",(h), 0, \\\n+\t  parse_opt_approxidate_cb }\n \n #endif\n-- \n1.5.4.3\n"},{"id":"72936","messageId":"200803241725.42940.barra_cuda@katamail.com","threadId":"12823","inReplyTo":"200803241502.21465.barra_cuda@katamail.com","subject":"Re: [PATCH 3/2] parse-options.c: introduce OPT_DATE","fromName":"Michele Ballabio","fromEmail":"barra_cuda@katamail.com","sentAt":"2008-03-24T16:25:42Z","receivedAt":"2008-03-24T16:25:42Z","isPatch":true,"sender":{"key":"barra_cuda@katamail.com","avatar":"https://avatars.githubusercontent.com/u/16371673?v=4"},"body":"On Monday 24 March 2008, Michele Ballabio wrote:\n> +               OPT_DATE(0, \"expire\", &expire,\n\n[...]\n\n> +#define OPT_DATE(s, l, v, h) \\\n\nOoops. To be consistent, these should be OPT__DATE (with two underscores)\ninstead (and in the commit message, too).\n"},{"id":"72942","messageId":"alpine.LSU.1.00.0803242102140.4353@racer.site","threadId":"12823","inReplyTo":"200803241725.42940.barra_cuda@katamail.com","subject":"Re: [PATCH 3/2] parse-options.c: introduce OPT_DATE","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2008-03-24T20:03:04Z","receivedAt":"2008-03-24T20:03:04Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Mon, 24 Mar 2008, Michele Ballabio wrote:\n\n> On Monday 24 March 2008, Michele Ballabio wrote:\n> > +               OPT_DATE(0, \"expire\", &expire,\n> \n> [...]\n> \n> > +#define OPT_DATE(s, l, v, h) \\\n> \n> Ooops. To be consistent, these should be OPT__DATE (with two \n> underscores) instead (and in the commit message, too).\n\nI thought OPT__BLA was reserved for --bla options?  IOW OPT__DATE would \nnot be usable to implement --expire, but only --date.\n\nI might be wrong, though.\n\nCiao,\nDscho\n"},{"id":"72944","messageId":"7vwsnrubmd.fsf@gitster.siamese.dyndns.org","threadId":"12823","inReplyTo":"200803241502.21465.barra_cuda@katamail.com","subject":"Re: [PATCH 3/2] parse-options.c: introduce OPT_DATE","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-03-24T20:10:18Z","receivedAt":"2008-03-24T20:10:18Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Michele Ballabio <barra_cuda@katamail.com> writes:\n\n> +int parse_opt_approxidate_cb(const struct option *opt, const char *arg,\n> +\t\tint unset)\n> +{\n> +\t*(unsigned int *)(opt->value) = approxidate(arg);\n\nDoesn't approxidate return ulong, not uint?\n"},{"id":"72958","messageId":"200803242218.44026.barra_cuda@katamail.com","threadId":"12823","inReplyTo":"7vwsnrubmd.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH 3/2] parse-options.c: introduce OPT_DATE","fromName":"Michele Ballabio","fromEmail":"barra_cuda@katamail.com","sentAt":"2008-03-24T21:18:43Z","receivedAt":"2008-03-24T21:18:43Z","isPatch":true,"sender":{"key":"barra_cuda@katamail.com","avatar":"https://avatars.githubusercontent.com/u/16371673?v=4"},"body":"On Monday 24 March 2008, Junio C Hamano wrote:\n> Michele Ballabio <barra_cuda@katamail.com> writes:\n> \n> > +int parse_opt_approxidate_cb(const struct option *opt, const char *arg,\n> > +             int unset)\n> > +{\n> > +     *(unsigned int *)(opt->value) = approxidate(arg);\n> \n> Doesn't approxidate return ulong, not uint?\n\nYes, you're right.\n"},{"id":"73006","messageId":"7vmyonnvbr.fsf@gitster.siamese.dyndns.org","threadId":"12823","inReplyTo":"200803242218.44026.barra_cuda@katamail.com","subject":"Re: [PATCH 3/2] parse-options.c: introduce OPT_DATE","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-03-25T06:58:48Z","receivedAt":"2008-03-25T06:58:48Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Michele Ballabio <barra_cuda@katamail.com> writes:\n\n> On Monday 24 March 2008, Junio C Hamano wrote:\n>> Michele Ballabio <barra_cuda@katamail.com> writes:\n>> \n>> > +int parse_opt_approxidate_cb(const struct option *opt, const char *arg,\n>> > +             int unset)\n>> > +{\n>> > +     *(unsigned int *)(opt->value) = approxidate(arg);\n>> \n>> Doesn't approxidate return ulong, not uint?\n>\n> Yes, you're right.\n\nNow, it is getting somewhat tiring to keep track of \"oops, that was wrong,\nand here is a fix-up on top\".\n\nSo here is my attempt to summarize by presenting them in an order that I\nthink is sensible.\n"},{"id":"73007","messageId":"7vhcevnvbd.fsf@gitster.siamese.dyndns.org","threadId":"12823","inReplyTo":"200803242218.44026.barra_cuda@katamail.com","subject":"[PATCH 1/5] parse-options.c: introduce OPT_DATE","fromName":"Junio C Hamano","fromEmail":"junio@pobox.com","sentAt":"2008-03-25T06:59:02Z","receivedAt":"2008-03-25T06:59:02Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"From: Michele Ballabio <barra_cuda@katamail.com>\nDate: Mon, 24 Mar 2008 15:02:21 +0100\n\nThere are quite a few places that will need to call approxidate(),\nwhen they'll adopt the parse-options system, so this patch adds the\nfunction parse_opt_approxidate_cb(), used by OPT_DATE.\n\nSigned-off-by: Michele Ballabio <barra_cuda@katamail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n parse-options.c |    7 +++++++\n parse-options.h |    4 ++++\n 2 files changed, 11 insertions(+), 0 deletions(-)\n\ndiff --git a/parse-options.c b/parse-options.c\nindex 8e64316..e87cafb 100644\n--- a/parse-options.c\n+++ b/parse-options.c\n@@ -409,3 +409,10 @@ int parse_opt_abbrev_cb(const struct option *opt, const char *arg, int unset)\n \t*(int *)(opt->value) = v;\n \treturn 0;\n }\n+\n+int parse_opt_approxidate_cb(const struct option *opt, const char *arg,\n+\t\t\t     int unset)\n+{\n+\t*(unsigned long *)(opt->value) = approxidate(arg);\n+\treturn 0;\n+}\ndiff --git a/parse-options.h b/parse-options.h\nindex 1af62b0..4ee443d 100644\n--- a/parse-options.h\n+++ b/parse-options.h\n@@ -94,6 +94,9 @@ struct option {\n #define OPT_SET_PTR(s, l, v, h, p)  { OPTION_SET_PTR, (s), (l), (v), NULL, (h), 0, NULL, (p) }\n #define OPT_INTEGER(s, l, v, h)     { OPTION_INTEGER, (s), (l), (v), NULL, (h) }\n #define OPT_STRING(s, l, v, a, h)   { OPTION_STRING,  (s), (l), (v), (a), (h) }\n+#define OPT_DATE(s, l, v, h) \\\n+\t{ OPTION_CALLBACK, (s), (l), (v), \"time\",(h), 0, \\\n+\t  parse_opt_approxidate_cb }\n #define OPT_CALLBACK(s, l, v, a, h, f) \\\n \t{ OPTION_CALLBACK, (s), (l), (v), (a), (h), 0, (f) }\n \n@@ -110,6 +113,7 @@ extern NORETURN void usage_with_options(const char * const *usagestr,\n \n /*----- some often used options -----*/\n extern int parse_opt_abbrev_cb(const struct option *, const char *, int);\n+extern int parse_opt_approxidate_cb(const struct option *, const char *, int);\n \n #define OPT__VERBOSE(var)  OPT_BOOLEAN('v', \"verbose\", (var), \"be verbose\")\n #define OPT__QUIET(var)    OPT_BOOLEAN('q', \"quiet\",   (var), \"be quiet\")\n-- \n1.5.5.rc1.121.g1594\n"},{"id":"73008","messageId":"7vbq53nvaz.fsf@gitster.siamese.dyndns.org","threadId":"12823","inReplyTo":"200803242218.44026.barra_cuda@katamail.com","subject":"[PATCH 2/5] test_must_fail: 129 is a valid error code from usage()","fromName":"Junio C Hamano","fromEmail":"junio@pobox.com","sentAt":"2008-03-25T06:59:16Z","receivedAt":"2008-03-25T06:59:16Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"From: Junio C Hamano <gitster@pobox.com>\nDate: Mon, 24 Mar 2008 23:07:08 -0700\n\nWhen a git command is run under test_must_fail to make sure that\nthe argument parser catches bogus command line, it exits with 129.\nWe need to catch it as a valid \"graceful error exit\".\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n t/test-lib.sh |    2 +-\n 1 files changed, 1 insertions(+), 1 deletions(-)\n\ndiff --git a/t/test-lib.sh b/t/test-lib.sh\nindex 870b255..7c2a8ba 100644\n--- a/t/test-lib.sh\n+++ b/t/test-lib.sh\n@@ -300,7 +300,7 @@ test_expect_code () {\n \n test_must_fail () {\n \t\"$@\"\n-\ttest $? -gt 0 -a $? -le 128\n+\ttest $? -gt 0 -a $? -le 129\n }\n \n # test_cmp is a helper function to compare actual and expected output.\n-- \n1.5.5.rc1.121.g1594\n"},{"id":"73009","messageId":"7v63vbnvak.fsf@gitster.siamese.dyndns.org","threadId":"12823","inReplyTo":"200803242218.44026.barra_cuda@katamail.com","subject":"[PATCH 3/5] Add tests for git-prune","fromName":"Junio C Hamano","fromEmail":"junio@pobox.com","sentAt":"2008-03-25T06:59:31Z","receivedAt":"2008-03-25T06:59:31Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"From: Michele Ballabio <barra_cuda@katamail.com>\nDate: Sun, 23 Mar 2008 22:34:34 +0100\n\nIt seems that git prune changed behaviour with respect to revisions added\nfrom command line, probably when it became a builtin. Currently, it prints\na short usage and exits: instead, it should take those revisions into\naccount and not prune them. So add a couple of test to point this out.\n\nWe'll be fixing this by switching to parse_options(), so add tests to\ndetect bogus command line parameters as well, to keep ourselves from\nintroducing regressions.\n\nSigned-off-by: Michele Ballabio <barra_cuda@katamail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n t/t5304-prune.sh |   34 ++++++++++++++++++++++++++++++++++\n 1 files changed, 34 insertions(+), 0 deletions(-)\n\ndiff --git a/t/t5304-prune.sh b/t/t5304-prune.sh\nindex 47090c4..3d81e1f 100644\n--- a/t/t5304-prune.sh\n+++ b/t/t5304-prune.sh\n@@ -78,4 +78,38 @@ test_expect_success 'gc: start with ok gc.pruneExpire' '\n \n '\n \n+test_expect_success 'prune: prune nonsense parameters' '\n+\n+\ttest_must_fail git prune garbage &&\n+\ttest_must_fail git prune --- &&\n+\ttest_must_fail git prune --no-such-option\n+\n+'\n+\n+test_expect_success 'prune: prune unreachable heads' '\n+\n+\tgit config core.logAllRefUpdates false &&\n+\tmv .git/logs .git/logs.old &&\n+\t: > file2 &&\n+\tgit add file2 &&\n+\tgit commit -m temporary &&\n+\ttmp_head=$(git rev-list -1 HEAD) &&\n+\tgit reset HEAD^ &&\n+\tgit prune &&\n+\ttest_must_fail git reset $tmp_head --\n+\n+'\n+\n+test_expect_failure 'prune: do not prune heads listed as an argument' '\n+\n+\t: > file2 &&\n+\tgit add file2 &&\n+\tgit commit -m temporary &&\n+\ttmp_head=$(git rev-list -1 HEAD) &&\n+\tgit reset HEAD^ &&\n+\tgit prune -- $tmp_head &&\n+\tgit reset $tmp_head --\n+\n+'\n+\n test_done\n-- \n1.5.5.rc1.121.g1594\n"},{"id":"73010","messageId":"7vzlsnmgps.fsf@gitster.siamese.dyndns.org","threadId":"12823","inReplyTo":"200803242218.44026.barra_cuda@katamail.com","subject":"[PATCH 4/5] builtin-prune.c: use parse_options()","fromName":"Junio C Hamano","fromEmail":"junio@pobox.com","sentAt":"2008-03-25T06:59:43Z","receivedAt":"2008-03-25T06:59:43Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"From: Michele Ballabio <barra_cuda@katamail.com>\nDate: Sun, 23 Mar 2008 21:50:29 +0100\n\nUsing the OPT_DATE() introduced earlier, this updates builtin-prune to\nuse parse_options().\n\nSigned-off-by: Michele Ballabio <barra_cuda@katamail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n builtin-prune.c |   38 ++++++++++++++++----------------------\n 1 files changed, 16 insertions(+), 22 deletions(-)\n\ndiff --git a/builtin-prune.c b/builtin-prune.c\nindex bb8ead9..71caac5 100644\n--- a/builtin-prune.c\n+++ b/builtin-prune.c\n@@ -4,8 +4,12 @@\n #include \"revision.h\"\n #include \"builtin.h\"\n #include \"reachable.h\"\n+#include \"parse-options.h\"\n \n-static const char prune_usage[] = \"git-prune [-n]\";\n+static const char * const prune_usage[] = {\n+\t\"git-prune [-n] [--expire <time>] [--] [<head>...]\",\n+\tNULL\n+};\n static int show_only;\n static unsigned long expire;\n \n@@ -123,32 +127,22 @@ static void remove_temporary_files(void)\n \n int cmd_prune(int argc, const char **argv, const char *prefix)\n {\n-\tint i;\n \tstruct rev_info revs;\n-\n-\tfor (i = 1; i < argc; i++) {\n-\t\tconst char *arg = argv[i];\n-\t\tif (!strcmp(arg, \"-n\")) {\n-\t\t\tshow_only = 1;\n-\t\t\tcontinue;\n-\t\t}\n-\t\tif (!strcmp(arg, \"--expire\")) {\n-\t\t\tif (++i < argc) {\n-\t\t\t\texpire = approxidate(argv[i]);\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t}\n-\t\telse if (!prefixcmp(arg, \"--expire=\")) {\n-\t\t\texpire = approxidate(arg + 9);\n-\t\t\tcontinue;\n-\t\t}\n-\t\tusage(prune_usage);\n-\t}\n+\tconst struct option options[] = {\n+\t\tOPT_BOOLEAN('n', NULL, &show_only,\n+\t\t\t    \"do not remove, show only\"),\n+\t\tOPT_DATE(0, \"expire\", &expire,\n+\t\t\t \"expire objects older than <time>\"),\n+\t\tOPT_END()\n+\t};\n \n \tsave_commit_buffer = 0;\n \tinit_revisions(&revs, prefix);\n-\tmark_reachable_objects(&revs, 1);\n \n+\targc = parse_options(argc, argv, options, prune_usage, 0);\n+\tif (argc)\n+\t\tdie (\"unrecognized argument: %s\", name);\n+\tmark_reachable_objects(&revs, 1);\n \tprune_object_dir(get_object_directory());\n \n \tsync();\n-- \n1.5.5.rc1.121.g1594\n"},{"id":"73011","messageId":"7vtzivmgpg.fsf@gitster.siamese.dyndns.org","threadId":"12823","inReplyTo":"200803242218.44026.barra_cuda@katamail.com","subject":"[PATCH 5/5] builtin-prune: protect objects listed on the command line","fromName":"Junio C Hamano","fromEmail":"junio@pobox.com","sentAt":"2008-03-25T06:59:55Z","receivedAt":"2008-03-25T06:59:55Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"From: Junio C Hamano <gitster@pobox.com>\nDate: Mon, 24 Mar 2008 23:20:51 -0700\n\nFinally, this resurrects the documented behaviour to protect other\nobjects listed on the command line from getting pruned.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n * This is done deliberately differently from what you did.  Because we do\n   not want to accept \"we allow losing what's reachable from master\" with\n   \"git prune master..next\", setup_revisions() is not the right thing to\n   use for this command.\n\n builtin-prune.c  |   12 ++++++++++--\n t/t5304-prune.sh |    2 +-\n 2 files changed, 11 insertions(+), 3 deletions(-)\n\ndiff --git a/builtin-prune.c b/builtin-prune.c\nindex 71caac5..ca50cca 100644\n--- a/builtin-prune.c\n+++ b/builtin-prune.c\n@@ -140,8 +140,16 @@ int cmd_prune(int argc, const char **argv, const char *prefix)\n \tinit_revisions(&revs, prefix);\n \n \targc = parse_options(argc, argv, options, prune_usage, 0);\n-\tif (argc)\n-\t\tdie (\"unrecognized argument: %s\", name);\n+\twhile (argc--) {\n+\t\tstruct object *object;\n+\t\tunsigned char sha1[20];\n+\t\tconst char *name = *argv++;\n+\n+\t\tif (!get_sha1(name, sha1) && (object = parse_object(sha1)))\n+\t\t\tadd_pending_object(&revs, object, \"\");\n+\t\telse\n+\t\t\tdie (\"unrecognized argument: %s\", name);\n+\t}\n \tmark_reachable_objects(&revs, 1);\n \tprune_object_dir(get_object_directory());\n \ndiff --git a/t/t5304-prune.sh b/t/t5304-prune.sh\nindex 3d81e1f..9fd9d07 100644\n--- a/t/t5304-prune.sh\n+++ b/t/t5304-prune.sh\n@@ -100,7 +100,7 @@ test_expect_success 'prune: prune unreachable heads' '\n \n '\n \n-test_expect_failure 'prune: do not prune heads listed as an argument' '\n+test_expect_success 'prune: do not prune heads listed as an argument' '\n \n \t: > file2 &&\n \tgit add file2 &&\n-- \n1.5.5.rc1.121.g1594\n"},{"id":"73021","messageId":"alpine.LSU.1.00.0803251100520.10660@wbgn129.biozentrum.uni-wuerzburg.de","threadId":"12823","inReplyTo":"7vbq53nvaz.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH 2/5] test_must_fail: 129 is a valid error code from usage()","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2008-03-25T10:01:43Z","receivedAt":"2008-03-25T10:01:43Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Mon, 24 Mar 2008, Junio C Hamano wrote:\n\n> diff --git a/t/test-lib.sh b/t/test-lib.sh\n> index 870b255..7c2a8ba 100644\n> --- a/t/test-lib.sh\n> +++ b/t/test-lib.sh\n> @@ -300,7 +300,7 @@ test_expect_code () {\n>  \n>  test_must_fail () {\n>  \t\"$@\"\n> -\ttest $? -gt 0 -a $? -le 128\n> +\ttest $? -gt 0 -a $? -le 129\n\nIIRC exit status is a signed byte on Win32.  Can somebody check?  I'll be \nin a hurry in 1.5 hours and travelling for two days.\n\nCiao,\nDscho\n"},{"id":"73034","messageId":"47E8E04E.6060606@viscovery.net","threadId":"12823","inReplyTo":"alpine.LSU.1.00.0803251100520.10660@wbgn129.biozentrum.uni-wuerzburg.de","subject":"Re: [PATCH 2/5] test_must_fail: 129 is a valid error code from usage()","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2008-03-25T11:21:50Z","receivedAt":"2008-03-25T11:21:50Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Johannes Schindelin schrieb:\n> Hi,\n> \n> On Mon, 24 Mar 2008, Junio C Hamano wrote:\n> \n>> diff --git a/t/test-lib.sh b/t/test-lib.sh\n>> index 870b255..7c2a8ba 100644\n>> --- a/t/test-lib.sh\n>> +++ b/t/test-lib.sh\n>> @@ -300,7 +300,7 @@ test_expect_code () {\n>>  \n>>  test_must_fail () {\n>>  \t\"$@\"\n>> -\ttest $? -gt 0 -a $? -le 128\n>> +\ttest $? -gt 0 -a $? -le 129\n> \n> IIRC exit status is a signed byte on Win32.  Can somebody check?\n\nNot at the shell level. This command:\n\n   git branch foo bar baz\n\nexits with 129 both when invoked by bash ($?) and CMD (%ERRORLEVEL%).\n\n-- Hannes\n"},{"id":"73064","messageId":"alpine.LSU.1.00.0803252026390.10660@wbgn129.biozentrum.uni-wuerzburg.de","threadId":"12823","inReplyTo":"47E8E04E.6060606@viscovery.net","subject":"Re: [PATCH 2/5] test_must_fail: 129 is a valid error code from usage()","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2008-03-25T19:27:18Z","receivedAt":"2008-03-25T19:27:18Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Tue, 25 Mar 2008, Johannes Sixt wrote:\n\n> This command:\n> \n>    git branch foo bar baz\n> \n> exits with 129 both when invoked by bash ($?) and CMD (%ERRORLEVEL%).\n\nThanks,\nDscho\n"},{"id":"73207","messageId":"7vve389lgc.fsf@gitster.siamese.dyndns.org","threadId":"12823","inReplyTo":"7vtzivmgpg.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH 5/5] builtin-prune: protect objects listed on the command line","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-03-27T16:32:35Z","receivedAt":"2008-03-27T16:32:35Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <junio@pobox.com> writes:\n\n> From: Junio C Hamano <gitster@pobox.com>\n> Date: Mon, 24 Mar 2008 23:20:51 -0700\n>\n> Finally, this resurrects the documented behaviour to protect other\n> objects listed on the command line from getting pruned.\n>\n> Signed-off-by: Junio C Hamano <gitster@pobox.com>\n> ---\n>  * This is done deliberately differently from what you did.  Because we do\n>    not want to accept \"we allow losing what's reachable from master\" with\n>    \"git prune master..next\", setup_revisions() is not the right thing to\n>    use for this command.\n\nPing?\n"},{"id":"73208","messageId":"alpine.LSU.1.00.0803271735010.3802@racer.site","threadId":"12823","inReplyTo":"7vve389lgc.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH 5/5] builtin-prune: protect objects listed on the command line","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2008-03-27T16:35:46Z","receivedAt":"2008-03-27T16:35:46Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Thu, 27 Mar 2008, Junio C Hamano wrote:\n\n> Junio C Hamano <junio@pobox.com> writes:\n> \n> > From: Junio C Hamano <gitster@pobox.com>\n> > Date: Mon, 24 Mar 2008 23:20:51 -0700\n> >\n> > Finally, this resurrects the documented behaviour to protect other \n> > objects listed on the command line from getting pruned.\n> >\n> > Signed-off-by: Junio C Hamano <gitster@pobox.com> ---\n> >  * This is done deliberately differently from what you did.  Because \n> >    we do not want to accept \"we allow losing what's reachable from \n> >    master\" with \"git prune master..next\", setup_revisions() is not the \n> >    right thing to use for this command.\n> \n> Ping?\n\nI did not see any problem with your implementation, but I thought Michele \nwould look more deeply, as he obviously cares about the to-be-fixed \nbehaviour.\n\nCiao,\nDscho\n"},{"id":"73218","messageId":"200803272211.44126.barra_cuda@katamail.com","threadId":"12823","inReplyTo":"alpine.LSU.1.00.0803271735010.3802@racer.site","subject":"Re: [PATCH 5/5] builtin-prune: protect objects listed on the command line","fromName":"Michele Ballabio","fromEmail":"barra_cuda@katamail.com","sentAt":"2008-03-27T21:11:43Z","receivedAt":"2008-03-27T21:11:43Z","isPatch":true,"sender":{"key":"barra_cuda@katamail.com","avatar":"https://avatars.githubusercontent.com/u/16371673?v=4"},"body":"On Thursday 27 March 2008, Johannes Schindelin wrote:\n> On Thu, 27 Mar 2008, Junio C Hamano wrote:\n> \n> > Junio C Hamano <junio@pobox.com> writes:\n> > \n> > > From: Junio C Hamano <gitster@pobox.com>\n> > > Date: Mon, 24 Mar 2008 23:20:51 -0700\n> > >\n> > > Finally, this resurrects the documented behaviour to protect other \n> > > objects listed on the command line from getting pruned.\n> > >\n> > > Signed-off-by: Junio C Hamano <gitster@pobox.com> ---\n> > >  * This is done deliberately differently from what you did.  Because \n> > >    we do not want to accept \"we allow losing what's reachable from \n> > >    master\" with \"git prune master..next\", setup_revisions() is not the \n> > >    right thing to use for this command.\n> > \n> > Ping?\n> \n> I did not see any problem with your implementation\n\nMe neither, but, as a nitpick, wouldn't something like\n\n\t\tif (!get_sha1(name, sha1)) {\n\t\t\tobject = parse_object(sha1);\n\t\t\tif (!object)\n\t\t\t\tdie(\"bad object %s\", name);\n\t\t} else\n\t\t\tdie(\"unrecognized argument: %s\", name);\n\nbe a bit more useful?\n"}]}