Git Mailing List Archive mirror
 help / color / mirror / Atom feed
From: Jacob Abel <jacobabel@nullpo.dev>
To: phillip.wood@dunelm.org.uk
Cc: "Ævar Arnfjörð Bjarmason" <avarab@gmail.com>,
	"Eric Sunshine" <sunshine@sunshineco.com>,
	git@vger.kernel.org, "Taylor Blau" <me@ttaylorr.com>
Subject: Re: [PATCH v3 0/2] worktree: Support `--orphan` when creating new worktrees
Date: Wed, 23 Nov 2022 04:21:04 +0000	[thread overview]
Message-ID: <20221123042052.t42jmsqjxgx2k3th@phi> (raw)
In-Reply-To: <b1ac730b-b4bd-3045-ce3b-1e5d9aca169a@dunelm.org.uk>

On 22/11/22 02:45PM, Phillip Wood wrote:
> On 19/11/2022 03:47, Jacob Abel wrote:
> > On 22/11/17 11:00AM, Ævar Arnfjörð Bjarmason wrote:
> >>
> >> On Tue, Nov 15 2022, Eric Sunshine wrote:
> >>
> >>> On Thu, Nov 10, 2022 at 6:32 PM Jacob Abel <jacobabel@nullpo.dev> wrote:
> >>>> While working with the worktree based git workflow, I realised that setting
> >>>> up a new git repository required switching between the traditional and
> >>>> worktree based workflows. Searching online I found a SO answer [1] which
> >>>> seemed to support this and which indicated that adding support for this should
> >>>> not be technically difficult.
> >>>>
> >>>>    * adding orphan branch functionality (as is present in `git-switch`)
> >>>>      to `git-worktree-add`
> >>>
> >>> I haven't had a chance yet to read v3, but can we take a step back for
> >>> a moment and look at this topic from a slightly different angle?
> >>> Setting aside the value of adding --orphan to `git worktree add`
> >>> (which, I'm perfectly fine with, as mentioned earlier), I have a
> >>> question about whether the solution proposed by this series is the
> >>> best we can do.
> >>>
> >>> As I understand it, the actual problem this series wants to solve is
> >>> that it's not possible to create a new worktree from an empty bare
> >>> repository; for instance:
> >>>
> >>>      % git init --bare foo.git
> >>>      % git -C foo.git worktree add -b main bar
> >>>      Preparing worktree (new branch 'main')
> >>>      fatal: not a valid object name: 'HEAD'
> >>>      %
> >>>
> >>> This series addresses that shortcoming by adding --orphan, so that the
> >>> following works:
> >>>
> >>>      % git init --bare foo.git
> >>>      % git -C foo.git worktree add --orphan main bar
> >>>      Preparing worktree (new branch 'main')
> >>>      %
> >>>
> >>> However, is this really the best and most user-friendly and most
> >>> discoverable solution? Is it likely that users are somehow going to
> >>> instinctively use --orphan when they see the "fatal: not a valid
> >>> object name: 'HEAD'" error message?
> >>>
> >>> Wouldn't a better solution be to somehow fix `git worktree add -b
> >>> <branch>` so that it just works rather than erroring out? I haven't
> >>> delved into the implementation to determine if this is possible, but
> >>> if it is, it seems a far superior "fix" for the problem shown above
> >>> since it requires no extra effort on the user's part, and doesn't
> >>> raise any discoverability red-flags (since nothing needs to be
> >>> "discovered" if `-b <branch>` works as expected in the first place).
> >>>
> >>> If fixing `-b <branch>` to "just work" is possible, then --orphan is
> >>> no longer a needed workaround but becomes "icing on the cake".
> >>
> >> That's a really good point, and we *could* "fix" that.
> >>
> >> But I don't see how to do it without overloading "-b" even further, in a
> >> way that some users either might not mean, or at least would be
> >> confusing.
> >>
> >> E.g. one script "manually clones" a repo because it does "git init",
> >> "git remote set-url", "git fetch" etc. Another one makes worktrees from
> >> those fresh checkouts once set up.
> >>
> >> If we "DWYM" here that second step will carry forward the bad state
> >> instead of erroring early.
>
> Wouldn't the first script error out if there was a problem?
>
> >> I haven't fully thought this throuh, so maybe it's fine, just
> >> wondering...
> >>
> >> ...an alternate way to perhaps to do this would be to detect this
> >> situation in add(), and emit an advise() telling the user that maybe
> >> they want to use "--orphan" for this?
> >>
> >
> > Prior to writing this patch, I tried to determine if there was a succinct way
> > to make `-b` "just work" however I wasn't able to find one that wouldn't
> > introduce unintuitive behavior.
>
> Can you say a bit more about what the unintuitive behavior was? As I
> understand it the problem is that "git branch" errors out when HEAD is a
> symbolic ref pointing to a ref that does not exist. I think we can use
> read_ref() to check for that before running "git branch" and act
> accordingly. We might want to check if HEAD matches init.defaultBranch
> and only do an orphan checkout in the new worktree in that case.

The main issue is that creating an orphan branch is very rarely what the user
intends to do. To modify `-b` to automatically create an orphan would require
that you set the behavior so that `-b` (and DWYM) creates a new orphan branch
only when the repository has no branches (i.e. a fresh init repo).

This has the effect that the command will perform separate operations depending
on the state of the repository and when mixed in with other commands it quickly
becomes confusing.

In the directory shown below:

    ../
    ./
    .git/

with `.git` containing a bare repository with no branches,

    % git worktree add foobar/

would now create a worktree `foobar/` with orphan branch `foobar` (which
technically speaking doesn't exist until a commit is made).

This behavior continues to apply until your first commit.

However after the following:

    % git worktree add foo/
    % cd foo/
    # create files
    % git add .
    % cd ../
    % git worktree add bar/
    % cd bar/
    # create files
    % cd ../foo/
    % git commit -m "foo commit"
    % cd ../bar/
    % git add .
    % git commit -m "bar commit"
    % cd ../foobar/
    # create files
    % git add .
    % git commit -m "foobar commit"

In that same directory:

    ../
    ./
    .git/
    foobar/ <- on branch foobar @ "foobar commit"
    foo/    <- on branch foo    @ "foo commit"
    bar/    <- on branch bar    @ "bar commit"

that same command now creates a branch which is based on whichever reference
HEAD happens to now refer to. In the case of a directory which is not a working
tree, it's not always clear to me what HEAD should actually point to. So now
what should the following do:

    % git worktree add what_am_i/

The user has just created 3 worktrees containing orphan branches. Wouldn't the
user now reasonably expect that from this directory with no working tree that
the above command would also create an orphan branch?

And when it doesn't, which branch is the history based off of? Which one will
the user expect?

- worktree foobar/ which was created first but with the most recent initial commit?
- worktree foo/ where the user has been working the longest?
- worktree bar/ which was created last but which had the earliest initial commit?

This isn't necessarily due to this change in particular but rather that this
change would expose users to an edge case where they can run into really
unintuitive behavior.

Of course this is a bit of an unusual use example but I'd rather warn & direct
the user when they need to do something slightly different/unusual to handle an
edge case rather than risk users getting weird behavior that leaves them turning
to Stack Overflow when they encounter an edge case.

>
> > My conclusion was that it was probably best
> > to break it out into a separate command as the other tools had.
> >
> > 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 init --bare foo.git
> >      % git -C foo.git branch --list
> >
> >      % 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 init --bare foo.git
> >      % git -C foo.git --no-pager branch --list
> >
> >      % 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'
> >
> > but not in the following circumstances:
> >
> >      % git init --bare foo.git
> >      % ...
> >      % git -C foo.git --no-pager branch --list
> >      + foo
> >        bar
> >      % git -C foo.git worktree add foobar/
> >      Preparing worktree (new branch 'foobar')
> >      HEAD is now at 319605f8f0 This is a commit message
> >
> > or
> >
> >      % git init --bare foo.git
> >      % ...
> >      % git -C foo.git --no-pager branch --list
> >      + foo
> >        bar
> >      % git -C foo.git worktree add -b foobar foobardir/
> >      Preparing worktree (new branch 'foobar)
> >      HEAD is now at 319605f8f0 This is a commit message
> >
> > Would there be any other circumstances where we'd definitely want an `advise()`?
> > Generally I'd assume that outside of those two circumstances, most users will
> > rarely intend to make an orphan without already knowing they absolutely need to
> > make an orphan.
>
> I don't think it matters if the repository is bare so I think it would
> be good to advise() on
>
> 	% git init foo
> 	% git -C foo worktree add bar
>
> Best Wishes
>
> Phillip

Correct. It shouldn't matter between bare and non-bare. I tend to prefer bare repos
when working with worktrees which is why I wrote it that way but I'm definitely
intending that the advise() works the same for both bare and non-bare.


  reply	other threads:[~2022-11-23  4:25 UTC|newest]

Thread overview: 132+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-11-04  1:02 [PATCH 0/4] worktree: Support `--orphan` when creating new worktrees Jacob Abel
2022-11-04  1:03 ` [PATCH 1/4] worktree add: Include -B in usage docs Jacob Abel
2022-11-04  3:05   ` Eric Sunshine
2022-11-04  4:24     ` Jacob Abel
2022-11-04  1:03 ` [PATCH 2/4] builtin/worktree.c: Update checkout_worktree() to use git-worktree Jacob Abel
2022-11-04  1:32   ` Ævar Arnfjörð Bjarmason
2022-11-04  3:58     ` Jacob Abel
2022-11-04 20:45     ` Taylor Blau
2022-11-04  1:03 ` [PATCH 3/4] worktree add: add --orphan flag Jacob Abel
2022-11-04  1:33   ` Ævar Arnfjörð Bjarmason
2022-11-04  4:11     ` Jacob Abel
2022-11-04  5:03   ` Eric Sunshine
2022-11-04 16:41     ` Jacob Abel
2022-11-10  4:13       ` Eric Sunshine
2022-11-10 21:21         ` Jacob Abel
2022-11-04  1:03 ` [PATCH 4/4] worktree add: Add unit tests for --orphan Jacob Abel
2022-11-04  1:37   ` Ævar Arnfjörð Bjarmason
2022-11-04  4:17     ` Jacob Abel
2022-11-04  4:33 ` [PATCH 0/4] worktree: Support `--orphan` when creating new worktrees Eric Sunshine
2022-11-04  4:47   ` Jacob Abel
2022-11-04  4:50   ` Jacob Abel
2022-11-04 21:34 ` [PATCH v2 0/2] " Jacob Abel
2022-11-04 21:34   ` [PATCH v2 1/2] worktree add: Include -B in usage docs Jacob Abel
2022-11-04 21:34   ` [PATCH v2 2/2] worktree add: add --orphan flag Jacob Abel
2022-11-10 23:32   ` [PATCH v3 0/2] worktree: Support `--orphan` when creating new worktrees Jacob Abel
2022-11-10 23:32     ` [PATCH v3 1/2] worktree add: Include -B in usage docs Jacob Abel
2022-11-10 23:32     ` [PATCH v3 2/2] worktree add: add --orphan flag Jacob Abel
2022-11-15 21:08       ` Ævar Arnfjörð Bjarmason
2022-11-15 21:29         ` Eric Sunshine
2022-11-15 22:35           ` Ævar Arnfjörð Bjarmason
2022-11-16  0:19             ` Eric Sunshine
2022-11-19  3:13               ` Jacob Abel
2022-11-19  3:09             ` Jacob Abel
2022-11-19 11:50               ` Ævar Arnfjörð Bjarmason
2022-11-19  1:44         ` Jacob Abel
2022-11-22  6:00           ` Eric Sunshine
2022-11-22 23:09             ` Jacob Abel
2022-11-15 22:09       ` Ævar Arnfjörð Bjarmason
2022-11-19  2:57         ` Jacob Abel
2022-11-19 11:50           ` Ævar Arnfjörð Bjarmason
2022-11-16  0:39     ` [PATCH v3 0/2] worktree: Support `--orphan` when creating new worktrees Eric Sunshine
2022-11-17 10:00       ` Ævar Arnfjörð Bjarmason
2022-11-19  3:47         ` Jacob Abel
2022-11-19 11:48           ` Ævar Arnfjörð Bjarmason
2022-11-22  5:16             ` Eric Sunshine
2022-11-22 23:26               ` Jacob Abel
2022-11-22 23:55                 ` Ævar Arnfjörð Bjarmason
2022-11-23  2:47                   ` Jacob Abel
2022-11-23  2:43                 ` Rubén Justo
2022-11-23  5:37                   ` Jacob Abel
2022-11-23  7:35                     ` Rubén Justo
2022-11-22 14:45           ` Phillip Wood
2022-11-23  4:21             ` Jacob Abel [this message]
2022-12-12  1:42     ` [PATCH v4 0/3] " Jacob Abel
2022-12-12  1:42       ` [PATCH v4 1/3] worktree add: Include -B in usage docs Jacob Abel
2022-12-12  1:42       ` [PATCH v4 2/3] worktree add: add --orphan flag Jacob Abel
2022-12-12  8:11         ` Ævar Arnfjörð Bjarmason
2022-12-12 14:55           ` Jacob Abel
2022-12-12 18:14             ` Ævar Arnfjörð Bjarmason
2022-12-12 22:39               ` Jacob Abel
2022-12-12  1:43       ` [PATCH v4 3/3] worktree add: Add hint to use --orphan when bad ref Jacob Abel
2022-12-12  8:35         ` Ævar Arnfjörð Bjarmason
2022-12-12 14:59           ` Jacob Abel
2022-12-12 18:16             ` Ævar Arnfjörð Bjarmason
2022-12-12 18:35               ` Eric Sunshine
2022-12-12 22:36                 ` Jacob Abel
2022-12-12 22:38               ` Jacob Abel
2022-12-20  2:37       ` [PATCH v5 0/4] worktree: Support `--orphan` when creating new worktrees Jacob Abel
2022-12-20  2:37         ` [PATCH v5 1/4] worktree add: Include -B in usage docs Jacob Abel
2022-12-20  3:42           ` Junio C Hamano
2022-12-20 23:24             ` Jacob Abel
2022-12-20  2:37         ` [PATCH v5 2/4] worktree add: refactor opt exclusion tests Jacob Abel
2022-12-20  4:00           ` Junio C Hamano
2022-12-20 23:29             ` Jacob Abel
2022-12-20  2:38         ` [PATCH v5 3/4] worktree add: add --orphan flag Jacob Abel
2022-12-20  4:19           ` Junio C Hamano
2022-12-21  0:17             ` Jacob Abel
2022-12-20  2:38         ` [PATCH v5 4/4] worktree add: Add hint to use --orphan when bad ref Jacob Abel
2022-12-20  6:18           ` Junio C Hamano
2022-12-21  0:42             ` Jacob Abel
2022-12-28  6:16         ` [PATCH v6 0/4] worktree: Support `--orphan` when creating new worktrees Jacob Abel
2022-12-28  6:16           ` [PATCH v6 1/4] worktree add: include -B in usage docs Jacob Abel
2022-12-28  6:16           ` [PATCH v6 2/4] worktree add: refactor opt exclusion tests Jacob Abel
2022-12-28 12:54             ` Junio C Hamano
2022-12-29  6:51               ` Jacob Abel
2022-12-29 10:07                 ` Junio C Hamano
2022-12-29 20:48                   ` Jacob Abel
2023-01-06  6:31                   ` Jacob Abel
2023-01-06 12:34                     ` Junio C Hamano
2023-01-07  4:45                       ` Jacob Abel
2022-12-28  6:17           ` [PATCH v6 3/4] worktree add: add --orphan flag Jacob Abel
2022-12-28  6:17           ` [PATCH v6 4/4] worktree add: add hint to direct users towards --orphan Jacob Abel
2023-01-06 14:19             ` Phillip Wood
2022-12-28  8:01           ` [PATCH v6 0/4] worktree: Support `--orphan` when creating new worktrees Ævar Arnfjörð Bjarmason
2022-12-29  6:38             ` Jacob Abel
2022-12-29 10:42               ` Ævar Arnfjörð Bjarmason
2022-12-29 21:22                 ` Jacob Abel
2023-01-07  4:58           ` [PATCH v7 " Jacob Abel
2023-01-07  4:59             ` [PATCH v7 1/4] worktree add: include -B in usage docs Jacob Abel
2023-01-07  4:59             ` [PATCH v7 2/4] worktree add: refactor opt exclusion tests Jacob Abel
2023-01-08  7:13               ` Junio C Hamano
2023-01-08 15:08                 ` Jacob Abel
2023-01-07  4:59             ` [PATCH v7 3/4] worktree add: add --orphan flag Jacob Abel
2023-01-07  4:59             ` [PATCH v7 4/4] worktree add: add hint to direct users towards --orphan Jacob Abel
2023-01-09 12:26             ` [PATCH v7 0/4] worktree: Support `--orphan` when creating new worktrees Ævar Arnfjörð Bjarmason
2023-01-09 17:11               ` Jacob Abel
2023-01-09 17:21                 ` Ævar Arnfjörð Bjarmason
2023-01-09 17:26                   ` Jacob Abel
2023-01-09 17:32             ` [PATCH v8 " Jacob Abel
2023-01-09 17:32               ` [PATCH v8 1/4] worktree add: include -B in usage docs Jacob Abel
2023-01-09 17:33               ` [PATCH v8 2/4] worktree add: refactor opt exclusion tests Jacob Abel
2023-01-09 17:33               ` [PATCH v8 3/4] worktree add: add --orphan flag Jacob Abel
2023-01-13 10:20                 ` Phillip Wood
2023-01-13 17:32                   ` Junio C Hamano
2023-01-14 22:47                   ` Jacob Abel
2023-01-15  3:09                     ` Junio C Hamano
2023-01-15  3:41                       ` rsbecker
2023-01-15  3:49                         ` Junio C Hamano
2023-01-18 22:46                           ` 'Jacob Abel'
2023-01-18 22:18                       ` Jacob Abel
2023-01-19 15:32                         ` Ævar Arnfjörð Bjarmason
2023-01-19 16:32                           ` Junio C Hamano
2023-01-16 10:47                     ` Phillip Wood
2023-01-18 22:40                       ` Jacob Abel
2023-01-19 16:18                         ` Phillip Wood
2023-01-19 22:20                           ` Jacob Abel
2023-01-09 17:33               ` [PATCH v8 4/4] worktree add: add hint to direct users towards --orphan Jacob Abel
2023-01-09 19:20               ` [PATCH v8 0/4] worktree: Support `--orphan` when creating new worktrees Ævar Arnfjörð Bjarmason
2023-01-13 17:34                 ` Junio C Hamano
  -- strict thread matches above, loose matches on Subject: below --
2022-12-08 21:41 [PATCH v3 0/2] " Jacob Abel
2022-12-08 22:00 ` rsbecker
2022-12-12  0:38   ` 'Jacob Abel'

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20221123042052.t42jmsqjxgx2k3th@phi \
    --to=jacobabel@nullpo.dev \
    --cc=avarab@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=me@ttaylorr.com \
    --cc=phillip.wood@dunelm.org.uk \
    --cc=sunshine@sunshineco.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).