Message ID | 20221104010242.11555-4-jacobabel@nullpo.dev (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | worktree: Support `--orphan` when creating new worktrees | expand |
On Fri, Nov 04 2022, Jacob Abel wrote: > commit = lookup_commit_reference_by_name(refname); > - if (!commit) > + Here. > + if (!commit && !opts->implicit) > die(_("invalid reference: %s"), refname); > > name = worktree_basename(path, &len); > @@ -482,10 +487,10 @@ static int add_worktree(const char *path, const char *refname, > strvec_pushf(&child_env, "%s=%s", GIT_WORK_TREE_ENVIRONMENT, path); > cp.git_cmd = 1; > > - if (!is_branch) > + if (!is_branch && commit) { > strvec_pushl(&cp.args, "update-ref", "HEAD", > oid_to_hex(&commit->object.oid), NULL); And here we have a stray style change, in this case conforming to our CodingGuidelines (it's agnostic on the former), but IMO better to keep this out, or split it into a "various style stuff" commit, makes this harder to review... > - else { > + } else { > strvec_pushl(&cp.args, "symbolic-ref", "HEAD", > symref.buf, NULL); > if (opts->quiet) > @@ -516,7 +521,7 @@ static int add_worktree(const char *path, const char *refname, > * Hook failure does not warrant worktree deletion, so run hook after > * is_junk is cleared, but do return appropriate code when hook fails. > */ > - if (!ret && opts->checkout) { > + if (!ret && opts->checkout && !opts->orphan_branch) { > struct run_hooks_opt opt = RUN_HOOKS_OPT_INIT; > > strvec_pushl(&opt.env, "GIT_DIR", "GIT_WORK_TREE", NULL); > @@ -608,33 +613,52 @@ static int add(int ac, const char **av, const char *prefix) > const char *opt_track = NULL; > const char *lock_reason = NULL; > int keep_locked = 0; > + ditto, we don't usually \n\n split up varibale decls. > struct option options[] = { > - OPT__FORCE(&opts.force, > - N_("checkout <branch> even if already checked out in other worktree"), > - PARSE_OPT_NOCOMPLETE), > + OPT__FORCE( > + &opts.force, > + N_("checkout <branch> even if already checked out in other worktree"), > + PARSE_OPT_NOCOMPLETE), This is just a stray refactoring of existing code to not-our-usual-style (first arg is on the same line as the "(", rest aligned with "("). > OPT_STRING('b', NULL, &new_branch, N_("branch"), > N_("create a new branch")), > OPT_STRING('B', NULL, &new_branch_force, N_("branch"), > N_("create or reset a branch")), > - OPT_BOOL('d', "detach", &opts.detach, N_("detach HEAD at named commit")), > - OPT_BOOL(0, "checkout", &opts.checkout, N_("populate the new working tree")), > - OPT_BOOL(0, "lock", &keep_locked, N_("keep the new working tree locked")), > + OPT_STRING(0, "orphan", &opts.orphan_branch, N_("branch"), > + N_("create a new unparented branch")), > + OPT_BOOL('d', "detach", &opts.detach, > + N_("detach HEAD at named commit")), > + OPT_BOOL(0, "checkout", &opts.checkout, > + N_("populate the new working tree")), > + OPT_BOOL(0, "lock", &keep_locked, > + N_("keep the new working tree locked")), Ditto, these look like they're too-long in the pre-image, but please resist re-flowing existing code while at it. > OPT_STRING(0, "reason", &lock_reason, N_("string"), > N_("reason for locking")), > OPT__QUIET(&opts.quiet, N_("suppress progress reporting")), > OPT_PASSTHRU(0, "track", &opt_track, NULL, > N_("set up tracking mode (see git-branch(1))"), > PARSE_OPT_NOARG | PARSE_OPT_OPTARG), > - OPT_BOOL(0, "guess-remote", &guess_remote, > - N_("try to match the new branch name with a remote-tracking branch")), > + OPT_BOOL( > + 0, "guess-remote", &guess_remote, > + N_("try to match the new branch name with a remote-tracking branch")), ditto. > OPT_END() > }; > > memset(&opts, 0, sizeof(opts)); > opts.checkout = 1; > ac = parse_options(ac, av, prefix, options, git_worktree_add_usage, 0); > - if (!!opts.detach + !!new_branch + !!new_branch_force > 1) > - die(_("options '%s', '%s', and '%s' cannot be used together"), "-b", "-B", "--detach"); > + > + opts.implicit = ac < 2; > + > + if (!!opts.detach + !!new_branch + !!new_branch_force + > + !!opts.orphan_branch > > + 1) The continued "if" is mis-indented, and that "1" is on a line of its own...
On 22/11/04 02:33AM, Ævar Arnfjörð Bjarmason wrote: > > > ... > > Here. > > > ... > > And here we have a stray style change, in this case conforming to our > CodingGuidelines (it's agnostic on the former), but IMO better to keep > this out, or split it into a "various style stuff" commit, makes this > harder to review... I believe those changes were introduced when I ran `make style`. I can revert these changes in v2. > > ... > > ditto, we don't usually \n\n split up varibale decls. Noted. Will fix in v2. > > ... > > This is just a stray refactoring of existing code to not-our-usual-style > (first arg is on the same line as the "(", rest aligned with "("). > > > ... > > Ditto, these look like they're too-long in the pre-image, but please > resist re-flowing existing code while at it. > > > ... > > ditto. Ditto the comment above regarding `make style`. > > + if (!!opts.detach + !!new_branch + !!new_branch_force + > > + !!opts.orphan_branch > > > + 1) > > The continued "if" is mis-indented, and that "1" is on a line of its > own... Ditto the comment above regarding `make style`. Also I'm not exactly sure what the tool tried to do here but I was initially hesitant to override the formatter.
On Thu, Nov 3, 2022 at 9:07 PM Jacob Abel <jacobabel@nullpo.dev> wrote: > Adds support for creating an orphan branch when adding a new worktree. > This functionality is equivalent to git checkout's --orphan flag. > [...] > Signed-off-by: Jacob Abel <jacobabel@nullpo.dev> > --- > diff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt > @@ -95,6 +95,17 @@ exist, a new branch based on `HEAD` is automatically created as if > +------------ > +$ git worktree add --orphan <branch> <path> [<commit-ish>] > +------------ > ++ > +Create a worktree containing an orphan branch named `<branch>` based > +on `<commit-ish>`. If `<commit-ish>` is not specified, the new orphan branch > +will be created based on `HEAD`. > ++ > +Note that unlike with `-b` or `-B`, this operation will succeed even if > +`<commit-ish>` is a branch that is currently checked out somewhere else. Are we sure we want to be modeling this after `git checkout --orphan`? If I understand correctly, that option has long been considered (by some) too clunky, which is why `git switch --orphan` was simplified to accept only a branch name but no commit-ish, and to start the orphan branch with an empty directory. My own feeling is that modeling it after `git switch --orphan` is probably the way to go... > @@ -222,6 +233,11 @@ This can also be set up as the default behaviour by using the > +--orphan <new-branch>:: > + With `add`, create a new orphan branch named `<new-branch>` in the new > + worktree based on `<commit-ish>`. If `<commit-ish>` is omitted, it > + defaults to `HEAD`. ...which would mean that this would no longer talk about `<commit-ish>`. > diff --git a/builtin/worktree.c b/builtin/worktree.c > @@ -608,33 +613,52 @@ static int add(int ac, const char **av, const char *prefix) > struct option options[] = { > + OPT_STRING(0, "orphan", &opts.orphan_branch, N_("branch"), > + N_("create a new unparented branch")), The short help message for `git switch --orphan` and `git checkout --orphan` say simply "new unparented branch", so this message should probably follow suit (or consistency and to ease the job of translators). > - if (!!opts.detach + !!new_branch + !!new_branch_force > 1) > - die(_("options '%s', '%s', and '%s' cannot be used together"), "-b", "-B", "--detach"); > + die(_("options '%s', '%s', '%s', and '%s' cannot be used together"), > + "-b", "-B", "--orphan", "--detach"); Good to see this interlock updated for --orphan. > + if (opts.orphan_branch && opt_track) > + die(_("'%s' cannot be used with '%s'"), "--orphan", "--track"); > + if (opts.orphan_branch && !opts.checkout) > + die(_("'%s' cannot be used with '%s'"), "--orphan", > + "--no-checkout"); Good to have these additional interlocks. I think, however, for the sake of translators, we should use the same terminology as the existing message above (i.e. "options ... cannot be used together"). > + /* > + * From here on, new_branch will contain the branch to be checked out, > + * and new_branch_force and opts.orphan_branch will tell us which one of > + * -b/-B/--orphan is being used. > + */ This can probably be worded a bit differently to make it clear that from this point onward, those other variables are interpreted as if they are booleans. Moreover, we can make this even clearer by following the example of -B in which (by necessity due to parse-options) the local variable in add() is a `const char *`, but its counterpart in `struct add_opts` is a boolean (int).
On 22/11/04 01:03AM, Eric Sunshine wrote: > On Thu, Nov 3, 2022 at 9:07 PM Jacob Abel <jacobabel@nullpo.dev> wrote: > > ... > > Are we sure we want to be modeling this after `git checkout --orphan`? > If I understand correctly, that option has long been considered (by > some) too clunky, which is why `git switch --orphan` was simplified to > accept only a branch name but no commit-ish, and to start the orphan > branch with an empty directory. My own feeling is that modeling it > after `git switch --orphan` is probably the way to go... I would argue that the `git checkout --orphan` command format is preferable to `git switch --orphan` when creating new worktrees. Reason being that in many cases (except when working in a new repo), if you are trying to create a worktree from an orphan you will be doing it with a different commit-ish currently checked out in your worktree than the one you want to use for the orphan (or you aren't in any worktree). Requiring the commit-ish to be inferred would limit the user to checking out an orphan from an existing worktree (in which case they could just create a new worktree normally and use `git switch --orphan` to move that to an orphan branch). > > ... > > The short help message for `git switch --orphan` and `git checkout > --orphan` say simply "new unparented branch", so this message should > probably follow suit (or consistency and to ease the job of > translators). Noted. > > ... > > Good to have these additional interlocks. I think, however, for the > sake of translators, we should use the same terminology as the > existing message above (i.e. "options ... cannot be used together"). Noted. > > > + /* > > + * From here on, new_branch will contain the branch to be checked out, > > + * and new_branch_force and opts.orphan_branch will tell us which one of > > + * -b/-B/--orphan is being used. > > + */ > > This can probably be worded a bit differently to make it clear that > from this point onward, those other variables are interpreted as if > they are booleans. Moreover, we can make this even clearer by > following the example of -B in which (by necessity due to > parse-options) the local variable in add() is a `const char *`, but > its counterpart in `struct add_opts` is a boolean (int). The one thing to note with `opts.orphan_branch` is that it is used as both a string and a boolean later in `add_worktree()`. Since orphan branches don't have any commits tied to them, we have to check out the original commit-ish in `add_worktree()` and then convert it to an orphan of name `opts.orphan_branch` instead of creating the branch prior to entering `add_worktree()` (as is done for `-B` and `-b`). I do agree that the comment should probably be re-worded. I'll update it to be clearer in v2.
On Fri, Nov 4, 2022 at 12:42 PM Jacob Abel <jacobabel@nullpo.dev> wrote: > On 22/11/04 01:03AM, Eric Sunshine wrote: > > On Thu, Nov 3, 2022 at 9:07 PM Jacob Abel <jacobabel@nullpo.dev> wrote: > > Are we sure we want to be modeling this after `git checkout --orphan`? > > If I understand correctly, that option has long been considered (by > > some) too clunky, which is why `git switch --orphan` was simplified to > > accept only a branch name but no commit-ish, and to start the orphan > > branch with an empty directory. My own feeling is that modeling it > > after `git switch --orphan` is probably the way to go... > > I would argue that the `git checkout --orphan` command format is preferable to > `git switch --orphan` when creating new worktrees. Reason being that in many > cases (except when working in a new repo), if you are trying to create a > worktree from an orphan you will be doing it with a different commit-ish > currently checked out in your worktree than the one you want to use for the > orphan (or you aren't in any worktree). I guess I'm not understanding the use-case being described here or that this series is trying to address. In my own experience, the very, very few times I've used --orphan was when I needed a branch with no existing history (i.e. "orphan") and with no existing files. For that use-case, `git switch --orphan` is ideal, whereas `git checkout --orphan` is a bother since it requires manually removing all content from the directory and clearing the index. > Requiring the commit-ish to be inferred would limit the user to checking out > an orphan from an existing worktree (in which case they could just create a > new worktree normally and use `git switch --orphan` to move that to an orphan > branch). I'm not following what you mean by inferred commit-ish. `git switch --orphan` does not infer any commit-ish; it starts the orphaned branch with an empty directory, hence there is no commit-ish involved. The `git switch --orphan` behavior was intentionally implemented to "fix" what has long been considered (by some) a UX botch in the behavior of `git checkout --orphan`. It was argued that in the vast majority of cases, people wanted an orphan branch to mean both "no history" and "no files". So, in that sense, it feels like a step backward to adopt `git checkout --orphan` when introducing `git worktree --orphan`. But, as I said, I'm genuinely not grasping your use-case, so I'm having trouble understanding why you consider `git checkout --orphan` a better model. If you can elaborate your use-case more thoroughly, perhaps it would help (at least me).
On 22/11/09 11:13PM, Eric Sunshine wrote: > On Fri, Nov 4, 2022 at 12:42 PM Jacob Abel <jacobabel@nullpo.dev> wrote: > > On 22/11/04 01:03AM, Eric Sunshine wrote: > > > On Thu, Nov 3, 2022 at 9:07 PM Jacob Abel <jacobabel@nullpo.dev> wrote: > > > Are we sure we want to be modeling this after `git checkout --orphan`? > > > If I understand correctly, that option has long been considered (by > > > some) too clunky, which is why `git switch --orphan` was simplified to > > > accept only a branch name but no commit-ish, and to start the orphan > > > branch with an empty directory. My own feeling is that modeling it > > > after `git switch --orphan` is probably the way to go... > > > > I would argue that the `git checkout --orphan` command format is preferable to > > `git switch --orphan` when creating new worktrees. Reason being that in many > > cases (except when working in a new repo), if you are trying to create a > > worktree from an orphan you will be doing it with a different commit-ish > > currently checked out in your worktree than the one you want to use for the > > orphan (or you aren't in any worktree). > > I guess I'm not understanding the use-case being described here or > that this series is trying to address. In my own experience, the very, > very few times I've used --orphan was when I needed a branch with no > existing history (i.e. "orphan") and with no existing files. For that > use-case, `git switch --orphan` is ideal, whereas `git checkout > --orphan` is a bother since it requires manually removing all content > from the directory and clearing the index. > > > Requiring the commit-ish to be inferred would limit the user to checking out > > an orphan from an existing worktree (in which case they could just create a > > new worktree normally and use `git switch --orphan` to move that to an orphan > > branch). > > I'm not following what you mean by inferred commit-ish. `git switch > --orphan` does not infer any commit-ish; it starts the orphaned branch > with an empty directory, hence there is no commit-ish involved. > > The `git switch --orphan` behavior was intentionally implemented to > "fix" what has long been considered (by some) a UX botch in the > behavior of `git checkout --orphan`. It was argued that in the vast > majority of cases, people wanted an orphan branch to mean both "no > history" and "no files". So, in that sense, it feels like a step > backward to adopt `git checkout --orphan` when introducing `git > worktree --orphan`. > > But, as I said, I'm genuinely not grasping your use-case, so I'm > having trouble understanding why you consider `git checkout --orphan` > a better model. If you can elaborate your use-case more thoroughly, > perhaps it would help (at least me). Ah I see where my misunderstanding was. I have significantly less experience with `git switch` vs `git checkout` so prior to responding I was trying to understand the difference in behaviour and I ended up misunderstanding what `git switch --orphan` was doing. I wrongly assumed that `git switch --orphan` was doing the same thing as `git checkout --orphan` but using the currently checked out branch. Additionally I had assumed that there was an important reason for being able to create orphans from existing branches and that not being able to select which branch to use would somehow be removing functionality. After re-reading your replies, I can see that this is not the case and that I jumped the gun on my reply prior to doing my research properly. I will make the requested change (moving from `git checkout` to `git switch` semantics) for v3. Apologies for the misunderstanding.
diff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt index 4dd658012b..92bd75564f 100644 --- a/Documentation/git-worktree.txt +++ b/Documentation/git-worktree.txt @@ -10,7 +10,7 @@ SYNOPSIS -------- [verse] 'git worktree add' [-f] [--detach] [--checkout] [--lock [--reason <string>]] - [[-b | -B] <new-branch>] <path> [<commit-ish>] + [[-b | -B | --orphan] <new-branch>] <path> [<commit-ish>] 'git worktree list' [-v | --porcelain [-z]] 'git worktree lock' [--reason <string>] <worktree> 'git worktree move' <worktree> <new-path> @@ -95,6 +95,17 @@ exist, a new branch based on `HEAD` is automatically created as if `-b <branch>` was given. If `<branch>` does exist, it will be checked out in the new worktree, if it's not checked out anywhere else, otherwise the command will refuse to create the worktree (unless `--force` is used). ++ +------------ +$ git worktree add --orphan <branch> <path> [<commit-ish>] +------------ ++ +Create a worktree containing an orphan branch named `<branch>` based +on `<commit-ish>`. If `<commit-ish>` is not specified, the new orphan branch +will be created based on `HEAD`. ++ +Note that unlike with `-b` or `-B`, this operation will succeed even if +`<commit-ish>` is a branch that is currently checked out somewhere else. list:: @@ -222,6 +233,11 @@ This can also be set up as the default behaviour by using the With `prune`, do not remove anything; just report what it would remove. +--orphan <new-branch>:: + With `add`, create a new orphan branch named `<new-branch>` in the new + worktree based on `<commit-ish>`. If `<commit-ish>` is omitted, it + defaults to `HEAD`. + --porcelain:: With `list`, output in an easy-to-parse format for scripts. This format will remain stable across Git versions and regardless of user diff --git a/builtin/worktree.c b/builtin/worktree.c index d40f771848..70f319a6b5 100644 --- a/builtin/worktree.c +++ b/builtin/worktree.c @@ -17,7 +17,7 @@ #define BUILTIN_WORKTREE_ADD_USAGE \ N_("git worktree add [-f] [--detach] [--checkout] [--lock [--reason <string>]]\n" \ - " [[-b | -B] <new-branch>] <path> [<commit-ish>]") + " [[-b | -B | --orphan] <new-branch>] <path> [<commit-ish>]") #define BUILTIN_WORKTREE_LIST_USAGE \ N_("git worktree list [-v | --porcelain [-z]]") #define BUILTIN_WORKTREE_LOCK_USAGE \ @@ -90,6 +90,8 @@ struct add_opts { int detach; int quiet; int checkout; + int implicit; + const char *orphan_branch; const char *keep_locked; }; @@ -360,6 +362,8 @@ static int checkout_worktree(const struct add_opts *opts, strvec_pushl(&cp.args, "checkout", "--no-recurse-submodules", NULL); if (opts->quiet) strvec_push(&cp.args, "--quiet"); + if (opts->orphan_branch) + strvec_pushl(&cp.args, "--orphan", opts->orphan_branch, NULL); strvec_pushv(&cp.env, child_env->v); return run_command(&cp); } @@ -393,7 +397,8 @@ static int add_worktree(const char *path, const char *refname, die_if_checked_out(symref.buf, 0); } commit = lookup_commit_reference_by_name(refname); - if (!commit) + + if (!commit && !opts->implicit) die(_("invalid reference: %s"), refname); name = worktree_basename(path, &len); @@ -482,10 +487,10 @@ static int add_worktree(const char *path, const char *refname, strvec_pushf(&child_env, "%s=%s", GIT_WORK_TREE_ENVIRONMENT, path); cp.git_cmd = 1; - if (!is_branch) + if (!is_branch && commit) { strvec_pushl(&cp.args, "update-ref", "HEAD", oid_to_hex(&commit->object.oid), NULL); - else { + } else { strvec_pushl(&cp.args, "symbolic-ref", "HEAD", symref.buf, NULL); if (opts->quiet) @@ -516,7 +521,7 @@ static int add_worktree(const char *path, const char *refname, * Hook failure does not warrant worktree deletion, so run hook after * is_junk is cleared, but do return appropriate code when hook fails. */ - if (!ret && opts->checkout) { + if (!ret && opts->checkout && !opts->orphan_branch) { struct run_hooks_opt opt = RUN_HOOKS_OPT_INIT; strvec_pushl(&opt.env, "GIT_DIR", "GIT_WORK_TREE", NULL); @@ -608,33 +613,52 @@ static int add(int ac, const char **av, const char *prefix) const char *opt_track = NULL; const char *lock_reason = NULL; int keep_locked = 0; + struct option options[] = { - OPT__FORCE(&opts.force, - N_("checkout <branch> even if already checked out in other worktree"), - PARSE_OPT_NOCOMPLETE), + OPT__FORCE( + &opts.force, + N_("checkout <branch> even if already checked out in other worktree"), + PARSE_OPT_NOCOMPLETE), OPT_STRING('b', NULL, &new_branch, N_("branch"), N_("create a new branch")), OPT_STRING('B', NULL, &new_branch_force, N_("branch"), N_("create or reset a branch")), - OPT_BOOL('d', "detach", &opts.detach, N_("detach HEAD at named commit")), - OPT_BOOL(0, "checkout", &opts.checkout, N_("populate the new working tree")), - OPT_BOOL(0, "lock", &keep_locked, N_("keep the new working tree locked")), + OPT_STRING(0, "orphan", &opts.orphan_branch, N_("branch"), + N_("create a new unparented branch")), + OPT_BOOL('d', "detach", &opts.detach, + N_("detach HEAD at named commit")), + OPT_BOOL(0, "checkout", &opts.checkout, + N_("populate the new working tree")), + OPT_BOOL(0, "lock", &keep_locked, + N_("keep the new working tree locked")), OPT_STRING(0, "reason", &lock_reason, N_("string"), N_("reason for locking")), OPT__QUIET(&opts.quiet, N_("suppress progress reporting")), OPT_PASSTHRU(0, "track", &opt_track, NULL, N_("set up tracking mode (see git-branch(1))"), PARSE_OPT_NOARG | PARSE_OPT_OPTARG), - OPT_BOOL(0, "guess-remote", &guess_remote, - N_("try to match the new branch name with a remote-tracking branch")), + OPT_BOOL( + 0, "guess-remote", &guess_remote, + N_("try to match the new branch name with a remote-tracking branch")), OPT_END() }; memset(&opts, 0, sizeof(opts)); opts.checkout = 1; ac = parse_options(ac, av, prefix, options, git_worktree_add_usage, 0); - if (!!opts.detach + !!new_branch + !!new_branch_force > 1) - die(_("options '%s', '%s', and '%s' cannot be used together"), "-b", "-B", "--detach"); + + opts.implicit = ac < 2; + + if (!!opts.detach + !!new_branch + !!new_branch_force + + !!opts.orphan_branch > + 1) + die(_("options '%s', '%s', '%s', and '%s' cannot be used together"), + "-b", "-B", "--orphan", "--detach"); + if (opts.orphan_branch && opt_track) + die(_("'%s' cannot be used with '%s'"), "--orphan", "--track"); + if (opts.orphan_branch && !opts.checkout) + die(_("'%s' cannot be used with '%s'"), "--orphan", + "--no-checkout"); if (lock_reason && !keep_locked) die(_("the option '%s' requires '%s'"), "--reason", "--lock"); if (lock_reason) @@ -646,11 +670,16 @@ static int add(int ac, const char **av, const char *prefix) usage_with_options(git_worktree_add_usage, options); path = prefix_filename(prefix, av[0]); - branch = ac < 2 ? "HEAD" : av[1]; + branch = opts.implicit ? "HEAD" : av[1]; if (!strcmp(branch, "-")) branch = "@{-1}"; + /* + * From here on, new_branch will contain the branch to be checked out, + * and new_branch_force and opts.orphan_branch will tell us which one of + * -b/-B/--orphan is being used. + */ if (new_branch_force) { struct strbuf symref = STRBUF_INIT; @@ -663,6 +692,11 @@ static int add(int ac, const char **av, const char *prefix) strbuf_release(&symref); } + if (opts.orphan_branch) { + new_branch = opts.orphan_branch; + opts.force = 1; + } + if (ac < 2 && !new_branch && !opts.detach) { const char *s = dwim_branch(path, &new_branch); if (s) @@ -686,7 +720,7 @@ 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) { + if (new_branch && !opts.orphan_branch) { struct child_process cp = CHILD_PROCESS_INIT; cp.git_cmd = 1; strvec_push(&cp.args, "branch");
Adds support for creating an orphan branch when adding a new worktree. This functionality is equivalent to git checkout's --orphan flag. The original reason this feature was implemented was to allow a user to initialise a new repository using solely the worktree oriented workflow. Example usage included below. $ GIT_DIR=".git" git init --bare $ git worktree add --orphan master master/ Signed-off-by: Jacob Abel <jacobabel@nullpo.dev> --- Documentation/git-worktree.txt | 18 ++++++++- builtin/worktree.c | 68 +++++++++++++++++++++++++--------- 2 files changed, 68 insertions(+), 18 deletions(-) -- 2.37.4