{"thread":{"id":"54948","subject":"New orphan worktree?","startedAt":"2021-01-06T16:17:50Z","lastAt":"2021-02-23T18:15:11Z","messageCount":22,"participants":["Stefan Monnier","Jim Hill","Elijah Newren","Eric Sunshine","Junio C Hamano","Ævar Arnfjörð Bjarmason"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"413588","messageId":"jwvwnwqrqwd.fsf-monnier+gmane.comp.version-control.git@gnu.org","threadId":"54948","inReplyTo":null,"subject":"New orphan worktree?","fromName":"Stefan Monnier","fromEmail":"monnier@iro.umontreal.ca","sentAt":"2021-01-06T16:17:02Z","receivedAt":"2021-01-06T16:17:50Z","isPatch":false,"sender":{"key":"monnier@iro.umontreal.ca","avatar":null},"body":"I use worktrees extensively (and rarely use `git checkout`).\n\nWhen I need to create a new orphan branch with a new matching worktree\n(or submodule), I find it is quite cumbersome.  I basically have\nto do something like:\n\n    git worktree add -b dummy foo\n    cd foo\n    git checkout --orphan newbranch\n    git rm -rf .\n    git branch -D dummy\n\nI wish I could just do something like:\n\n    git worktree add --orphan foo newbranch\n\ninstead,\n\n\n        Stefan\n\n"},{"id":"413591","messageId":"CAEE75_1fnvzOid-xfNOtd0eZfh_y8QizfLGAP_ceOeTQdJy2tg@mail.gmail.com","threadId":"54948","inReplyTo":"jwvwnwqrqwd.fsf-monnier+gmane.comp.version-control.git@gnu.org","subject":"Re: New orphan worktree?","fromName":"Jim Hill","fromEmail":"gjthill@gmail.com","sentAt":"2021-01-06T17:00:49Z","receivedAt":"2021-01-06T17:02:01Z","isPatch":false,"sender":{"key":"gjthill@gmail.com","avatar":"https://avatars.githubusercontent.com/u/80352?v=4"},"body":"On Wed, Jan 6, 2021 at 8:18 AM Stefan Monnier <monnier@iro.umontreal.ca> wrote:\n> create a new orphan branch with a new matching worktree\n\nThere's a much shorter sequence\n\n    git worktree add -b new new $(git commit-tree `git mktree <&-` <&-)\n    rm .git/refs/heads/new\n"},{"id":"413597","messageId":"CABPp-BE1QXA0ohB9D-tqKpzDTok0BMsGQjotmcqMxfs9AL5noA@mail.gmail.com","threadId":"54948","inReplyTo":"jwvwnwqrqwd.fsf-monnier+gmane.comp.version-control.git@gnu.org","subject":"Re: New orphan worktree?","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2021-01-06T19:40:25Z","receivedAt":"2021-01-06T19:41:19Z","isPatch":false,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Wed, Jan 6, 2021 at 8:21 AM Stefan Monnier <monnier@iro.umontreal.ca> wrote:\n>\n> I use worktrees extensively (and rarely use `git checkout`).\n>\n> When I need to create a new orphan branch with a new matching worktree\n> (or submodule), I find it is quite cumbersome.  I basically have\n> to do something like:\n>\n>     git worktree add -b dummy foo\n>     cd foo\n\n>     git checkout --orphan newbranch\n>     git rm -rf .\n\nSidenote:\n\nYeah, checkout --orphan is broken.  You should use switch --orphan,\nwhich doesn't require the extra 'git rm -rf .' step.  That bit is\ndefinitely cumbersome.\n\n>     git branch -D dummy\n>\n> I wish I could just do something like:\n>\n>     git worktree add --orphan foo newbranch\n\nI think you mean\n    git worktree add --orphan newbranch foo\n    cd foo\n\nBecause (a) the option to --orphan is the name of the new branch, and\n(b) you need the cd to be equivalent to the first sequence of\ncommands.\n\nOut of curiosity, why are you frequently creating orphan branches?\nSuch an option would drop the number of commands you need to run from\nfour down to two, but I'm surprised this would come up enough to\nmatter enough to do much more than create a personal git alias for it.\n"},{"id":"413598","messageId":"CABPp-BHzPkZu=s=ssmcW=jxg3bOmbL2CkbiQn6N7-Dor8H0BaA@mail.gmail.com","threadId":"54948","inReplyTo":"CAEE75_1fnvzOid-xfNOtd0eZfh_y8QizfLGAP_ceOeTQdJy2tg@mail.gmail.com","subject":"Re: New orphan worktree?","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2021-01-06T19:48:27Z","receivedAt":"2021-01-06T19:49:21Z","isPatch":false,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Wed, Jan 6, 2021 at 9:05 AM Jim Hill <gjthill@gmail.com> wrote:\n>\n> On Wed, Jan 6, 2021 at 8:18 AM Stefan Monnier <monnier@iro.umontreal.ca> wrote:\n> > create a new orphan branch with a new matching worktree\n>\n> There's a much shorter sequence\n>\n>     git worktree add -b new new $(git commit-tree `git mktree <&-` <&-)\n>     rm .git/refs/heads/new\n\nThe rm command presumes the file-backend for refs.  That might not\nwork in the future with reftable.\n"},{"id":"413599","messageId":"CAPig+cRzXd+zd+xVisaW+HToSaGzAE28acGmxwRxNU4bczHXbw@mail.gmail.com","threadId":"54948","inReplyTo":"CABPp-BE1QXA0ohB9D-tqKpzDTok0BMsGQjotmcqMxfs9AL5noA@mail.gmail.com","subject":"Re: New orphan worktree?","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2021-01-06T20:01:16Z","receivedAt":"2021-01-06T20:02:11Z","isPatch":false,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Wed, Jan 6, 2021 at 2:41 PM Elijah Newren <newren@gmail.com> wrote:\n> On Wed, Jan 6, 2021 at 8:21 AM Stefan Monnier <monnier@iro.umontreal.ca> wrote:\n> > I wish I could just do something like:\n> >\n> >     git worktree add --orphan foo newbranch\n>\n> Out of curiosity, why are you frequently creating orphan branches?\n> Such an option would drop the number of commands you need to run from\n> four down to two, but I'm surprised this would come up enough to\n> matter enough to do much more than create a personal git alias for it.\n\nI'm also curious about a use-case in which orphaned branches are used\nso frequently.\n\nNevertheless, I'm not at all opposed to seeing an --orphan option\nadded to `git worktree add`. In fact, --orphan has been on the\nradar[1] from the very beginning. Although the original implementation\nof `git worktree add` mimicked a small set of options from\ngit-checkout, the plan all along was to mimic additional options from\ngit-checkout as demand for them arose, and several such options have\nalready been added.\n\n> Yeah, checkout --orphan is broken.  You should use switch --orphan,\n> which doesn't require the extra 'git rm -rf .' step.  That bit is\n> definitely cumbersome.\n\nYep, when/if --orphan is added to `git worktree add`, it should mimic\nthe behavior of --orphan in git-switch rather than git-checkout.\n\nPatches are welcome.\n\n[1]: https://lore.kernel.org/git/CAPig+cQiJnrnz4jsGdT0=8kYogWfsNkjq5WQCGC4Zk6res5mtg@mail.gmail.com/\n"},{"id":"413600","messageId":"CAEE75_3qtAwhVgHjvch4gMaF_7MTcRf=YzomeTYfpG6H=FB-5A@mail.gmail.com","threadId":"54948","inReplyTo":"CABPp-BHzPkZu=s=ssmcW=jxg3bOmbL2CkbiQn6N7-Dor8H0BaA@mail.gmail.com","subject":"Re: New orphan worktree?","fromName":"Jim Hill","fromEmail":"gjthill@gmail.com","sentAt":"2021-01-06T20:33:22Z","receivedAt":"2021-01-06T20:34:25Z","isPatch":false,"sender":{"key":"gjthill@gmail.com","avatar":"https://avatars.githubusercontent.com/u/80352?v=4"},"body":"On Wed, Jan 6, 2021 at 11:48 AM Elijah Newren <newren@gmail.com> wrote:\n\n> The rm command presumes the file-backend for refs.  That might not\n> work in the future with reftable.\n\nTrue dat. The pure way is\n\n    git worktree add newbranch $(git commit-tree `git mktree <&-` <&-)\n    git -C newbranch symbolic-ref HEAD refs/heads/newbranch\n"},{"id":"413608","messageId":"xmqq1rexrbz1.fsf@gitster.c.googlers.com","threadId":"54948","inReplyTo":"CABPp-BE1QXA0ohB9D-tqKpzDTok0BMsGQjotmcqMxfs9AL5noA@mail.gmail.com","subject":"Re: New orphan worktree?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-01-06T21:29:06Z","receivedAt":"2021-01-06T21:29:50Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Elijah Newren <newren@gmail.com> writes:\n\n> Sidenote:\n>\n> Yeah, checkout --orphan is broken.  You should use switch --orphan,\n> which doesn't require the extra 'git rm -rf .' step.  That bit is\n> definitely cumbersome.\n\nI doubt \"broken\" is an appropriate word.  \n\nIt only targets a different workflow that wanted to start an\nunrelated history with a known contents.\n\n> Out of curiosity, why are you frequently creating orphan branches?\n> Such an option would drop the number of commands you need to run from\n> four down to two, but I'm surprised this would come up enough to\n> matter enough to do much more than create a personal git alias for it.\n\nYes, a need to have multiple unrelated line of histories in a single\nrepository may not be there, even though a desire to do so might\nexist.  What is done with these unrelated histories that record\nunrelated contents [*1*]?\n\nFor example, the answer might turn out to be \"our hosting provider\ncharge by number of publishing repositories, so I keep only one\nrepository there and push unrelated stuff into it, on different\nbranches\", and such a use case to work around external limitation\ncan be more naturally solved by having separate repositories on the\nproducing side, and pushing into different branches in that single\npublishing repository, which does not require any \"--orphan\" at all.\n\n\n[Footnote]\n\n*1* if the trees in these unrelated histories record related\n    contents, the user wouldn't be doing \"git rm -f .\" in the first\n    place and \"checkout --orphan\" would be more appropriate than\n    \"switch --orphan\".\n"},{"id":"413611","messageId":"CAEE75_0e4_m_7hQXycVK1f=4LOb82U2DYveAvcF2XKKNgmfpNw@mail.gmail.com","threadId":"54948","inReplyTo":"xmqq1rexrbz1.fsf@gitster.c.googlers.com","subject":"Re: New orphan worktree?","fromName":"Jim Hill","fromEmail":"gjthill@gmail.com","sentAt":"2021-01-06T22:01:13Z","receivedAt":"2021-01-06T22:02:06Z","isPatch":false,"sender":{"key":"gjthill@gmail.com","avatar":"https://avatars.githubusercontent.com/u/80352?v=4"},"body":"On Wed, Jan 6, 2021 at 1:32 PM Junio C Hamano <gitster@pobox.com> wrote:\n> a need to have multiple unrelated line of histories in a single\n> repository may not be there, even though a desire to do so might\n> exist.  What is done with these unrelated histories that record\n> unrelated contents [*1*]?\n\nGit itself is an example of other reasons for carrying disjoint dags as a\nset of related histories.\n\nAlso, I've taken to carrying submodule histories in the main repo, the setup is\nvery easy, just a submodule init and worktree add. I think the pair of flows\nshows disjoint dags can be on a spectrum of relatedness.\n"},{"id":"413612","messageId":"jwvv9c9rakf.fsf-monnier+Inbox@gnu.org","threadId":"54948","inReplyTo":"xmqq1rexrbz1.fsf@gitster.c.googlers.com","subject":"Re: New orphan worktree?","fromName":"Stefan Monnier","fromEmail":"monnier@iro.umontreal.ca","sentAt":"2021-01-06T22:01:52Z","receivedAt":"2021-01-06T22:02:52Z","isPatch":false,"sender":{"key":"monnier@iro.umontreal.ca","avatar":null},"body":"> Yes, a need to have multiple unrelated line of histories in a single\n> repository may not be there, even though a desire to do so might\n> exist.  What is done with these unrelated histories that record\n> unrelated contents [*1*]?\n\nFor the record, my use cases are basically subtrees of the project\nstashed in submodules instead of being kept as subdirectories in the\nmain branch (the purpose being to be able to easily share&sync those\nsubtrees between different projects).\n\n\n        Stefan\n\n"},{"id":"413613","messageId":"xmqqr1mxpv8n.fsf@gitster.c.googlers.com","threadId":"54948","inReplyTo":"CAEE75_0e4_m_7hQXycVK1f=4LOb82U2DYveAvcF2XKKNgmfpNw@mail.gmail.com","subject":"Re: New orphan worktree?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-01-06T22:15:52Z","receivedAt":"2021-01-06T22:16:40Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jim Hill <gjthill@gmail.com> writes:\n\n> On Wed, Jan 6, 2021 at 1:32 PM Junio C Hamano <gitster@pobox.com> wrote:\n>> a need to have multiple unrelated line of histories in a single\n>> repository may not be there, even though a desire to do so might\n>> exist.  What is done with these unrelated histories that record\n>> unrelated contents [*1*]?\n>\n> Git itself is an example of other reasons for carrying disjoint dags as a\n> set of related histories.\n\nThanks, it is a good example why a repository may want to have\nunrelated histories stored in it, but it is not a good example to\nsupport the use of the \"--orphan\" option.\n\nHistories for gitk, git-gui and todo come from different local\nrepositories.  gitk and git-gui histories come to my (local)\nrepository by pulling from separate repositories that have only\nunrelated histories, and the todo branch does not exist even in my\nlocal repository working on git codebase.\n\nYou see git, gitk, git-gui histories in a single repository but\nthese independent histories originate from and worked on each\nseparate repositories.  You see the todo history in the same\nrepository as these other three lines, only because I used to have\njust a single publishing repository I can push into at kernel.org.\n\nAnd none of the management above has any need to use \"--orphan\".\n\n\"gitk\" and \"git-gui\" are worked in their own repositories, that do\nnot even have any commits of \"git\" history.  \"todo\" is worked in its\nown repository, that do not even have any commits of \"git\" history.\nThe former two are pulled into my \"git\" repository and pushed out to\nthe public repositories.  The last one is pushed directly from my\n\"git-todo\" repository and pushed out.\n"},{"id":"413616","messageId":"CAEE75_1o+A13+8SBeF9S0SN0ZaYhgK3D1bhbfWNWZWsj9jOXrw@mail.gmail.com","threadId":"54948","inReplyTo":"xmqqr1mxpv8n.fsf@gitster.c.googlers.com","subject":"Re: New orphan worktree?","fromName":"Jim Hill","fromEmail":"gjthill@gmail.com","sentAt":"2021-01-06T22:25:20Z","receivedAt":"2021-01-06T22:26:29Z","isPatch":false,"sender":{"key":"gjthill@gmail.com","avatar":"https://avatars.githubusercontent.com/u/80352?v=4"},"body":"On Wed, Jan 6, 2021 at 2:15 PM Junio C Hamano <gitster@pobox.com> wrote:\n> not a good example to support the use of the \"--orphan\" option.\n\nI agree with that part, slathering infrastructure and abstractions on\noneliners (okay, twoliners) is suspect in my book. worktree add,\nsymoblic ref (really, no need to get lowlevel there, checkout --orphan\ndoes it) done. Tag an empty commit and the sequence gets closer\nto a legit oneliner\n\n    git worktree add foo empty; git -C foo checkout --orphan newbranch\n"},{"id":"413619","messageId":"jwvk0spr8ta.fsf-monnier+Inbox@gnu.org","threadId":"54948","inReplyTo":"CAEE75_1o+A13+8SBeF9S0SN0ZaYhgK3D1bhbfWNWZWsj9jOXrw@mail.gmail.com","subject":"Re: New orphan worktree?","fromName":"Stefan Monnier","fromEmail":"monnier@iro.umontreal.ca","sentAt":"2021-01-06T22:56:59Z","receivedAt":"2021-01-06T22:57:44Z","isPatch":false,"sender":{"key":"monnier@iro.umontreal.ca","avatar":null},"body":">> not a good example to support the use of the \"--orphan\" option.\n> I agree with that part, slathering infrastructure and abstractions on\n> oneliners (okay, twoliners) is suspect in my book. worktree add,\n> symoblic ref (really, no need to get lowlevel there, checkout --orphan\n> does it) done. Tag an empty commit and the sequence gets closer\n> to a legit oneliner\n>\n>     git worktree add foo empty; git -C foo checkout --orphan newbranch\n\nFWIW, I'd be quite happy to have an ad-hoc revision which represents\n\"the (currently non-existing) ancestor shared by all branches\".\nAssuming we'd call it \"ORPHAN\" (other names that come to mind would be\n\"ROOT\", \"GOD\", \"∅\", \"BIGBANG\", ...), then\n\n    git checkout --orphan newbranch\n\nwould become\n\n    git checkout -b newbranch ORPHAN\n\nand then I'd also be able to say\n\n    got worktree add -b newbranch foo ORPHAN\n\nI've had occasional use for such a pseudo-revision in other\ncircumstances as well and I think I'd find it easier to remember how to\nuse this then the `--orphan` option.\n\n\n        Stefan\n\n"},{"id":"417265","messageId":"87wnv688u4.fsf@evledraar.gmail.com","threadId":"54948","inReplyTo":"CAPig+cRzXd+zd+xVisaW+HToSaGzAE28acGmxwRxNU4bczHXbw@mail.gmail.com","subject":"Re: New orphan worktree?","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-02-18T01:26:27Z","receivedAt":"2021-02-18T01:27:32Z","isPatch":false,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Wed, Jan 06 2021, Eric Sunshine wrote:\n\n> On Wed, Jan 6, 2021 at 2:41 PM Elijah Newren <newren@gmail.com> wrote:\n>> On Wed, Jan 6, 2021 at 8:21 AM Stefan Monnier <monnier@iro.umontreal.ca> wrote:\n>> > I wish I could just do something like:\n>> >\n>> >     git worktree add --orphan foo newbranch\n>>\n>> Out of curiosity, why are you frequently creating orphan branches?\n>> Such an option would drop the number of commands you need to run from\n>> four down to two, but I'm surprised this would come up enough to\n>> matter enough to do much more than create a personal git alias for it.\n>\n> I'm also curious about a use-case in which orphaned branches are used\n> so frequently.\n>\n> Nevertheless, I'm not at all opposed to seeing an --orphan option\n> added to `git worktree add`. In fact, --orphan has been on the\n> radar[1] from the very beginning. Although the original implementation\n> of `git worktree add` mimicked a small set of options from\n> git-checkout, the plan all along was to mimic additional options from\n> git-checkout as demand for them arose, and several such options have\n> already been added.\n>\n>> Yeah, checkout --orphan is broken.  You should use switch --orphan,\n>> which doesn't require the extra 'git rm -rf .' step.  That bit is\n>> definitely cumbersome.\n>\n> Yep, when/if --orphan is added to `git worktree add`, it should mimic\n> the behavior of --orphan in git-switch rather than git-checkout.\n\nHow would a mode for \"worktree add --orphan\" that mimics checkout rather\nthan switch even look like? The \"checkout --orphan\" special-case is\nbecause we retain the index, so you need to \"git rm -rf .\".\n\nBut with worktrees we always get a new index, so AFAICT the only way to\nmake it work like \"checkout\" would be to have it be the only mode that\ncopies over the current worktree's index.\n\nIn any case I implemented a rough version of this today, and it uses the\n\"switch\" semantics. I only discovered this ML thread afterwards.\n\nIt's surely full of bugs, and needs test work (see all the BUG(...)),\nbut if someone's interested in taking it further all it should need is\nsome more tests & dealing with the edge cases of incompatible options\netc. It's Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>.\n\nI'd tried crafting as simple worktree manually, and discovered that I\ncould get worktree_add() to create it rather easily by jumping past some\nof the \"commit exists?\" checks.\n\ndiff --git a/builtin/worktree.c b/builtin/worktree.c\nindex 1cd5c2016e3..eeecb6da380 100644\n--- a/builtin/worktree.c\n+++ b/builtin/worktree.c\n@@ -31,6 +31,7 @@ struct add_opts {\n \tint quiet;\n \tint checkout;\n \tint keep_locked;\n+\tint orphan;\n };\n \n static int show_only;\n@@ -266,8 +267,12 @@ static int add_worktree(const char *path, const char *refname,\n \t\t\tdie_if_checked_out(symref.buf, 0);\n \t}\n \tcommit = lookup_commit_reference_by_name(refname);\n-\tif (!commit)\n+\tif (opts->orphan) {\n+\t\tif (commit)\n+\t\t\tdie(_(\"valid reference: %s\"), refname);\n+\t} else if  (!commit) {\n \t\tdie(_(\"invalid reference: %s\"), refname);\n+\t}\n \n \tname = worktree_basename(path, &len);\n \tstrbuf_add(&sb, name, path + len - name);\n@@ -340,7 +345,7 @@ static int add_worktree(const char *path, const char *refname,\n \tstrvec_pushf(&child_env, \"%s=%s\", GIT_WORK_TREE_ENVIRONMENT, path);\n \tcp.git_cmd = 1;\n \n-\tif (!is_branch)\n+\tif (!opts->orphan && !is_branch)\n \t\tstrvec_pushl(&cp.args, \"update-ref\", \"HEAD\",\n \t\t\t     oid_to_hex(&commit->object.oid), NULL);\n \telse {\n@@ -414,18 +419,28 @@ static int add_worktree(const char *path, const char *refname,\n static void print_preparing_worktree_line(int detach,\n \t\t\t\t\t  const char *branch,\n \t\t\t\t\t  const char *new_branch,\n-\t\t\t\t\t  int force_new_branch)\n+\t\t\t\t\t  int force_new_branch,\n+\t\t\t\t\t  int orphan)\n {\n \tif (force_new_branch) {\n \t\tstruct commit *commit = lookup_commit_reference_by_name(new_branch);\n-\t\tif (!commit)\n-\t\t\tprintf_ln(_(\"Preparing worktree (new branch '%s')\"), new_branch);\n-\t\telse\n+\t\tif (!commit) {\n+\t\t\tif (orphan)\n+\t\t\t\tprintf_ln(_(\"Preparing worktree (new orphan branch '%s')\"), new_branch);\n+\t\t\telse\n+\t\t\t\tprintf_ln(_(\"Preparing worktree (new branch '%s')\"), new_branch);\n+\t\t} else {\n+\t\t\tif (orphan)\n+\t\t\t\tBUG(\"TODO\");\n \t\t\tprintf_ln(_(\"Preparing worktree (resetting branch '%s'; was at %s)\"),\n \t\t\t\t  new_branch,\n \t\t\t\t  find_unique_abbrev(&commit->object.oid, DEFAULT_ABBREV));\n+\t\t}\n \t} else if (new_branch) {\n-\t\tprintf_ln(_(\"Preparing worktree (new branch '%s')\"), new_branch);\n+\t\tif (orphan)\n+\t\t\tprintf_ln(_(\"Preparing worktree (new orphan branch '%s')\"), new_branch);\n+\t\telse\n+\t\t\tprintf_ln(_(\"Preparing worktree (new branch '%s')\"), new_branch);\n \t} else {\n \t\tstruct strbuf s = STRBUF_INIT;\n \t\tif (!detach && !strbuf_check_branch_ref(&s, branch) &&\n@@ -486,6 +501,7 @@ static int add(int ac, const char **av, const char *prefix)\n \t\tOPT_BOOL('d', \"detach\", &opts.detach, N_(\"detach HEAD at named commit\")),\n \t\tOPT_BOOL(0, \"checkout\", &opts.checkout, N_(\"populate the new working tree\")),\n \t\tOPT_BOOL(0, \"lock\", &opts.keep_locked, N_(\"keep the new working tree locked\")),\n+\t\tOPT_BOOL(0, \"orphan\", &opts.orphan, N_(\"new unparented branch\")),\n \t\tOPT__QUIET(&opts.quiet, N_(\"suppress progress reporting\")),\n \t\tOPT_PASSTHRU(0, \"track\", &opt_track, NULL,\n \t\t\t     N_(\"set up tracking mode (see git-branch(1))\"),\n@@ -505,6 +521,8 @@ static int add(int ac, const char **av, const char *prefix)\n \n \tpath = prefix_filename(prefix, av[0]);\n \tbranch = ac < 2 ? \"HEAD\" : av[1];\n+\tif (opts.orphan)\n+\t\tbranch = \"\";\n \n \tif (!strcmp(branch, \"-\"))\n \t\tbranch = \"@{-1}\";\n@@ -542,9 +560,11 @@ static int add(int ac, const char **av, const char *prefix)\n \t\t}\n \t}\n \tif (!opts.quiet)\n-\t\tprint_preparing_worktree_line(opts.detach, branch, new_branch, !!new_branch_force);\n+\t\tprint_preparing_worktree_line(opts.detach, branch, new_branch, !!new_branch_force, opts.orphan);\n \n-\tif (new_branch) {\n+\tif (opts.orphan && new_branch) {\n+\t\tbranch = new_branch;\n+\t} else if (new_branch) {\n \t\tstruct child_process cp = CHILD_PROCESS_INIT;\n \t\tcp.git_cmd = 1;\n \t\tstrvec_push(&cp.args, \"branch\");\n@@ -560,6 +580,8 @@ static int add(int ac, const char **av, const char *prefix)\n \t\t\treturn -1;\n \t\tbranch = new_branch;\n \t} else if (opt_track) {\n+\t\tif (opts.orphan)\n+\t\t\tBUG(\"TODO\");\n \t\tdie(_(\"--[no-]track can only be used if a new branch is created\"));\n \t}\n \ndiff --git a/t/t2400-worktree-add.sh b/t/t2400-worktree-add.sh\nindex 96dfca15542..e52aa6a11a2 100755\n--- a/t/t2400-worktree-add.sh\n+++ b/t/t2400-worktree-add.sh\n@@ -66,6 +66,19 @@ test_expect_success '\"add\" worktree' '\n \t)\n '\n \n+test_expect_success '\"add\" worktree orphan branch' '\n+\tgit worktree add --orphan -b orphan here-orphan &&\n+\techo refs/heads/orphan >expect &&\n+\tgit -C here-orphan symbolic-ref HEAD >actual &&\n+\ttest_cmp expect actual &&\n+\ttest_must_fail git -C here-orphan rev-parse --verify HEAD &&\n+\ttest_must_fail git -C here-orphan log &&\n+\n+\techo here-orphan/.git >expected &&\n+\tfind here-orphan -type f >actual &&\n+\ttest_cmp expected actual\n+'\n+\n test_expect_success '\"add\" worktree with lock' '\n \tgit rev-parse HEAD >expect &&\n \tgit worktree add --detach --lock here-with-lock main &&\n\n"},{"id":"417458","messageId":"CAPig+cQ9oqMWjBkyRt-SQFuyfAGkMu1J-U6ZCCJqeL0a_3ynkw@mail.gmail.com","threadId":"54948","inReplyTo":"87wnv688u4.fsf@evledraar.gmail.com","subject":"Re: New orphan worktree?","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2021-02-21T19:55:42Z","receivedAt":"2021-02-21T19:56:52Z","isPatch":false,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Wed, Feb 17, 2021 at 8:26 PM Ævar Arnfjörð Bjarmason\n<avarab@gmail.com> wrote:\n> On Wed, Jan 06 2021, Eric Sunshine wrote:\n> > Yep, when/if --orphan is added to `git worktree add`, it should mimic\n> > the behavior of --orphan in git-switch rather than git-checkout.\n>\n> How would a mode for \"worktree add --orphan\" that mimics checkout rather\n> than switch even look like? The \"checkout --orphan\" special-case is\n> because we retain the index, so you need to \"git rm -rf .\".\n>\n> But with worktrees we always get a new index, so AFAICT the only way to\n> make it work like \"checkout\" would be to have it be the only mode that\n> copies over the current worktree's index.\n\nI hadn't actually put any thought into it aside from (1) `--orphan`\nbeing a likely candidate for `git worktree add`, and (2) my uses of\norphan branches always involved `git checkout --orphan && git rm -rf\n.`. I never got as far as thinking about the actual implementation.\n\n> In any case I implemented a rough version of this today, and it uses the\n> \"switch\" semantics. I only discovered this ML thread afterwards.\n>\n> It's surely full of bugs, and needs test work (see all the BUG(...)),\n> but if someone's interested in taking it further all it should need is\n> some more tests & dealing with the edge cases of incompatible options\n> etc. It's Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>.\n\nThanks. This looks like a good start.\n\n> +test_expect_success '\"add\" worktree orphan branch' '\n> +       git worktree add --orphan -b orphan here-orphan &&\n\nRather than making --orphan a boolean flag, we'd probably want to\nmirror the behavior of the other commands and have <branch> be an\nargument consumed by --orphan:\n\n    git worktree add --orphan <branch> <path>\n\nThat would make --orphan, -b, and -B mutually exclusive, much like\nthey are for git-checkout, and much like -c, -C, and --orphan are\nmutually exclusive for git-switch.\n"},{"id":"417466","messageId":"87ft1o8mi0.fsf@evledraar.gmail.com","threadId":"54948","inReplyTo":"CAPig+cQ9oqMWjBkyRt-SQFuyfAGkMu1J-U6ZCCJqeL0a_3ynkw@mail.gmail.com","subject":"Re: New orphan worktree?","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-02-22T09:44:55Z","receivedAt":"2021-02-22T09:46:48Z","isPatch":false,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Sun, Feb 21 2021, Eric Sunshine wrote:\n\n> On Wed, Feb 17, 2021 at 8:26 PM Ævar Arnfjörð Bjarmason\n> <avarab@gmail.com> wrote:\n>> On Wed, Jan 06 2021, Eric Sunshine wrote:\n>> > Yep, when/if --orphan is added to `git worktree add`, it should mimic\n>> > the behavior of --orphan in git-switch rather than git-checkout.\n>>\n>> How would a mode for \"worktree add --orphan\" that mimics checkout rather\n>> than switch even look like? The \"checkout --orphan\" special-case is\n>> because we retain the index, so you need to \"git rm -rf .\".\n>>\n>> But with worktrees we always get a new index, so AFAICT the only way to\n>> make it work like \"checkout\" would be to have it be the only mode that\n>> copies over the current worktree's index.\n>\n> I hadn't actually put any thought into it aside from (1) `--orphan`\n> being a likely candidate for `git worktree add`, and (2) my uses of\n> orphan branches always involved `git checkout --orphan && git rm -rf\n> .`. I never got as far as thinking about the actual implementation.\n>\n>> In any case I implemented a rough version of this today, and it uses the\n>> \"switch\" semantics. I only discovered this ML thread afterwards.\n>>\n>> It's surely full of bugs, and needs test work (see all the BUG(...)),\n>> but if someone's interested in taking it further all it should need is\n>> some more tests & dealing with the edge cases of incompatible options\n>> etc. It's Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>.\n>\n> Thanks. This looks like a good start.\n>\n>> +test_expect_success '\"add\" worktree orphan branch' '\n>> +       git worktree add --orphan -b orphan here-orphan &&\n>\n> Rather than making --orphan a boolean flag, we'd probably want to\n> mirror the behavior of the other commands and have <branch> be an\n> argument consumed by --orphan:\n>\n>     git worktree add --orphan <branch> <path>\n>\n> That would make --orphan, -b, and -B mutually exclusive, much like\n> they are for git-checkout, and much like -c, -C, and --orphan are\n> mutually exclusive for git-switch.\n\nI see now (but didn't before, I haven't really used \"switch\" before)\nthat that's how it works.\n\nBut that doesn't seem to make much sense as a UI, maybe I'm missing\nsomething but how do you:\n\n    git switch --orphan existing-branch\n\nJust like you can:\n\n    git switch -C existing-branch <start-point>\n\nIt's actually this exact use-case that prompted me to write the --orphan\npatch. I wanted to create a \"meta\" orphan branch in my git.git, but had\nan existing local \"meta\" (from Jeff King) that I'd happened to have\nchecked out long ago which I first needed to \"git branch -D\".\n\nWouldn't it make more sense for a feature like this & back-compat to\nstart with switch's \"--orphan\" implying \"-c\", but you could also supply\n\"--orphan -C\" instead? And in worktree have -b and -B work like they do\nfor other branches.\n\n"},{"id":"417500","messageId":"CAPig+cSkL+5otKUWwm=CLaRR+j71wW61U7LWtmuUHO+7bZaY_g@mail.gmail.com","threadId":"54948","inReplyTo":"87ft1o8mi0.fsf@evledraar.gmail.com","subject":"Re: New orphan worktree?","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2021-02-22T23:06:32Z","receivedAt":"2021-02-22T23:07:28Z","isPatch":false,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Mon, Feb 22, 2021 at 4:45 AM Ævar Arnfjörð Bjarmason\n<avarab@gmail.com> wrote:\n> On Sun, Feb 21 2021, Eric Sunshine wrote:\n> > Rather than making --orphan a boolean flag, we'd probably want to\n> > mirror the behavior of the other commands and have <branch> be an\n> > argument consumed by --orphan:\n> >\n> >     git worktree add --orphan <branch> <path>\n> >\n> > That would make --orphan, -b, and -B mutually exclusive, much like\n> > they are for git-checkout, and much like -c, -C, and --orphan are\n> > mutually exclusive for git-switch.\n>\n> I see now (but didn't before, I haven't really used \"switch\" before)\n> that that's how it works.\n>\n> But that doesn't seem to make much sense as a UI, maybe I'm missing\n> something but how do you:\n>\n>     git switch --orphan existing-branch\n>\n> Just like you can:\n>\n>     git switch -C existing-branch <start-point>\n\nWhen responding to your initial email, I noticed this same shortcoming\nof --orphan in both git-branch and git-switch, and assumed that's why\nyou made it a boolean in combination with -b/-B in \"git worktree add\".\nBefore writing that email, I did put a bit of thought into how one\nmight support a \"force\" mode but didn't include my thoughts in the\nmessage.\n\n> It's actually this exact use-case that prompted me to write the --orphan\n> patch. I wanted to create a \"meta\" orphan branch in my git.git, but had\n> an existing local \"meta\" (from Jeff King) that I'd happened to have\n> checked out long ago which I first needed to \"git branch -D\".\n>\n> Wouldn't it make more sense for a feature like this & back-compat to\n> start with switch's \"--orphan\" implying \"-c\", but you could also supply\n> \"--orphan -C\" instead? And in worktree have -b and -B work like they do\n> for other branches.\n\nI'm not sure I follow. In git-switch, --orphan does not imply -c even\nthough --orphan also creates a new branch (thus seems to work similar\nto -c); it is nevertheless mutually-exclusive with -c and -C. The same\ngoes for --orphan in git-branch.\n\nAs far as combining --orphan and -C (or -c), I'm not sure how we would\narrange that using the existing parse_options() mechanism. It seems\ntoo magical and has potential for weird corner cases.\n\nSince git-worktree doesn't yet support --orphan, we certainly have\nmore leeway and could go with your proposal of having --orphan be\nboolean and always requiring it to be used in conjunction with -b/-B.\nHowever, I'm quite hesitant to take that approach since it breaks with\nexisting precedent in git-branch and git-switch, in which case\n--orphan takes its own argument (<branch>) and is mutually-exclusive\nwith -b/-B/-c/-C.\n\nWhen I was pondering the issue before writing my original response,\ntwo thoughts came to mind. (1) \"git worktree add --force --orphan\n<branch>\" would be one way to make your case work; (2) given how\ninfrequently --orphan is used, we just punt and require people to\nfirst use \"git branch -D <branch>\" if necessary (which has been the\nstatus-quo for git-branch and git-switch). The latter thought is\nsuperficially tempting, though it doesn't help in automation\nsituations since \"git branch -D <branch>\" errors out if <branch>\ndoesn't exist, so a script would first have to check for existence of\n<branch> before attempting to delete it prior to using \"git worktree\nadd --orphan <branch>\".\n\nSo, I don't have any great answers at this time.\n"},{"id":"417507","messageId":"xmqqmtvv64dp.fsf@gitster.g","threadId":"54948","inReplyTo":"CAPig+cSkL+5otKUWwm=CLaRR+j71wW61U7LWtmuUHO+7bZaY_g@mail.gmail.com","subject":"Re: New orphan worktree?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-02-22T23:59:14Z","receivedAt":"2021-02-23T00:00:12Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Eric Sunshine <sunshine@sunshineco.com> writes:\n\n> When I was pondering the issue before writing my original response,\n> two thoughts came to mind. (1) \"git worktree add --force --orphan\n> <branch>\" would be one way to make your case work; (2) given how\n> infrequently --orphan is used, we just punt and require people to\n> first use \"git branch -D <branch>\" if necessary (which has been the\n> status-quo for git-branch and git-switch).\n\nFWIW, as I personally view that branch -d/-D, checkout -b/-B, and\nswitch -c/-C were all mistakes (they should have been -d, -b and -c\nwith and without --force, respectively), I find the combination of\n\"--force --orphan\" a reasonable way forward.\n"},{"id":"417508","messageId":"87czwr8wou.fsf@evledraar.gmail.com","threadId":"54948","inReplyTo":"CAPig+cSkL+5otKUWwm=CLaRR+j71wW61U7LWtmuUHO+7bZaY_g@mail.gmail.com","subject":"Re: New orphan worktree?","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-02-23T00:17:05Z","receivedAt":"2021-02-23T00:18:00Z","isPatch":false,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Tue, Feb 23 2021, Eric Sunshine wrote:\n\n> On Mon, Feb 22, 2021 at 4:45 AM Ævar Arnfjörð Bjarmason\n> <avarab@gmail.com> wrote:\n>> On Sun, Feb 21 2021, Eric Sunshine wrote:\n>> > Rather than making --orphan a boolean flag, we'd probably want to\n>> > mirror the behavior of the other commands and have <branch> be an\n>> > argument consumed by --orphan:\n>> >\n>> >     git worktree add --orphan <branch> <path>\n>> >\n>> > That would make --orphan, -b, and -B mutually exclusive, much like\n>> > they are for git-checkout, and much like -c, -C, and --orphan are\n>> > mutually exclusive for git-switch.\n>>\n>> I see now (but didn't before, I haven't really used \"switch\" before)\n>> that that's how it works.\n>>\n>> But that doesn't seem to make much sense as a UI, maybe I'm missing\n>> something but how do you:\n>>\n>>     git switch --orphan existing-branch\n>>\n>> Just like you can:\n>>\n>>     git switch -C existing-branch <start-point>\n>\n> When responding to your initial email, I noticed this same shortcoming\n> of --orphan in both git-branch and git-switch, and assumed that's why\n> you made it a boolean in combination with -b/-B in \"git worktree add\".\n> Before writing that email, I did put a bit of thought into how one\n> might support a \"force\" mode but didn't include my thoughts in the\n> message.\n>\n>> It's actually this exact use-case that prompted me to write the --orphan\n>> patch. I wanted to create a \"meta\" orphan branch in my git.git, but had\n>> an existing local \"meta\" (from Jeff King) that I'd happened to have\n>> checked out long ago which I first needed to \"git branch -D\".\n>>\n>> Wouldn't it make more sense for a feature like this & back-compat to\n>> start with switch's \"--orphan\" implying \"-c\", but you could also supply\n>> \"--orphan -C\" instead? And in worktree have -b and -B work like they do\n>> for other branches.\n>\n> I'm not sure I follow. In git-switch, --orphan does not imply -c even\n> though --orphan also creates a new branch (thus seems to work similar\n> to -c); it is nevertheless mutually-exclusive with -c and -C. The same\n> goes for --orphan in git-branch.\n\nI think we're on the same page with regards to what I meant. I.e. I\ndon't see how it makes sense to conflate the type of branch we want\n(orphan or not orphan) with whether we want to clobber that branch or\nnot (switch -c or -C, or worktree -b or -B)\n\n> As far as combining --orphan and -C (or -c), I'm not sure how we would\n> arrange that using the existing parse_options() mechanism. It seems\n> too magical and has potential for weird corner cases.\n\nIsn't it just having --orphan be an OPTION_STRING with\nPARSE_OPT_LASTARG_DEFAULT. I.e. to support:\n\n    git switch -b branch --orphan\n    git switch -B branch --orphan\n    git switch --orphan branch\n\nAnd:\n\n    git worktree add -b branch --orphan\n    git worktree add -B branch --orphan\n\nI didn't test it, just skimmed the code.\n\n> Since git-worktree doesn't yet support --orphan, we certainly have\n> more leeway and could go with your proposal of having --orphan be\n> boolean and always requiring it to be used in conjunction with -b/-B.\n> However, I'm quite hesitant to take that approach since it breaks with\n> existing precedent in git-branch and git-switch, in which case\n> --orphan takes its own argument (<branch>) and is mutually-exclusive\n> with -b/-B/-c/-C.\n\nIn git-branch? Isn't it only git [checkout|switch] that takes --orphan?\n\nBut yeah, I agree that it makes sense for \"worktree add\" to be\nconsistent with \"switch\". I was just wondering if we couldn't fix what\nseems to me to be a small options UI issue while we're at it.\n\n> When I was pondering the issue before writing my original response,\n> two thoughts came to mind. (1) \"git worktree add --force --orphan\n> <branch>\" would be one way to make your case work; (2) given how\n> infrequently --orphan is used, we just punt and require people to\n> first use \"git branch -D <branch>\" if necessary (which has been the\n> status-quo for git-branch and git-switch). The latter thought is\n> superficially tempting, though it doesn't help in automation\n> situations since \"git branch -D <branch>\" errors out if <branch>\n> doesn't exist, so a script would first have to check for existence of\n> <branch> before attempting to delete it prior to using \"git worktree\n> add --orphan <branch>\".\n\nI think not having a -B or -C equivalent at all would be preferrable to\nhaving a --force special-case just to work around the lack of it for\n--orphan.\n"},{"id":"417510","messageId":"CAPig+cQ5aLEzpUwFAkofd86HjJsJnJ-DtRKkrrkF0EdjHnJm4g@mail.gmail.com","threadId":"54948","inReplyTo":"xmqqmtvv64dp.fsf@gitster.g","subject":"Re: New orphan worktree?","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2021-02-23T00:33:38Z","receivedAt":"2021-02-23T00:34:47Z","isPatch":false,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Mon, Feb 22, 2021 at 6:59 PM Junio C Hamano <gitster@pobox.com> wrote:\n> Eric Sunshine <sunshine@sunshineco.com> writes:\n> > When I was pondering the issue before writing my original response,\n> > two thoughts came to mind. (1) \"git worktree add --force --orphan\n> > <branch>\" would be one way to make your case work; (2) given how\n> > infrequently --orphan is used, we just punt and require people to\n> > first use \"git branch -D <branch>\" if necessary (which has been the\n> > status-quo for git-branch and git-switch).\n>\n> FWIW, as I personally view that branch -d/-D, checkout -b/-B, and\n> switch -c/-C were all mistakes (they should have been -d, -b and -c\n> with and without --force, respectively), I find the combination of\n> \"--force --orphan\" a reasonable way forward.\n\nI'm also leaning toward `git worktree add --force --orphan <branch>`\nas a way forward. Indeed, `git worktree add --force -b <branch>` is a\nsensible extension even without --orphan being part of the equation,\nand it's easy to frame -B in documentation as equivalent to `--force\n-b`.\n"},{"id":"417512","messageId":"CAPig+cQxYtw5z_bRQbS6MLgHQM2OTs5oRfpvKSOwZo8GcuwpTg@mail.gmail.com","threadId":"54948","inReplyTo":"87czwr8wou.fsf@evledraar.gmail.com","subject":"Re: New orphan worktree?","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2021-02-23T00:55:28Z","receivedAt":"2021-02-23T00:56:38Z","isPatch":false,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Mon, Feb 22, 2021 at 7:17 PM Ævar Arnfjörð Bjarmason\n<avarab@gmail.com> wrote:\n> On Tue, Feb 23 2021, Eric Sunshine wrote:\n> > I'm not sure I follow. In git-switch, --orphan does not imply -c even\n> > though --orphan also creates a new branch (thus seems to work similar\n> > to -c); it is nevertheless mutually-exclusive with -c and -C. The same\n> > goes for --orphan in git-branch.\n>\n> I think we're on the same page with regards to what I meant. I.e. I\n> don't see how it makes sense to conflate the type of branch we want\n> (orphan or not orphan) with whether we want to clobber that branch or\n> not (switch -c or -C, or worktree -b or -B)\n\nI see where you're coming from in viewing --orphan as a modifier of\nbranch creation rather than as a branch-creation option itself.\nHowever, as far as UI is concerned, that ship sailed a long time ago,\nI suppose.\n\n> > As far as combining --orphan and -C (or -c), I'm not sure how we would\n> > arrange that using the existing parse_options() mechanism. It seems\n> > too magical and has potential for weird corner cases.\n>\n> Isn't it just having --orphan be an OPTION_STRING with\n> PARSE_OPT_LASTARG_DEFAULT. I.e. to support:\n>\n>     git switch -b branch --orphan\n>     git switch -B branch --orphan\n>     git switch --orphan branch\n>\n> And:\n>\n>     git worktree add -b branch --orphan\n>     git worktree add -B branch --orphan\n>\n> I didn't test it, just skimmed the code.\n\nI haven't dived into this stuff in a long time, but I'm having trouble\nconvincing myself that it would work out as intended. If I'm reading\nPARSE_OPT_LASTARG_DEFAULT correctly, `git switch -b <branch> --orphan`\nwould not be the same as `git switch --orphan -b <branch>`, and I\ndon't think it would work at all for git-worktree-add which has\nadditional <path> and <commitish> arguments (i.e. `git worktree add -b\n<branch> --orphan <path> [<commitish>]`).\n\nAnyhow, as I responded elsewhere to Junio, my present leaning is\ntoward -b, -B, --orphan all being mutually-exclusive branch-creation\noptions, each taking a <branch> argument -- just like they are in\ngit-checkout and git-switch (-c/-C, in this case) -- and allowing\n--force to overwrite an existing branch (in which case, -B can be\nviewed as shorthand for `--force -b`).\n\n> > Since git-worktree doesn't yet support --orphan, we certainly have\n> > more leeway and could go with your proposal of having --orphan be\n> > boolean and always requiring it to be used in conjunction with -b/-B.\n> > However, I'm quite hesitant to take that approach since it breaks with\n> > existing precedent in git-branch and git-switch, in which case\n> > --orphan takes its own argument (<branch>) and is mutually-exclusive\n> > with -b/-B/-c/-C.\n>\n> In git-branch? Isn't it only git [checkout|switch] that takes --orphan?\n\nUm, yes, I meant git-checkout everywhere I wrote git-branch. Sorry for\nthe confusion.\n\n> I think not having a -B or -C equivalent at all would be preferrable to\n> having a --force special-case just to work around the lack of it for\n> --orphan.\n\nI'm having trouble wrapping my brain around this statement.\n"},{"id":"417553","messageId":"87a6rv82n3.fsf@evledraar.gmail.com","threadId":"54948","inReplyTo":"CAPig+cQxYtw5z_bRQbS6MLgHQM2OTs5oRfpvKSOwZo8GcuwpTg@mail.gmail.com","subject":"Re: New orphan worktree?","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-02-23T11:06:08Z","receivedAt":"2021-02-23T11:06:55Z","isPatch":false,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Tue, Feb 23 2021, Eric Sunshine wrote:\n\n> On Mon, Feb 22, 2021 at 7:17 PM Ævar Arnfjörð Bjarmason\n> <avarab@gmail.com> wrote:\n>> On Tue, Feb 23 2021, Eric Sunshine wrote:\n>> > I'm not sure I follow. In git-switch, --orphan does not imply -c even\n>> > though --orphan also creates a new branch (thus seems to work similar\n>> > to -c); it is nevertheless mutually-exclusive with -c and -C. The same\n>> > goes for --orphan in git-branch.\n>>\n>> I think we're on the same page with regards to what I meant. I.e. I\n>> don't see how it makes sense to conflate the type of branch we want\n>> (orphan or not orphan) with whether we want to clobber that branch or\n>> not (switch -c or -C, or worktree -b or -B)\n>\n> I see where you're coming from in viewing --orphan as a modifier of\n> branch creation rather than as a branch-creation option itself.\n> However, as far as UI is concerned, that ship sailed a long time ago,\n> I suppose.\n\nNot really, I think we can have a new-style of it and just say:\n\n    It is also possible to provide `--orphan <branch-name>`, but\n    supplying it as an option to `-[cC]` as `-[cC] <branch-name>\n    --orphan` is preferred these days.\n\nWhether we should is another matter, see below...\n\n>> > As far as combining --orphan and -C (or -c), I'm not sure how we would\n>> > arrange that using the existing parse_options() mechanism. It seems\n>> > too magical and has potential for weird corner cases.\n>>\n>> Isn't it just having --orphan be an OPTION_STRING with\n>> PARSE_OPT_LASTARG_DEFAULT. I.e. to support:\n>>\n>>     git switch -b branch --orphan\n>>     git switch -B branch --orphan\n>>     git switch --orphan branch\n>>\n>> And:\n>>\n>>     git worktree add -b branch --orphan\n>>     git worktree add -B branch --orphan\n>>\n>> I didn't test it, just skimmed the code.\n>\n> I haven't dived into this stuff in a long time, but I'm having trouble\n> convincing myself that it would work out as intended. If I'm reading\n> PARSE_OPT_LASTARG_DEFAULT correctly, `git switch -b <branch> --orphan`\n> would not be the same as `git switch --orphan -b <branch>`\n\nYeah, I think so. But I think for an option like that it would be more\nobvious. I.e. we could say:\n\n    If \"-b\" or \"-B\" is provided a subsequent \"--orphan\" is a boolean.\n\nWe don't support the combination of the two now, so we could just\nmandate that the order matters.\n\nAnyway...\n\n> , and I don't think it would work at all for git-worktree-add which\n> has additional <path> and <commitish> arguments (i.e. `git worktree\n> add -b <branch> --orphan <path> [<commitish>]`).\n\n...we can parse these options, whether it's easy or trivial with\nparse-options.c is something I'd like to leave aside for now.\n\nRight now I'm not intending to re-roll this patch, but maybe someone\nelse (or even me) will get to it sometime. I think it's more useful\nif/when that happens to get people's take on whether this makes sense as\nUI, not whether it's trivial with the current parse_options() API.\n\nI think it's fairly easy to tease this behavior out of\nparse_options(). Worse case we can do a pre-loop over argv and see if\nboth \"--orphan\" and \"-b\"/\"-B\" occur. if so parse it with \"--orphan\" as a\nBOOL, otherwise STRING.\n\n> Anyhow, as I responded elsewhere to Junio, my present leaning is\n> toward -b, -B, --orphan all being mutually-exclusive branch-creation\n> options, each taking a <branch> argument -- just like they are in\n> git-checkout and git-switch (-c/-C, in this case) -- and allowing\n> --force to overwrite an existing branch (in which case, -B can be\n> viewed as shorthand for `--force -b`).\n\nSee https://lore.kernel.org/git/7vpqzlrmo4.fsf@alter.siamese.dyndns.org/\nfor past Junio arguing with his future self :)\n\nI.e. the reason we had -B in the first place is because --force means\nsomething else. We'd need \"--force-ref-deletion\n--force-work-tree-clobbering\" or whatever, or \"--force --force\".\n\nI like this lower/upper case convention. It started with \"branch -D\" in\nba65af9c1f6 (git-branch -d <branch>: delete unused branch., 2005-09-14),\nbut in checkout the --orphan option pre-dates -B. See 9db5ebf4022 (git\ncheckout: create unparented branch by --orphan, 2010-03-21) and\n02ac98374ee (builtin/checkout: learn -B, 2010-06-24).\n\nI don't think we're going to change how \"branch -D\" and \"switch -C\" work\nat this point, so making things consistent with it makes sense.\n\n>> > Since git-worktree doesn't yet support --orphan, we certainly have\n>> > more leeway and could go with your proposal of having --orphan be\n>> > boolean and always requiring it to be used in conjunction with -b/-B.\n>> > However, I'm quite hesitant to take that approach since it breaks with\n>> > existing precedent in git-branch and git-switch, in which case\n>> > --orphan takes its own argument (<branch>) and is mutually-exclusive\n>> > with -b/-B/-c/-C.\n>>\n>> In git-branch? Isn't it only git [checkout|switch] that takes --orphan?\n>\n> Um, yes, I meant git-checkout everywhere I wrote git-branch. Sorry for\n> the confusion.\n\n*nod*\n\n>> I think not having a -B or -C equivalent at all would be preferrable to\n>> having a --force special-case just to work around the lack of it for\n>> --orphan.\n>\n> I'm having trouble wrapping my brain around this statement.\n\nI mean I'd rather not have an --orphan mode that works like -B (as\nopposed to -b) at all instead of having one that's \"--orphan\n--force-ref-deletion\" or whatever.\n\nIt's an obscure enough thing that I don't think anyone *really* cares. I\njust wanted to find out if it not being a boolean was intentional, or a\nhistorical accident we would consider fixing if there was further work\non it.\n"},{"id":"417573","messageId":"xmqq7dmy4pox.fsf@gitster.g","threadId":"54948","inReplyTo":"87a6rv82n3.fsf@evledraar.gmail.com","subject":"Re: New orphan worktree?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-02-23T18:14:06Z","receivedAt":"2021-02-23T18:15:11Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:\n\n>> I see where you're coming from in viewing --orphan as a modifier of\n>> branch creation rather than as a branch-creation option itself.\n>> However, as far as UI is concerned, that ship sailed a long time ago,\n>> I suppose.\n>\n> Not really, I think we can have a new-style of it and just say:\n>\n>     It is also possible to provide `--orphan <branch-name>`, but\n>     supplying it as an option to `-[cC]` as `-[cC] <branch-name>\n>     --orphan` is preferred these days.\n>\n> Whether we should is another matter, see below...\n\nWe cannot affored to give it a short-and-sweet \"-[oO]\", but if we\ncould, we probably would have, and that would have made the UI\nconsistent, at least (in other words, I'd see the act of creating an\n\"orphan\" branch something distinct from creation of a normal\nbranch).\n\n\"You can treat --orphan as a standalone and distinct request to\ncreate this specific kind of branch, or you can treat as if it is\njust a modifier to specify which kind of branch, and -c/-C is still\nused to ask for creation or forced update\" does not sound like a\nvery end-user friendly explanation, at least to me.  Extra choices\nthat do not make a real difference invites \"so, which should I\nuse?\", a question they do not have to ask.\n\n>>> I think not having a -B or -C equivalent at all would be preferrable to\n>>> having a --force special-case just to work around the lack of it for\n>>> --orphan.\n>>\n>> I'm having trouble wrapping my brain around this statement.\n>\n> I mean I'd rather not have an --orphan mode that works like -B (as\n> opposed to -b) at all instead of having one that's \"--orphan\n> --force-ref-deletion\" or whatever.\n\nIf you are saying that we should just have\n\n    -c/-b/--orphan\n    -c/-b/--orphan --force\n    -C/-B (synonym for -c/-b --force)\n\nthen I fully agree.  I think the uppercase ones (and \"git branch -d/-D\")\nwere mistakes and should have used --force instead.\n\n> It's an obscure enough thing that I don't think anyone *really* cares. I\n> just wanted to find out if it not being a boolean was intentional, or a\n> historical accident we would consider fixing if there was further work\n> on it.\n"}]}