git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH v3 0/2] worktree: Support `--orphan` when creating new worktrees

From
Jacob Abel <jacobabel@nullpo.dev>
Date
Nov 23, 2022, 05:37 UTC
Message-ID
<20221123053708.rrbcphg7uukafdsg@phi>
In-Reply-To
<e027dc5b-dbb9-c511-038e-5440d59d976c@gmail.com>
On 22/11/23 03:43AM, Rubén Justo wrote:
Show 52 quoted lines
> On 22-nov-2022 23:26:57, Jacob Abel wrote:
> > On 22/11/22 12:16AM, Eric Sunshine wrote:
> > > On Sat, Nov 19, 2022 at 6:49 AM Ævar Arnfjörð Bjarmason
> > > <avarab@gmail.com> wrote:
> > > > On Sat, Nov 19 2022, Jacob Abel wrote:
> > > > > I'd support adding an `advise()` for at least the basic case where you try to
> > > > > create a worktree and no branches currently exist in the repository.
> > > > > i.e. something like this:
> > > > >
> > > > >     % git -C foo.git worktree add foobar/
> > > > >     hint: If you meant to create a new initial branch for this repository,
> > > > >     hint: e.g. 'main', you can do so using the --orphan option:
> > > > >     hint:
> > > > >     hint:   git worktree add --orphan main main/
> > > > >     hint:
> > > > >     fatal: invalid reference: 'foobar'
> > > > > and
> > > > >     % git -C foo.git worktree add -b foobar foobardir/
> > > > >     hint: If you meant to create a new initial branch for this repository,
> > > > >     hint: e.g. 'main', you can do so using the --orphan option:
> > > > >     hint:
> > > > >     hint:   git worktree add --orphan main main/
> > > > >     hint:
> > > > >     fatal: invalid reference: 'foobar'
> > > >
> > > > I think those would make sense, yes.
> > >
> > > Yes, this sort of advice could go a long way toward addressing my
> > > discoverability concerns. (I think, too, we should be able to
> > > dynamically customize the advice to mention "foobar" rather than
> > > "main" in order to more directly help the user.) Along with that,
> > > explaining this use-case in the git-worktree documentation would also
> > > be valuable for improving discoverability.
> >
> > Perfect. I think I've got this working already on my end using more or less
> > the following:
> >
> >     diff --git a/builtin/worktree.c b/builtin/worktree.c
> >     index 71786b72f6..f65b63d9d2 100644
> >     --- a/builtin/worktree.c
> >     +++ b/builtin/worktree.c
> >     @@ -736,7 +736,21 @@ static int add(int ac, const char **av, const char *prefix)
> >         if (!opts.quiet)
> >             print_preparing_worktree_line(opts.detach, branch, new_branch, !!new_branch_force);
> >
> >     -	if (new_branch && !opts.orphan_branch) {
> >     +	if (opts.orphan_branch) {
> >     +		branch = new_branch;
> >     +	} else if (!lookup_commit_reference_by_name("head")) {
>
> I haven't read the full thread and sorry to enter this way in the
> conversation, but this line got my attention.
No worries. It's always nice to have more eyes to catch mistakes.
> This needs to be "HEAD", in capital letters.

Ah yes. I wasn't paying attention when I copied it into my MUA and must have accidentally typed `ggvGu` instead of `ggvGy` and lowercased it before I copied it (thanks vim/user error). It should be:

    diff --git a/builtin/worktree.c b/builtin/worktree.c
    index 71786b72f6..f65b63d9d2 100644
    --- a/builtin/worktree.c
    +++ b/builtin/worktree.c
    @@ -736,7 +736,21 @@ static int add(int ac, const char **av, const char *prefix)
        if (!opts.quiet)
            print_preparing_worktree_line(opts.detach, branch, new_branch, !!new_branch_force);
    -	if (new_branch && !opts.orphan_branch) {
    +	if (opts.orphan_branch) {
    +		branch = new_branch;
    +	} else if (!lookup_commit_reference_by_name("HEAD")) {
    +		/*
    +		 * If HEAD does not reference a valid commit, only worktrees
    +		 * based on orphan branches can be created.
    +		 */
    +		advise("If you meant to create a new orphan branch for this repository,\n"
    +			 "e.g. '%s', you can do so using the --orphan option:\n"
    +			 "\n"
    +			 "	git worktree add --orphan %s %s\n"
    +			 "\n",
    +			 new_branch, new_branch, path);
    +		die(_("invalid reference: %s"), new_branch);
    +	} else if (new_branch) {
            struct child_process cp = CHILD_PROCESS_INIT;
            cp.git_cmd = 1;
            strvec_push(&cp.args, "branch");
Show 7 quoted lines
>
> Thank you for working on this, this is a thing that has hit me several
> times.
>
> The first impression got me thinking.. Why do we need this advise?
> Why not make the orphan branch right away? And why the argument for the
> --orphan option?

I went into my concerns with further overloading `worktree add -b/-B` and `worktree add` (DWYM) over on the other side of this thread [1]. I won't echo it all here but I wanted to mention a few things.

As for why we want the advise, by not short circuiting with the advise and instead just trying to DWYM, we can catch the following edge case:

A user less well acquainted with git tries out worktrees on a new project (no branches). They create multiple worktrees and since there are no branches, they are all orphans. Unless they've read the docs, they are now accustomed to this "new worktrees have no history" behavior. Then they make a commit on one of the orphans and the behavior changes and all new worktrees derive from that branch unless `git worktree add` is run from inside another worktree with a non-orphan branch.

There's more to it in the other thread but it gets kinda messy for the user if they walk off the well trodden path inadvertently. I'd like to avoid that all together where possible.

As for the argument, the reason is so that the syntax matches `git switch --orphan <new_branch>` (and the `git checkout` variant).

> I like what this new flag allows: make a new orphan branch when we
> are in any branch.  But if we are already in an orphan branch (like the
> initial) what's the user's expectation?

Like mentioned above (and in [1]), further overloading DWYM and `-b` impacts the already somewhat complex/unclear expectations for `git worktree add`.

When using the flag and not adding to `-b` and DWYM, we can short circuit this confusion for the most part by requiring the user to explicitly request `--orphan`.

As for creating a new orphan in a repo with existing branches but from a worktree containing an orphan branch, that fails cleanly as shown below:

    # in worktree with orphan branch
    % git worktree add -b foobar ../foobar
    Preparing worktree (new branch 'foobar')
    fatal: invalid reference: foobar
and in the next revision should fail with the following:
    # in worktree with orphan branch
    % git worktree add -b foobar ../foobar
    Preparing worktree (new branch 'foobar')
    hint: If you meant to create a new orphan branch for this repository,
    hint: e.g. 'foobar', you can do so using the --orphan option:
    hint:
    hint:   git worktree add --orphan foobar ../foobar/
    hint:
    fatal: invalid reference: foobar
> Maybe we can use the new flag to indicate that the user unconditionally
> wants an orphan branch, and use the rest of the arguments as they are,
> '-b' included.

I wouldn't necessarily be opposed to this however I do think changing it from `--orphan <new_branch>` to `--orphan -b <new_branch>` would be a departure from the syntax used in `git switch` and `git checkout` and that may make it harder for users already familar with those other commands.

Show 39 quoted lines
>
> This needs more work, but something like this:
>
> --- >8 ---
>
> diff --git a/builtin/worktree.c b/builtin/worktree.c
> index d774ff192a..1ea8d05c2f 100644
> --- a/builtin/worktree.c
> +++ b/builtin/worktree.c
> @@ -406,7 +406,7 @@ static int add_worktree(const char *path, const char *refname,
>
>  	/* is 'refname' a branch or commit? */
>  	if (!opts->detach && !strbuf_check_branch_ref(&symref, refname) &&
> -	    ref_exists(symref.buf)) {
> +	    (opts->orphan_branch || ref_exists(symref.buf))) {
>  		is_branch = 1;
>  		if (!opts->force)
>  			die_if_checked_out(symref.buf, 0);
> @@ -738,18 +738,8 @@ static int add(int ac, const char **av, const char *prefix)
>
>  	if (opts.orphan_branch) {
>  		branch = new_branch;
> -	} else if (!lookup_commit_reference_by_name("head")) {
> -		/*
> -		 * if head does not reference a valid commit, only worktrees
> -		 * based on orphan branches can be created.
> -		 */
> -		advise("if you meant to create a new orphan branch for this repository,\n"
> -			 "e.g. '%s', you can do so using the --orphan option:\n"
> -			 "\n"
> -			 "	git worktree add --orphan %s %s\n"
> -			 "\n",
> -			 new_branch, new_branch, path);
> -		die(_("invalid reference: %s"), new_branch);
> +	} else if (new_branch && !lookup_commit_reference_by_name("HEAD")) {
> +		branch = opts.orphan_branch = new_branch;
>  	} else if (new_branch) {
>  		struct child_process cp = CHILD_PROCESS_INIT;
>  		cp.git_cmd = 1;
1. https://lore.kernel.org/git/20221123042052.t42jmsqjxgx2k3th@phi/
Previous: Rubén JustoNext: Rubén Justo
Message 50 of 129 in “worktree: Support `--orphan` when creating new worktrees”
  1. 0/4 worktree: Support `--orphan` when creating new worktreesJacob Abel, Nov 4, 2022
  2. 1/4 worktree add: Include -B in usage docsJacob Abel, Nov 4, 2022
  3. Eric SunshineNov 4, 2022
  4. Jacob AbelNov 4, 2022
  5. 2/4 builtin/worktree.c: Update checkout_worktree() to use git-worktreeJacob Abel, Nov 4, 2022
  6. Ævar Arnfjörð BjarmasonNov 4, 2022
  7. Jacob AbelNov 4, 2022
  8. Taylor BlauNov 4, 2022
  9. 3/4 worktree add: add --orphan flagJacob Abel, Nov 4, 2022
  10. Ævar Arnfjörð BjarmasonNov 4, 2022
  11. Jacob AbelNov 4, 2022
  12. Eric SunshineNov 4, 2022
  13. Jacob AbelNov 4, 2022
  14. Eric SunshineNov 10, 2022
  15. Jacob AbelNov 10, 2022
  16. 4/4 worktree add: Add unit tests for --orphanJacob Abel, Nov 4, 2022
  17. Ævar Arnfjörð BjarmasonNov 4, 2022
  18. Jacob AbelNov 4, 2022
  19. Eric SunshineNov 4, 2022
  20. Jacob AbelNov 4, 2022
  21. Jacob AbelNov 4, 2022
  22. 0/2 worktree: Support `--orphan` when creating new worktreesJacob Abel, Nov 4, 2022
  23. 1/2 worktree add: Include -B in usage docsJacob Abel, Nov 4, 2022
  24. 2/2 worktree add: add --orphan flagJacob Abel, Nov 4, 2022
  25. 0/2 worktree: Support `--orphan` when creating new worktreesJacob Abel, Nov 10, 2022
  26. 1/2 worktree add: Include -B in usage docsJacob Abel, Nov 10, 2022
  27. 2/2 worktree add: add --orphan flagJacob Abel, Nov 10, 2022
  28. Ævar Arnfjörð BjarmasonNov 15, 2022
  29. Eric SunshineNov 15, 2022
  30. Ævar Arnfjörð BjarmasonNov 15, 2022
  31. Eric SunshineNov 16, 2022
  32. Jacob AbelNov 19, 2022
  33. Jacob AbelNov 19, 2022
  34. Ævar Arnfjörð BjarmasonNov 19, 2022
  35. Jacob AbelNov 19, 2022
  36. Eric SunshineNov 22, 2022
  37. Jacob AbelNov 22, 2022
  38. Ævar Arnfjörð BjarmasonNov 15, 2022
  39. Jacob AbelNov 19, 2022
  40. Ævar Arnfjörð BjarmasonNov 19, 2022
  41. Eric SunshineNov 16, 2022
  42. Ævar Arnfjörð BjarmasonNov 17, 2022
  43. Jacob AbelNov 19, 2022
  44. Ævar Arnfjörð BjarmasonNov 19, 2022
  45. Eric SunshineNov 22, 2022
  46. Jacob AbelNov 22, 2022
  47. Ævar Arnfjörð BjarmasonNov 22, 2022
  48. Jacob AbelNov 23, 2022
  49. Rubén JustoNov 23, 2022
  50. Jacob AbelNov 23, 2022
  51. Rubén JustoNov 23, 2022
  52. Phillip WoodNov 22, 2022
  53. Jacob AbelNov 23, 2022
  54. 0/3 worktree: Support `--orphan` when creating new worktreesJacob Abel, Dec 12, 2022
  55. 1/3 worktree add: Include -B in usage docsJacob Abel, Dec 12, 2022
  56. 2/3 worktree add: add --orphan flagJacob Abel, Dec 12, 2022
  57. Ævar Arnfjörð BjarmasonDec 12, 2022
  58. Jacob AbelDec 12, 2022
  59. Ævar Arnfjörð BjarmasonDec 12, 2022
  60. Jacob AbelDec 12, 2022
  61. 3/3 worktree add: Add hint to use --orphan when bad refJacob Abel, Dec 12, 2022
  62. Ævar Arnfjörð BjarmasonDec 12, 2022
  63. Jacob AbelDec 12, 2022
  64. Ævar Arnfjörð BjarmasonDec 12, 2022
  65. Eric SunshineDec 12, 2022
  66. Jacob AbelDec 12, 2022
  67. Jacob AbelDec 12, 2022
  68. 0/4 worktree: Support `--orphan` when creating new worktreesJacob Abel, Dec 20, 2022
  69. 1/4 worktree add: Include -B in usage docsJacob Abel, Dec 20, 2022
  70. Junio C HamanoDec 20, 2022
  71. Jacob AbelDec 20, 2022
  72. 2/4 worktree add: refactor opt exclusion testsJacob Abel, Dec 20, 2022
  73. Junio C HamanoDec 20, 2022
  74. Jacob AbelDec 20, 2022
  75. 3/4 worktree add: add --orphan flagJacob Abel, Dec 20, 2022
  76. Junio C HamanoDec 20, 2022
  77. Jacob AbelDec 21, 2022
  78. 4/4 worktree add: Add hint to use --orphan when bad refJacob Abel, Dec 20, 2022
  79. Junio C HamanoDec 20, 2022
  80. Jacob AbelDec 21, 2022
  81. 0/4 worktree: Support `--orphan` when creating new worktreesJacob Abel, Dec 28, 2022
  82. 1/4 worktree add: include -B in usage docsJacob Abel, Dec 28, 2022
  83. 2/4 worktree add: refactor opt exclusion testsJacob Abel, Dec 28, 2022
  84. Junio C HamanoDec 28, 2022
  85. Jacob AbelDec 29, 2022
  86. Junio C HamanoDec 29, 2022
  87. Jacob AbelDec 29, 2022
  88. Jacob AbelJan 6, 2023
  89. Junio C HamanoJan 6, 2023
  90. Jacob AbelJan 7, 2023
  91. 3/4 worktree add: add --orphan flagJacob Abel, Dec 28, 2022
  92. 4/4 worktree add: add hint to direct users towards --orphanJacob Abel, Dec 28, 2022
  93. Phillip WoodJan 6, 2023
  94. Ævar Arnfjörð BjarmasonDec 28, 2022
  95. Jacob AbelDec 29, 2022
  96. Ævar Arnfjörð BjarmasonDec 29, 2022
  97. Jacob AbelDec 29, 2022
  98. 0/4 worktree: Support `--orphan` when creating new worktreesJacob Abel, Jan 7, 2023
  99. 1/4 worktree add: include -B in usage docsJacob Abel, Jan 7, 2023
  100. 2/4 worktree add: refactor opt exclusion testsJacob Abel, Jan 7, 2023
  101. Junio C HamanoJan 8, 2023
  102. Jacob AbelJan 8, 2023
  103. 3/4 worktree add: add --orphan flagJacob Abel, Jan 7, 2023
  104. 4/4 worktree add: add hint to direct users towards --orphanJacob Abel, Jan 7, 2023
  105. Ævar Arnfjörð BjarmasonJan 9, 2023
  106. Jacob AbelJan 9, 2023
  107. Ævar Arnfjörð BjarmasonJan 9, 2023
  108. Jacob AbelJan 9, 2023
  109. 0/4 worktree: Support `--orphan` when creating new worktreesJacob Abel, Jan 9, 2023
  110. 1/4 worktree add: include -B in usage docsJacob Abel, Jan 9, 2023
  111. 3/4 worktree add: add --orphan flagJacob Abel, Jan 9, 2023
  112. Phillip WoodJan 13, 2023
  113. Junio C HamanoJan 13, 2023
  114. Jacob AbelJan 14, 2023
  115. Junio C HamanoJan 15, 2023
  116. rsbecker@nexbridge.comJan 15, 2023
  117. Junio C HamanoJan 15, 2023
  118. 'Jacob Abel'Jan 18, 2023
  119. Jacob AbelJan 18, 2023
  120. Ævar Arnfjörð BjarmasonJan 19, 2023
  121. Junio C HamanoJan 19, 2023
  122. Phillip WoodJan 16, 2023
  123. Jacob AbelJan 18, 2023
  124. Phillip WoodJan 19, 2023
  125. Jacob AbelJan 19, 2023
  126. 2/4 worktree add: refactor opt exclusion testsJacob Abel, Jan 9, 2023
  127. 4/4 worktree add: add hint to direct users towards --orphanJacob Abel, Jan 9, 2023
  128. Ævar Arnfjörð BjarmasonJan 9, 2023
  129. Junio C HamanoJan 13, 2023

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.