From: Jacob Abel <jacobabel@nullpo.dev>
To: git@vger.kernel.org
Cc: "Jacob Abel" <jacobabel@nullpo.dev>,
"Ævar Arnfjörð Bjarmason" <avarab@gmail.com>,
"Eric Sunshine" <sunshine@sunshineco.com>,
"Junio C Hamano" <gitster@pobox.com>,
"Phillip Wood" <phillip.wood123@gmail.com>,
"Rubén Justo" <rjusto@gmail.com>, "Taylor Blau" <me@ttaylorr.com>,
rsbecker@nexbridge.com
Subject: [RESEND PATCH v10 8/8] worktree add: emit warn when there is a bad HEAD
Date: Wed, 17 May 2023 21:49:06 +0000 [thread overview]
Message-ID: <20230517214711.12467-9-jacobabel@nullpo.dev> (raw)
In-Reply-To: <20230517214711.12467-1-jacobabel@nullpo.dev>
Add a warning to `worktree add` when the command tries to reference
HEAD, there exist valid local branches, and the HEAD points to a
non-existent reference.
Current Behavior:
% git -C foo worktree list
/path/to/repo/foo dadc8e6dac [main]
/path/to/repo/foo_wt 0000000000 [badref]
% git -C foo worktree add ../wt1
Preparing worktree (new branch 'wt1')
HEAD is now at dadc8e6dac dummy commit
% git -C foo_wt worktree add ../wt2
hint: If you meant to create a worktree containing a new orphan branch
[...]
hint: Disable this message with "git config advice.worktreeAddOrphan false"
fatal: invalid reference: HEAD
%
New Behavior:
% git -C foo worktree list
/path/to/repo/foo dadc8e6dac [main]
/path/to/repo/foo_wt 0000000000 [badref]
% git -C foo worktree add ../wt1
Preparing worktree (new branch 'wt1')
HEAD is now at dadc8e6dac dummy commit
% git -C foo_wt worktree add ../wt2
warning: HEAD points to an invalid (or orphaned) reference.
HEAD path: '/path/to/repo/foo/.git/worktrees/foo_wt/HEAD'
HEAD contents: 'ref: refs/heads/badref'
hint: If you meant to create a worktree containing a new orphan branch
[...]
hint: Disable this message with "git config advice.worktreeAddOrphan false"
fatal: invalid reference: HEAD
%
Signed-off-by: Jacob Abel <jacobabel@nullpo.dev>
---
builtin/worktree.c | 34 +++++++++++++++++++++++++++++-----
t/t2400-worktree-add.sh | 18 +++++++++++++++++-
2 files changed, 46 insertions(+), 6 deletions(-)
diff --git a/builtin/worktree.c b/builtin/worktree.c
index 093b2cb032..5f62084334 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -638,6 +638,9 @@ static int first_valid_ref(const char *refname,
*
* - Checks whether any valid local branches exist.
*
+ * - Emits a warning if there exist any valid branches but HEAD does not point
+ * to a valid reference.
+ *
* Returns 1 if any of the previous checks are true, otherwise returns 0.
*/
static int can_use_local_refs(const struct add_opts *opts)
@@ -645,6 +648,23 @@ static int can_use_local_refs(const struct add_opts *opts)
if (head_ref(first_valid_ref, NULL)) {
return 1;
} else if (for_each_branch_ref(first_valid_ref, NULL)) {
+ if (!opts->quiet) {
+ struct strbuf path = STRBUF_INIT;
+ struct strbuf contents = STRBUF_INIT;
+
+ strbuf_add_real_path(&path, get_worktree_git_dir(NULL));
+ strbuf_addstr(&path, "/HEAD");
+ strbuf_read_file(&contents, path.buf, 64);
+ strbuf_stripspace(&contents, 0);
+ strbuf_strip_suffix(&contents, "\n");
+
+ warning(_("HEAD points to an invalid (or orphaned) reference.\n"
+ "HEAD path: '%s'\n"
+ "HEAD contents: '%s'"),
+ path.buf, contents.buf);
+ strbuf_release(&path);
+ strbuf_release(&contents);
+ }
return 1;
}
return 0;
@@ -666,16 +686,12 @@ static int can_use_local_refs(const struct add_opts *opts)
static int can_use_remote_refs(const struct add_opts *opts)
{
if (!guess_remote) {
- if (!opts->quiet)
- fprintf_ln(stderr, WORKTREE_ADD_DWIM_ORPHAN_INFER_TEXT);
return 0;
} else if (for_each_remote_ref(first_valid_ref, NULL)) {
return 1;
} else if (!opts->force && remote_get(NULL)) {
die(_("No local or remote refs exist despite at least one remote\n"
"present, stopping; use 'add -f' to overide or fetch a remote first"));
- } else if (!opts->quiet) {
- fprintf_ln(stderr, WORKTREE_ADD_DWIM_ORPHAN_INFER_TEXT);
}
return 0;
}
@@ -828,8 +844,12 @@ static int add(int ac, const char **av, const char *prefix)
int n;
const char *s = worktree_basename(path, &n);
new_branch = xstrndup(s, n);
- } else if (opts.orphan || opts.detach) {
+ } else if (opts.orphan) {
// No-op
+ } else if (opts.detach) {
+ // Check HEAD
+ if (!strcmp(branch, "HEAD"))
+ can_use_local_refs(&opts);
} else if (ac < 2 && new_branch) {
// DWIM: Infer --orphan when repo has no refs.
opts.orphan = dwim_orphan(&opts, !!opt_track, 0);
@@ -854,6 +874,10 @@ static int add(int ac, const char **av, const char *prefix)
branch = remote;
}
}
+
+ if (!strcmp(branch, "HEAD"))
+ can_use_local_refs(&opts);
+
}
if (!opts.orphan && !lookup_commit_reference_by_name(branch)) {
diff --git a/t/t2400-worktree-add.sh b/t/t2400-worktree-add.sh
index c7ca8df586..0ac468e69e 100755
--- a/t/t2400-worktree-add.sh
+++ b/t/t2400-worktree-add.sh
@@ -722,6 +722,7 @@ test_dwim_orphan () {
local use_quiet=0 &&
local remote=0 &&
local remote_ref=0 &&
+ local use_detach=0 &&
local use_new_branch=0 &&
local outcome="$1" &&
@@ -747,6 +748,10 @@ test_dwim_orphan () {
success=0 &&
outcome_text='"add" error inferred "--orphan" gives illegal opts combo'
;;
+ "warn_bad_head")
+ success=0 &&
+ outcome_text='"add" error, warn on bad HEAD, hint use orphan'
+ ;;
*)
echo "test_dwim_orphan(): invalid outcome: '$outcome'" >&2 &&
return 1
@@ -818,7 +823,7 @@ test_dwim_orphan () {
context="$context, invalid (or orphan) HEAD"
;;
- # Whether the code path is tested with the base add command or -b
+ # Whether the code path is tested with the base add command, -b, or --detach
"no_-b")
use_new_branch=0 &&
context="$context, no --branch"
@@ -827,6 +832,10 @@ test_dwim_orphan () {
use_new_branch=1 &&
context="$context, --branch"
;;
+ "detach")
+ use_detach=1 &&
+ context="$context, --detach"
+ ;;
# Whether to check that all output is suppressed (except errors)
# or that the output is as expected
@@ -887,6 +896,9 @@ test_dwim_orphan () {
if [ $use_new_branch -eq 1 ]
then
args="$args -b foo"
+ elif [ $use_detach -eq 1 ]
+ then
+ args="$args --detach"
else
context="DWIM (no --branch), $context"
fi &&
@@ -1023,6 +1035,10 @@ do
test_dwim_orphan 'infer' $dwim_test_args -b no_local_ref remote no_remote_ref no_guess_remote
test_dwim_orphan 'infer' $dwim_test_args -b no_local_ref remote no_remote_ref guess_remote
test_dwim_orphan 'infer' $dwim_test_args -b no_local_ref remote remote_ref guess_remote
+
+ test_dwim_orphan 'warn_bad_head' $dwim_test_args no_-b local_ref bad_head
+ test_dwim_orphan 'warn_bad_head' $dwim_test_args -b local_ref bad_head
+ test_dwim_orphan 'warn_bad_head' $dwim_test_args detach local_ref bad_head
done
test_dwim_orphan 'fatal_orphan_bad_combo' $quiet_mode no_-b no_checkout
--
2.39.3
prev parent reply other threads:[~2023-05-17 21:49 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-04-17 9:33 [PATCH v9 0/8] worktree: Support `--orphan` when creating new worktrees Jacob Abel
2023-04-17 9:33 ` [PATCH v9 1/8] worktree add: include -B in usage docs Jacob Abel
2023-04-17 9:33 ` [PATCH v9 2/8] t2400: print captured git output when finished Jacob Abel
2023-04-17 21:09 ` Junio C Hamano
2023-04-18 3:53 ` Jacob Abel
2023-04-18 16:34 ` Junio C Hamano
2023-04-19 13:23 ` Jacob Abel
2023-04-19 13:36 ` Jacob Abel
2023-04-19 15:41 ` Junio C Hamano
2023-04-19 16:50 ` Jacob Abel
2023-04-17 9:33 ` [PATCH v9 3/8] t2400: refactor "worktree add" opt exclusion tests Jacob Abel
2023-04-17 21:30 ` Junio C Hamano
2023-04-20 2:46 ` Jacob Abel
2023-04-17 9:34 ` [PATCH v9 4/8] t2400: add tests to verify --quiet Jacob Abel
2023-04-17 21:33 ` Junio C Hamano
2023-04-20 2:48 ` Jacob Abel
2023-04-17 9:34 ` [PATCH v9 5/8] worktree add: add --orphan flag Jacob Abel
2023-04-17 9:34 ` [PATCH v9 6/8] worktree add: introduce "try --orphan" hint Jacob Abel
2023-04-17 9:34 ` [PATCH v9 7/8] worktree add: extend DWIM to infer --orphan Jacob Abel
2023-04-17 9:34 ` [PATCH v9 8/8] worktree add: emit warn when there is a bad HEAD Jacob Abel
2023-04-20 3:05 ` [PATCH v9 0/8] worktree: Support `--orphan` when creating new worktrees Jacob Abel
2023-05-01 21:51 ` Junio C Hamano
2023-05-02 5:48 ` Jacob Abel
2023-05-17 21:47 ` [RESEND PATCH v10 " Jacob Abel
2023-05-17 21:48 ` [RESEND PATCH v10 1/8] worktree add: include -B in usage docs Jacob Abel
2023-05-17 21:48 ` [RESEND PATCH v10 2/8] t2400: cleanup created worktree in test Jacob Abel
2023-05-17 21:48 ` [RESEND PATCH v10 3/8] t2400: refactor "worktree add" opt exclusion tests Jacob Abel
2023-05-17 21:48 ` [RESEND PATCH v10 4/8] t2400: add tests to verify --quiet Jacob Abel
2023-05-17 21:48 ` [RESEND PATCH v10 5/8] worktree add: add --orphan flag Jacob Abel
2023-05-17 21:48 ` [RESEND PATCH v10 6/8] worktree add: introduce "try --orphan" hint Jacob Abel
2023-05-17 21:48 ` [RESEND PATCH v10 7/8] worktree add: extend DWIM to infer --orphan Jacob Abel
2023-08-09 6:47 ` RESEND [PATCH " Teng Long
2023-08-11 17:43 ` Jacob Abel
2023-05-17 21:49 ` Jacob Abel [this message]
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=20230517214711.12467-9-jacobabel@nullpo.dev \
--to=jacobabel@nullpo.dev \
--cc=avarab@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=me@ttaylorr.com \
--cc=phillip.wood123@gmail.com \
--cc=rjusto@gmail.com \
--cc=rsbecker@nexbridge.com \
--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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.