diff mbox series

[v5,4/4] worktree add: Add hint to use --orphan when bad ref

Message ID 20221220023637.29042-5-jacobabel@nullpo.dev (mailing list archive)
State Superseded
Headers show
Series worktree: Support `--orphan` when creating new worktrees | expand

Commit Message

Jacob Abel Dec. 20, 2022, 2:38 a.m. UTC
Adds a new advice/hint in `git worktree add` for when the user
tries to create a new worktree from a reference that doesn't exist.

Signed-off-by: Jacob Abel <jacobabel@nullpo.dev>
---
 Documentation/config/advice.txt |  4 ++++
 advice.c                        |  1 +
 advice.h                        |  1 +
 builtin/worktree.c              |  6 ++++++
 t/t2400-worktree-add.sh         | 16 ++++++++++++++++
 5 files changed, 28 insertions(+)

--
2.38.2

Comments

Junio C Hamano Dec. 20, 2022, 6:18 a.m. UTC | #1
Jacob Abel <jacobabel@nullpo.dev> writes:

> Subject: Re: [PATCH v5 4/4] worktree add: Add hint to use --orphan when bad ref

Incomplete sentence that invites "when bad ref, what?"

> +			"	git worktree add --orphan %s %s\n"), new_branch, path

OK.  "git worktree add -b <name-of-branch> <path>" is how you create
a worktree and have it on a named branch.  And instead of saying -b, 
you would say --orphan.  This sounds like a fairly easy-to-understand
parallel to how "git checkout [-b/-B/--orphan] name-of-branch" takes
its parameters.

> +test_wt_add_empty_repo_orphan_hint() {
> +	local context="$1"
> +	shift
> +	local opts="$@"
> +	test_expect_success "'worktree add' show orphan hint in empty repo w/ $context" '
> +		test_when_finished "rm -rf empty_repo" &&
> +		GIT_DIR="empty_repo" git init --bare &&
> +		test_must_fail git -C empty_repo worktree add $opts foobar/ 2> actual &&

The comments on "$@" (vs "$*") in an earlier step equally applies here.
Jacob Abel Dec. 21, 2022, 12:42 a.m. UTC | #2
On 22/12/20 03:18PM, Junio C Hamano wrote:
> Jacob Abel <jacobabel@nullpo.dev> writes:
>
> > Subject: Re: [PATCH v5 4/4] worktree add: Add hint to use --orphan when bad ref
>
> Incomplete sentence that invites "when bad ref, what?"

Noted. Changed commit title to the following:

    worktree add: add hint to direct users towards --orphan

>
> > +			"	git worktree add --orphan %s %s\n"), new_branch, path
>
> OK.  "git worktree add -b <name-of-branch> <path>" is how you create
> a worktree and have it on a named branch.  And instead of saying -b,
> you would say --orphan.  This sounds like a fairly easy-to-understand
> parallel to how "git checkout [-b/-B/--orphan] name-of-branch" takes
> its parameters.

Yes. Originally it was a direct reproduction of `git checkout --orphan` with the
syntax being `git worktree add --orphan new_branch path/ old_branch` and the
operation checking out `old_branch` then discarding the commit history to make
the orphan branch `new_branch`. However after some discussion[1], the option was
changed to match `git switch --orphan` with the syntax and behavior we have now.

