{"thread":{"id":"56495","subject":"[PATCH v1] git-clone.txt: add the --recursive option","startedAt":"2021-09-13T19:14:27Z","lastAt":"2021-09-14T20:21:56Z","messageCount":10,"participants":["Alban Gruin","Eric Sunshine","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"435769","messageId":"20210913185941.6247-1-alban.gruin@gmail.com","threadId":"56495","inReplyTo":null,"subject":"[PATCH v1] git-clone.txt: add the --recursive option","fromName":"Alban Gruin","fromEmail":"alban.gruin@gmail.com","sentAt":"2021-09-13T18:59:41Z","receivedAt":"2021-09-13T19:14:27Z","isPatch":true,"sender":{"key":"alban.gruin@gmail.com","avatar":"https://avatars.githubusercontent.com/u/6310153?v=4"},"body":"This adds the --recursive option, an alias of --recurse-submodule, to\ngit-clone's manual page.\n\nSigned-off-by: Alban Gruin <alban.gruin@gmail.com>\n---\nI found this out when a friend told me he could not remember how to\nfetch submodules with git-clone, and when another one suggested\n`--recurse-submodule'.  I checked the man page, and I was surprised to\nfind out that `--recursive' is not mentionned at all.\n\nI did not modify the synopsis.  So, this alias, although shorter than\nthe \"real\" option, would still be somewhat hidden in the man page.\n\n Documentation/git-clone.txt | 1 +\n 1 file changed, 1 insertion(+)\n\ndiff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt\nindex 3fe3810f1c..8a578252a0 100644\n--- a/Documentation/git-clone.txt\n+++ b/Documentation/git-clone.txt\n@@ -270,6 +270,7 @@ branch. This is useful e.g. to maintain minimal clones of the default\n branch of some repository for search indexing.\n \n --recurse-submodules[=<pathspec>]::\n+--recursive[=<pathspec>]::\n \tAfter the clone is created, initialize and clone submodules\n \twithin based on the provided pathspec.  If no pathspec is\n \tprovided, all submodules are initialized and cloned.\n-- \n2.30.2\n\n"},{"id":"435774","messageId":"CAPig+cR=HUDgFctXzcigZ062c=QWYfGWUPuT7scc-xU_w3NT1w@mail.gmail.com","threadId":"56495","inReplyTo":"20210913185941.6247-1-alban.gruin@gmail.com","subject":"Re: [PATCH v1] git-clone.txt: add the --recursive option","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2021-09-13T19:26:25Z","receivedAt":"2021-09-13T19:26:39Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Mon, Sep 13, 2021 at 3:14 PM Alban Gruin <alban.gruin@gmail.com> wrote:\n> This adds the --recursive option, an alias of --recurse-submodule, to\n> git-clone's manual page.\n>\n> Signed-off-by: Alban Gruin <alban.gruin@gmail.com>\n> ---\n> I found this out when a friend told me he could not remember how to\n> fetch submodules with git-clone, and when another one suggested\n> `--recurse-submodule'.  I checked the man page, and I was surprised to\n> find out that `--recursive' is not mentionned at all.\n>\n> I did not modify the synopsis.  So, this alias, although shorter than\n> the \"real\" option, would still be somewhat hidden in the man page.\n\nConsidering that the `--recursive` option was intentionally removed\nfrom `git-clone.txt` by bb62e0a99f (clone: teach --recurse-submodules\nto optionally take a pathspec, 2017-03-17), it's not clear that this\nchange helps the situation.\n"},{"id":"435789","messageId":"26422bc7-f1d4-4959-ce30-b26d8fe61888@gmail.com","threadId":"56495","inReplyTo":"CAPig+cR=HUDgFctXzcigZ062c=QWYfGWUPuT7scc-xU_w3NT1w@mail.gmail.com","subject":"Re: [PATCH v1] git-clone.txt: add the --recursive option","fromName":"Alban Gruin","fromEmail":"alban.gruin@gmail.com","sentAt":"2021-09-13T20:42:30Z","receivedAt":"2021-09-13T20:42:47Z","isPatch":true,"sender":{"key":"alban.gruin@gmail.com","avatar":"https://avatars.githubusercontent.com/u/6310153?v=4"},"body":"Hi Eric,\n\nLe 13/09/2021 à 21:26, Eric Sunshine a écrit :\n> On Mon, Sep 13, 2021 at 3:14 PM Alban Gruin <alban.gruin@gmail.com> wrote:\n>> This adds the --recursive option, an alias of --recurse-submodule, to\n>> git-clone's manual page.\n>>\n>> Signed-off-by: Alban Gruin <alban.gruin@gmail.com>\n>> ---\n>> I found this out when a friend told me he could not remember how to\n>> fetch submodules with git-clone, and when another one suggested\n>> `--recurse-submodule'.  I checked the man page, and I was surprised to\n>> find out that `--recursive' is not mentionned at all.\n>>\n>> I did not modify the synopsis.  So, this alias, although shorter than\n>> the \"real\" option, would still be somewhat hidden in the man page.\n> \n> Considering that the `--recursive` option was intentionally removed\n> from `git-clone.txt` by bb62e0a99f (clone: teach --recurse-submodules\n> to optionally take a pathspec, 2017-03-17), it's not clear that this\n> change helps the situation.\n> \n\nThe patch you mention also hides --recursive from the option array, but\nthat was reverted with 5c387428f1 (parse-options: don't emit \"ambiguous\noption\" for aliases, 2019-04-29).  The option should be re-hidden, or\neven removed.\n\nAlban\n\n"},{"id":"435793","messageId":"xmqqsfy8cft4.fsf@gitster.g","threadId":"56495","inReplyTo":"CAPig+cR=HUDgFctXzcigZ062c=QWYfGWUPuT7scc-xU_w3NT1w@mail.gmail.com","subject":"Re: [PATCH v1] git-clone.txt: add the --recursive option","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-09-13T21:43:19Z","receivedAt":"2021-09-13T21:43:25Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Eric Sunshine <sunshine@sunshineco.com> writes:\n\n> On Mon, Sep 13, 2021 at 3:14 PM Alban Gruin <alban.gruin@gmail.com> wrote:\n>> This adds the --recursive option, an alias of --recurse-submodule, to\n>> git-clone's manual page.\n>>\n>> Signed-off-by: Alban Gruin <alban.gruin@gmail.com>\n>> ---\n>> I found this out when a friend told me he could not remember how to\n>> fetch submodules with git-clone, and when another one suggested\n>> `--recurse-submodule'.  I checked the man page, and I was surprised to\n>> find out that `--recursive' is not mentionned at all.\n>>\n>> I did not modify the synopsis.  So, this alias, although shorter than\n>> the \"real\" option, would still be somewhat hidden in the man page.\n>\n> Considering that the `--recursive` option was intentionally removed\n> from `git-clone.txt` by bb62e0a99f (clone: teach --recurse-submodules\n> to optionally take a pathspec, 2017-03-17), it's not clear that this\n> change helps the situation.\n\nA logical continuation of what bb62e0a99f tried to do might be to\nhide the --recursive[=<pathspec>] from \"git clone -h\", I guess.\n"},{"id":"435794","messageId":"CAPig+cRGzmN6tH-5DmtnbW2cMHSSQ2RS_6d=B0xJ7QWKtG6yug@mail.gmail.com","threadId":"56495","inReplyTo":"26422bc7-f1d4-4959-ce30-b26d8fe61888@gmail.com","subject":"Re: [PATCH v1] git-clone.txt: add the --recursive option","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2021-09-13T21:57:35Z","receivedAt":"2021-09-13T21:57:49Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Mon, Sep 13, 2021 at 4:42 PM Alban Gruin <alban.gruin@gmail.com> wrote:\n> Le 13/09/2021 à 21:26, Eric Sunshine a écrit :\n> > On Mon, Sep 13, 2021 at 3:14 PM Alban Gruin <alban.gruin@gmail.com> wrote:\n> >> This adds the --recursive option, an alias of --recurse-submodule, to\n> >> git-clone's manual page.\n> >\n> > Considering that the `--recursive` option was intentionally removed\n> > from `git-clone.txt` by bb62e0a99f (clone: teach --recurse-submodules\n> > to optionally take a pathspec, 2017-03-17), it's not clear that this\n> > change helps the situation.\n>\n> The patch you mention also hides --recursive from the option array, but\n> that was reverted with 5c387428f1 (parse-options: don't emit \"ambiguous\n> option\" for aliases, 2019-04-29).  The option should be re-hidden, or\n> even removed.\n\nI don't quite follow. As far as I understand both by reading\n5c387428f1 and by testing, 5c387428f1 fixed tab-completion so it would\n_not_ show `--recursive`.\n\nAnyhow, another approach which we've used elsewhere is to mention the\noption in the documentation but indicate clearly that it's deprecated.\nThat way, people who run across the option in existing scripts or old\nblogs can at least find out what it means. Something like:\n\n    --recurse-submodules[=<pathspec>]::\n        After the clone is created, initialize and clone submodules\n        within based on the provided pathspec.  If no pathspec is\n        provided, all submodules are initialized and cloned.\n        (`--recursive` is a deprecated synonym.)\n\nI don't have an opinion as to whether or not we'd want to do that in this case.\n"},{"id":"435837","messageId":"d02c7f3b-221d-fbab-827a-a950bf28856c@gmail.com","threadId":"56495","inReplyTo":"CAPig+cRGzmN6tH-5DmtnbW2cMHSSQ2RS_6d=B0xJ7QWKtG6yug@mail.gmail.com","subject":"Re: [PATCH v1] git-clone.txt: add the --recursive option","fromName":"Alban Gruin","fromEmail":"alban.gruin@gmail.com","sentAt":"2021-09-14T10:27:44Z","receivedAt":"2021-09-14T10:28:14Z","isPatch":true,"sender":{"key":"alban.gruin@gmail.com","avatar":"https://avatars.githubusercontent.com/u/6310153?v=4"},"body":"Hi Eric,\n\nLe 13/09/2021 à 23:57, Eric Sunshine a écrit :\n> On Mon, Sep 13, 2021 at 4:42 PM Alban Gruin <alban.gruin@gmail.com> wrote:\n>> Le 13/09/2021 à 21:26, Eric Sunshine a écrit :\n>>> On Mon, Sep 13, 2021 at 3:14 PM Alban Gruin <alban.gruin@gmail.com> wrote:\n>>>> This adds the --recursive option, an alias of --recurse-submodule, to\n>>>> git-clone's manual page.\n>>>\n>>> Considering that the `--recursive` option was intentionally removed\n>>> from `git-clone.txt` by bb62e0a99f (clone: teach --recurse-submodules\n>>> to optionally take a pathspec, 2017-03-17), it's not clear that this\n>>> change helps the situation.\n>>\n>> The patch you mention also hides --recursive from the option array, but\n>> that was reverted with 5c387428f1 (parse-options: don't emit \"ambiguous\n>> option\" for aliases, 2019-04-29).  The option should be re-hidden, or\n>> even removed.\n> \n> I don't quite follow. As far as I understand both by reading\n> 5c387428f1 and by testing, 5c387428f1 fixed tab-completion so it would\n> _not_ show `--recursive`.\n> \n\nbb62e0a99f hid --recursive from `git clone -h' with PARSE_OPT_HIDDEN,\nbut 5c387428f1 reverted that:\n\n$ git checkout 5c387428f1~\n$ make\n$ bin-wrappers/git clone -h\n...\n    -s, --shared          setup as shared repository\n    --recurse-submodules[=<pathspec>]\n                          initialize submodules in the clone\n    -j, --jobs <n>        number of submodules cloned in parallel\n...\n\n$ git checkout 5c387428f1\n$ make\n$ bin-wrappers/git clone -h\n...\n    --recursive[=<pathspec>]\n                          initialize submodules in the clone\n    --recurse-submodules[=<pathspec>]\n                          initialize submodules in the clone\n...\n\nThe two options were then reordered by c28b036fe3 (clone: reorder\n--recursive/--recurse-submodules, 2020-03-16), and this is where we are\ntoday:\n\n$ git clone -h\n...\n    --recurse-submodules[=<pathspec>]\n                          initialize submodules in the clone\n    --recursive[=<pathspec>]\n                          alias of --recurse-submodules\n...\n\nJunio did mention[0] that --recursive was no longer in the manual, but\nnot that it was once hidden from the option list.\n\n> Anyhow, another approach which we've used elsewhere is to mention the\n> option in the documentation but indicate clearly that it's deprecated.\n> That way, people who run across the option in existing scripts or old\n> blogs can at least find out what it means. Something like:\n> \n>     --recurse-submodules[=<pathspec>]::\n>         After the clone is created, initialize and clone submodules\n>         within based on the provided pathspec.  If no pathspec is\n>         provided, all submodules are initialized and cloned.\n>         (`--recursive` is a deprecated synonym.)\n> \n> I don't have an opinion as to whether or not we'd want to do that in this case.\n> \n\n[0] https://lore.kernel.org/git/20200316212857.259093-3-gitster@pobox.com/\n\nAlban\n\n"},{"id":"435895","messageId":"xmqqbl4v2gpu.fsf@gitster.g","threadId":"56495","inReplyTo":"d02c7f3b-221d-fbab-827a-a950bf28856c@gmail.com","subject":"Re: [PATCH v1] git-clone.txt: add the --recursive option","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-09-14T17:46:05Z","receivedAt":"2021-09-14T17:46:11Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Alban Gruin <alban.gruin@gmail.com> writes:\n\n> Junio did mention[0] that --recursive was no longer in the manual, but\n> not that it was once hidden from the option list.\n\nPlease allow me to summarize the discussion so far.\n\nWe want our subcommands to take \"--recurse-submodules=<arg>\"\nuniformly, while accepting any unique prefix, e.g. --recurs=<arg>,\nas its short-hand.\n\nFor \"git clone\", we kept \"--recurse=<it>\" in the options[] table as\na HIDDEN entry as part of our deprecation plan.  This nicely hid the\ndeprecated \"--recurse=<it>\" from \"git clone -h\".\n\nBut it backfired because \"git cmd --recur=<it>\" was not a \"unique\nprefix\" (as it matched both) and triggered a disambiguation error.\nTo solve it, we introduced OPT_ALIAS() to tell the machinery that\nallows unique prefix that these two are the same thing.  As a side\neffect, because the use of OPT_ALIAS() did not have HIDDEN bit, we\nstarted showing the deprecated \"--recurse\" in \"git clone -h\" output.\n\nIs that where we are?\n\nI am wondering if it is just a matter of either\n\n * removing the \"recursive\" alias from the options table.  Because\n   we accept unique prefix, --recurse=<arg> the user types will be\n   taken as --recurse-submodules=<arg> anyway (until \"git clone\"\n   learns another option --recurse-xyzzy=<arg>, at which time it\n   will become ambiguous and error out, that is).\n\nor\n\n * adding the PARSE_OPT_HIDDEN bit to the OPT_ALIAS() element for\n   the deprecated \"recurse\" option.\n\nand all would be fine?\n\nBetween adding \"--recursive\" to the manual and describing it as a\ndeprecated synonym for \"--recurse-submodules\", and not doing so, I\ndo not have a strong preference.\n\nThanks.\n\n"},{"id":"435898","messageId":"CAPig+cTQNkwWgpgu-Mw=Qd++cUVnFrrdnaQnaSZ79RexnNQFHg@mail.gmail.com","threadId":"56495","inReplyTo":"xmqqbl4v2gpu.fsf@gitster.g","subject":"Re: [PATCH v1] git-clone.txt: add the --recursive option","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2021-09-14T17:53:11Z","receivedAt":"2021-09-14T17:53:28Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Tue, Sep 14, 2021 at 1:46 PM Junio C Hamano <gitster@pobox.com> wrote:\n> I am wondering if it is just a matter of either\n>\n>  * removing the \"recursive\" alias from the options table.  Because\n>    we accept unique prefix, --recurse=<arg> the user types will be\n>    taken as --recurse-submodules=<arg> anyway (until \"git clone\"\n>    learns another option --recurse-xyzzy=<arg>, at which time it\n>    will become ambiguous and error out, that is).\n\nWith this option, we risk breaking existing tooling which happens to\nuse the deprecated --recursive.\n\n> or\n>\n>  * adding the PARSE_OPT_HIDDEN bit to the OPT_ALIAS() element for\n>    the deprecated \"recurse\" option.\n\nI was going to suggest this as a possible way forward to address\nAlban's most recent response to my response. The lack of\nPARSE_OPT_HIDDEN on OPT_ALIAS() almost seems like an oversight.\n\n> Between adding \"--recursive\" to the manual and describing it as a\n> deprecated synonym for \"--recurse-submodules\", and not doing so, I\n> do not have a strong preference.\n\nI don't have a strong preference either, especially considering how\nlong ago --recursive was removed from the manual, however, adding it\nwould help someone who runs across --recursive in existing tooling or\nold blog post and wants to know what it does.\n"},{"id":"435901","messageId":"xmqqtuin1019.fsf@gitster.g","threadId":"56495","inReplyTo":"CAPig+cTQNkwWgpgu-Mw=Qd++cUVnFrrdnaQnaSZ79RexnNQFHg@mail.gmail.com","subject":"Re: [PATCH v1] git-clone.txt: add the --recursive option","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-09-14T18:31:46Z","receivedAt":"2021-09-14T18:31:56Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Eric Sunshine <sunshine@sunshineco.com> writes:\n\n> On Tue, Sep 14, 2021 at 1:46 PM Junio C Hamano <gitster@pobox.com> wrote:\n>> I am wondering if it is just a matter of either\n>>\n>>  * removing the \"recursive\" alias from the options table.  Because\n>>    we accept unique prefix, --recurse=<arg> the user types will be\n>>    taken as --recurse-submodules=<arg> anyway (until \"git clone\"\n>>    learns another option --recurse-xyzzy=<arg>, at which time it\n>>    will become ambiguous and error out, that is).\n>\n> With this option, we risk breaking existing tooling which happens to\n> use the deprecated --recursive.\n\nAhh, sorry and thanks for correcting my stupid thinko.  recursive is\nnot a prefix of recurse-submodules.\n\n\n>>  * adding the PARSE_OPT_HIDDEN bit to the OPT_ALIAS() element for\n>>    the deprecated \"recurse\" option.\n>\n> I was going to suggest this as a possible way forward to address\n> Alban's most recent response to my response. The lack of\n> PARSE_OPT_HIDDEN on OPT_ALIAS() almost seems like an oversight.\n\nYou may have an alias with no intention to deprecate either, so it\nwould make it cumbersome if OPT_ALIAS() always meant HIDDEN, just\nlike it currently is cumbersome for an alias that is deprecated.\n\nIndependently (because I do not think this helps in solving the\ncurrent situation), we might want to tweak the disambiguation\nmachinery to require HIDDEN ones to be spelled out exactly, because\nthey are hidden for a reason---we do not want users to casually and\naccidentally trigger them.  Of course, that is totally outside the\nscope of everything we discussed so far.\n\n>> Between adding \"--recursive\" to the manual and describing it as a\n>> deprecated synonym for \"--recurse-submodules\", and not doing so, I\n>> do not have a strong preference.\n>\n> I don't have a strong preference either, especially considering how\n> long ago --recursive was removed from the manual, however, adding it\n> would help someone who runs across --recursive in existing tooling or\n> old blog post and wants to know what it does.\n\nMakes sense.  I think we list other deprecated ones for that exact\nreason.\n"},{"id":"435918","messageId":"xmqq1r5q29i6.fsf_-_@gitster.g","threadId":"56495","inReplyTo":"xmqqtuin1019.fsf@gitster.g","subject":"Re* [PATCH v1] git-clone.txt: add the --recursive option","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-09-14T20:21:53Z","receivedAt":"2021-09-14T20:21:56Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Subject: parse-options: allow hidden aliases\n\nWhen OPT_ALIAS() was introduced to mark one option is a mere synonym\nfor another option, we forgot to add support for a use case where an\noption is made an alias with an intention to deprecat and eventually\nremove it in the future, which usually means \"git cmd -h\" hides the\ndeprecated alias while \"git cmd --help-all\" shows it.\n\nThe \"--recursive\" option of \"git clone\" and the \"--mailmap\" option\nof \"git log\" use the OPT_ALIAS mechansim to mark themselves as an\nalias of another.  The former has been deprecated but \"git clone -h\"\nstill shows it.\n\nIntroduce OPT_HIDDEN_ALIAS() that hides the entry from \"git cmd -h\"\noutput and use it for \"git clone --recursive\".\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n\n * So here is to add support for hidden aliases and application of\n   it on \"git clone\".  Perhaps everything except for the part that\n   applies to \"builtin/clone.c\" should become [1/2] of a two-patch\n   series, while the change to \"builtin/clone.c\", plus documentation\n   updates to mention \"--recursive\" as a deprecated synonym, should\n   become [2/2].\n\n   But I do not have time to go that last mile right now ;-)\n\n>>>  * adding the PARSE_OPT_HIDDEN bit to the OPT_ALIAS() element for\n>>>    the deprecated \"recurse\" option.\n>>\n>> I was going to suggest this as a possible way forward to address\n>> Alban's most recent response to my response. The lack of\n>> PARSE_OPT_HIDDEN on OPT_ALIAS() almost seems like an oversight.\n>\n> You may have an alias with no intention to deprecate either, so it\n> would make it cumbersome if OPT_ALIAS() always meant HIDDEN, just\n> like it currently is cumbersome for an alias that is deprecated.\n\n builtin/clone.c               |  2 +-\n parse-options.c               |  4 +++-\n parse-options.h               |  3 +++\n t/helper/test-parse-options.c |  1 +\n t/t0040-parse-options.sh      | 13 ++++++++++++-\n 5 files changed, 20 insertions(+), 3 deletions(-)\n\ndiff --git c/builtin/clone.c w/builtin/clone.c\nindex 66fe66679c..6fd4b41eb3 100644\n--- c/builtin/clone.c\n+++ w/builtin/clone.c\n@@ -110,7 +110,7 @@ static struct option builtin_clone_options[] = {\n \t{ OPTION_CALLBACK, 0, \"recurse-submodules\", &option_recurse_submodules,\n \t  N_(\"pathspec\"), N_(\"initialize submodules in the clone\"),\n \t  PARSE_OPT_OPTARG, recurse_submodules_cb, (intptr_t)\".\" },\n-\tOPT_ALIAS(0, \"recursive\", \"recurse-submodules\"),\n+\tOPT_HIDDEN_ALIAS(0, \"recursive\", \"recurse-submodules\"),\n \tOPT_INTEGER('j', \"jobs\", &max_jobs,\n \t\t    N_(\"number of submodules cloned in parallel\")),\n \tOPT_STRING(0, \"template\", &option_template, N_(\"template-directory\"),\ndiff --git c/parse-options.c w/parse-options.c\nindex 2abff136a1..46af4eacdf 100644\n--- c/parse-options.c\n+++ w/parse-options.c\n@@ -653,6 +653,7 @@ static struct option *preprocess_options(struct parse_opt_ctx_t *ctx,\n \t\tint short_name;\n \t\tconst char *long_name;\n \t\tconst char *source;\n+\t\tint flags;\n \t\tstruct strbuf help = STRBUF_INIT;\n \t\tint j;\n \n@@ -662,6 +663,7 @@ static struct option *preprocess_options(struct parse_opt_ctx_t *ctx,\n \t\tshort_name = newopt[i].short_name;\n \t\tlong_name = newopt[i].long_name;\n \t\tsource = newopt[i].value;\n+\t\tflags = newopt[i].flags;\n \n \t\tif (!long_name)\n \t\t\tBUG(\"An alias must have long option name\");\n@@ -680,7 +682,7 @@ static struct option *preprocess_options(struct parse_opt_ctx_t *ctx,\n \t\t\tnewopt[i].short_name = short_name;\n \t\t\tnewopt[i].long_name = long_name;\n \t\t\tnewopt[i].help = strbuf_detach(&help, NULL);\n-\t\t\tnewopt[i].flags |= PARSE_OPT_FROM_ALIAS;\n+\t\t\tnewopt[i].flags |= PARSE_OPT_FROM_ALIAS | flags;\n \t\t\tbreak;\n \t\t}\n \ndiff --git c/parse-options.h w/parse-options.h\nindex a845a9d952..8ba72c7916 100644\n--- c/parse-options.h\n+++ w/parse-options.h\n@@ -201,6 +201,9 @@ struct option {\n #define OPT_ALIAS(s, l, source_long_name) \\\n \t{ OPTION_ALIAS, (s), (l), (source_long_name) }\n \n+#define OPT_HIDDEN_ALIAS(s, l, source_long_name)\t\t\\\n+\t{ OPTION_ALIAS, (s), (l), (source_long_name), NULL, NULL, PARSE_OPT_HIDDEN }\n+\n /*\n  * parse_options() will filter out the processed options and leave the\n  * non-option arguments in argv[]. argv0 is assumed program name and\ndiff --git c/t/helper/test-parse-options.c w/t/helper/test-parse-options.c\nindex 2051ce57db..86c3eb1a29 100644\n--- c/t/helper/test-parse-options.c\n+++ w/t/helper/test-parse-options.c\n@@ -154,6 +154,7 @@ int cmd__parse_options(int argc, const char **argv)\n \t\tOPT_GROUP(\"Alias\"),\n \t\tOPT_STRING('A', \"alias-source\", &string, \"string\", \"get a string\"),\n \t\tOPT_ALIAS('Z', \"alias-target\", \"alias-source\"),\n+\t\tOPT_HIDDEN_ALIAS(0, \"hidden-alias\", \"alias-source\"),\n \t\tOPT_END(),\n \t};\n \tint i;\ndiff --git c/t/t0040-parse-options.sh w/t/t0040-parse-options.sh\nindex ad4746d899..4d31367b07 100755\n--- c/t/t0040-parse-options.sh\n+++ w/t/t0040-parse-options.sh\n@@ -7,7 +7,7 @@ test_description='our own option parser'\n \n . ./test-lib.sh\n \n-cat >expect <<\\EOF\n+cat >help-all.in <<\\EOF\n usage: test-tool parse-options <options>\n \n     A helper function for the parse-options API.\n@@ -34,6 +34,7 @@ String options\n     --string2 <str>       get another string\n     --st <st>             get another string (pervert ordering)\n     -o <str>              get another string\n+#    --obsolete            no-op (backward compatibility)\n     --list <str>          add str to list\n \n Magic arguments\n@@ -55,10 +56,20 @@ Alias\n                           get a string\n     -Z, --alias-target <string>\n                           alias of --alias-source\n+#    --hidden-alias <string>\n+#                          alias of --alias-source\n \n EOF\n \n+test_expect_success 'hidden alias in test help' '\n+\tsed -e \"s/^#//\" help-all.in >expect &&\n+\ttest_must_fail test-tool parse-options --help-all >output 2>output.err && \n+\ttest_must_be_empty output.err &&\n+\ttest_cmp expect output\n+'\n+\n test_expect_success 'test help' '\n+\tsed -e \"/^#/d\" help-all.in >expect &&\n \ttest_must_fail test-tool parse-options -h >output 2>output.err &&\n \ttest_must_be_empty output.err &&\n \ttest_cmp expect output\n"}]}