>
> > +test_wt_add_empty_repo_orphan_hint() {
> > +	local context="$1"
> > +	shift
> > +	local opts="$@"
> > +	test_expect_success "'worktree add' show orphan hint in empty repo w/ $context" '
> > +		test_when_finished "rm -rf empty_repo" &&
> > +		GIT_DIR="empty_repo" git init --bare &&
> > +		test_must_fail git -C empty_repo worktree add $opts foobar/ 2> actual &&
>
> The comments on "$@" (vs "$*") in an earlier step equally applies here.

Noted. Changed.

1. https://lore.kernel.org/git/CAPig+cSVzewXpk+eDSC-W-+Q8X_7ikZXXeSQbmpHBcdLCU5svw@mail.gmail.com/
diff mbox series

Patch

diff --git a/Documentation/config/advice.txt b/Documentation/config/advice.txt
index a00d0100a8..3e58521613 100644
--- a/Documentation/config/advice.txt
+++ b/Documentation/config/advice.txt
@@ -136,4 +136,8 @@  advice.*::
 		Advice shown when either linkgit:git-add[1] or linkgit:git-rm[1]
 		is asked to update index entries outside the current sparse
 		checkout.
+	worktreeAddOrphan::
+		Advice shown when a user tries to create a worktree from an
+		invalid reference, to instruct how to create a new orphan
+		branch instead.
 --
diff --git a/advice.c b/advice.c
index fd18968943..53e91fdb85 100644
--- a/advice.c
+++ b/advice.c
@@ -75,6 +75,7 @@  static struct {
 	[ADVICE_SUBMODULES_NOT_UPDATED] 		= { "submodulesNotUpdated", 1 },
 	[ADVICE_UPDATE_SPARSE_PATH]			= { "updateSparsePath", 1 },
 	[ADVICE_WAITING_FOR_EDITOR]			= { "waitingForEditor", 1 },
+	[ADVICE_WORKTREE_ADD_ORPHAN]			= { "worktreeAddOrphan", 1 },
 };

 static const char turn_off_instructions[] =
diff --git a/advice.h b/advice.h
index 07e0f76833..919d8c0064 100644
--- a/advice.h
+++ b/advice.h
@@ -50,6 +50,7 @@  struct string_list;
 	ADVICE_UPDATE_SPARSE_PATH,
 	ADVICE_WAITING_FOR_EDITOR,
 	ADVICE_SKIPPED_CHERRY_PICKS,
+	ADVICE_WORKTREE_ADD_ORPHAN,
 };

 int git_default_advice_config(const char *var, const char *value);
diff --git a/builtin/worktree.c b/builtin/worktree.c
index 194c3ccabf..1f44978616 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -730,6 +730,12 @@  static int add(int ac, const char **av, const char *prefix)
 	if (opts.orphan) {
 		branch = new_branch;
 	} else if (!lookup_commit_reference_by_name(branch)) {
+		advise_if_enabled(ADVICE_WORKTREE_ADD_ORPHAN,
+			_("If you meant to create a worktree containing a new orphan branch\n"
+			"(branch with no commits) for this repository, you can do so\n"
+			"using the --orphan option:\n"
+			"\n"
+			"	git worktree add --orphan %s %s\n"), new_branch, path);
 		die(_("invalid reference: %s"), branch);
 	} else if (new_branch) {
 		struct child_process cp = CHILD_PROCESS_INIT;
diff --git a/t/t2400-worktree-add.sh b/t/t2400-worktree-add.sh
index 73ad26651e..05539aa03c 100755
--- a/t/t2400-worktree-add.sh
+++ b/t/t2400-worktree-add.sh
@@ -375,6 +375,22 @@  test_expect_success '"add" worktree with orphan branch, lock, and reason' '
 	test_cmp expect .git/worktrees/orphan-with-lock-reason/locked
 '

+test_wt_add_empty_repo_orphan_hint() {
+	local context="$1"
+	shift
+	local opts="$@"
+	test_expect_success "'worktree add' show orphan hint in empty repo w/ $context" '
+		test_when_finished "rm -rf empty_repo" &&
+		GIT_DIR="empty_repo" git init --bare &&
+		test_must_fail git -C empty_repo worktree add $opts foobar/ 2> actual &&
+		grep "hint: If you meant to create a worktree containing a new orphan branch" actual
+	'
+}
+
+test_wt_add_empty_repo_orphan_hint 'DWIM'
+test_wt_add_empty_repo_orphan_hint '-b' -b foobar_branch
+test_wt_add_empty_repo_orphan_hint '-B' -B foobar_branch
+
 test_expect_success 'local clone from linked checkout' '
 	git clone --local here here-clone &&
 	( cd here-clone && git fsck )