зеркало из https://github.com/microsoft/git.git
worktree add: introduce "try --orphan" hint
Add 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. Current Behavior: % git init foo Initialized empty Git repository in /path/to/foo/ % touch file % git -C foo commit -q -a -m "test commit" % git -C foo switch --orphan norefbranch % git -C foo worktree add newbranch/ Preparing worktree (new branch 'newbranch') fatal: invalid reference: HEAD % New Behavior: % git init --bare foo Initialized empty Git repository in /path/to/foo/ % touch file % git -C foo commit -q -a -m "test commit" % git -C foo switch --orphan norefbranch % git -C foo worktree add newbranch/ Preparing worktree (new branch 'newbranch') hint: If you meant to create a worktree containing a new orphan branch hint: (branch with no commits) for this repository, you can do so hint: using the --orphan option: hint: hint: git worktree add --orphan newbranch/ hint: hint: Disable this message with "git config advice.worktreeAddOrphan false" fatal: invalid reference: HEAD % git -C foo worktree add -b newbranch2 new_wt/ Preparing worktree (new branch 'newbranch') hint: If you meant to create a worktree containing a new orphan branch hint: (branch with no commits) for this repository, you can do so hint: using the --orphan option: hint: hint: git worktree add --orphan -b newbranch2 new_wt/ hint: hint: Disable this message with "git config advice.worktreeAddOrphan false" fatal: invalid reference: HEAD % Signed-off-by: Jacob Abel <jacobabel@nullpo.dev> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Родитель
7ab8918985
Коммит
35f0383ca6
|
@ -138,4 +138,8 @@ advice.*::
|
||||||
checkout.
|
checkout.
|
||||||
diverging::
|
diverging::
|
||||||
Advice shown when a fast-forward is not possible.
|
Advice shown when a fast-forward is not possible.
|
||||||
|
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.
|
||||||
--
|
--
|
||||||
|
|
1
advice.c
1
advice.c
|
@ -78,6 +78,7 @@ static struct {
|
||||||
[ADVICE_SUBMODULES_NOT_UPDATED] = { "submodulesNotUpdated", 1 },
|
[ADVICE_SUBMODULES_NOT_UPDATED] = { "submodulesNotUpdated", 1 },
|
||||||
[ADVICE_UPDATE_SPARSE_PATH] = { "updateSparsePath", 1 },
|
[ADVICE_UPDATE_SPARSE_PATH] = { "updateSparsePath", 1 },
|
||||||
[ADVICE_WAITING_FOR_EDITOR] = { "waitingForEditor", 1 },
|
[ADVICE_WAITING_FOR_EDITOR] = { "waitingForEditor", 1 },
|
||||||
|
[ADVICE_WORKTREE_ADD_ORPHAN] = { "worktreeAddOrphan", 1 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char turn_off_instructions[] =
|
static const char turn_off_instructions[] =
|
||||||
|
|
1
advice.h
1
advice.h
|
@ -49,6 +49,7 @@ struct string_list;
|
||||||
ADVICE_UPDATE_SPARSE_PATH,
|
ADVICE_UPDATE_SPARSE_PATH,
|
||||||
ADVICE_WAITING_FOR_EDITOR,
|
ADVICE_WAITING_FOR_EDITOR,
|
||||||
ADVICE_SKIPPED_CHERRY_PICKS,
|
ADVICE_SKIPPED_CHERRY_PICKS,
|
||||||
|
ADVICE_WORKTREE_ADD_ORPHAN,
|
||||||
};
|
};
|
||||||
|
|
||||||
int git_default_advice_config(const char *var, const char *value);
|
int git_default_advice_config(const char *var, const char *value);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
#include "abspath.h"
|
#include "abspath.h"
|
||||||
|
#include "advice.h"
|
||||||
#include "checkout.h"
|
#include "checkout.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "builtin.h"
|
#include "builtin.h"
|
||||||
|
@ -39,6 +40,20 @@
|
||||||
#define BUILTIN_WORKTREE_UNLOCK_USAGE \
|
#define BUILTIN_WORKTREE_UNLOCK_USAGE \
|
||||||
N_("git worktree unlock <worktree>")
|
N_("git worktree unlock <worktree>")
|
||||||
|
|
||||||
|
#define WORKTREE_ADD_ORPHAN_WITH_DASH_B_HINT_TEXT \
|
||||||
|
_("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 flag:\n" \
|
||||||
|
"\n" \
|
||||||
|
" git worktree add --orphan -b %s %s\n")
|
||||||
|
|
||||||
|
#define WORKTREE_ADD_ORPHAN_NO_DASH_B_HINT_TEXT \
|
||||||
|
_("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 flag:\n" \
|
||||||
|
"\n" \
|
||||||
|
" git worktree add --orphan %s\n")
|
||||||
|
|
||||||
static const char * const git_worktree_usage[] = {
|
static const char * const git_worktree_usage[] = {
|
||||||
BUILTIN_WORKTREE_ADD_USAGE,
|
BUILTIN_WORKTREE_ADD_USAGE,
|
||||||
BUILTIN_WORKTREE_LIST_USAGE,
|
BUILTIN_WORKTREE_LIST_USAGE,
|
||||||
|
@ -634,6 +649,7 @@ static int add(int ac, const char **av, const char *prefix)
|
||||||
const char *opt_track = NULL;
|
const char *opt_track = NULL;
|
||||||
const char *lock_reason = NULL;
|
const char *lock_reason = NULL;
|
||||||
int keep_locked = 0;
|
int keep_locked = 0;
|
||||||
|
int used_new_branch_options;
|
||||||
struct option options[] = {
|
struct option options[] = {
|
||||||
OPT__FORCE(&opts.force,
|
OPT__FORCE(&opts.force,
|
||||||
N_("checkout <branch> even if already checked out in other worktree"),
|
N_("checkout <branch> even if already checked out in other worktree"),
|
||||||
|
@ -686,6 +702,7 @@ static int add(int ac, const char **av, const char *prefix)
|
||||||
|
|
||||||
path = prefix_filename(prefix, av[0]);
|
path = prefix_filename(prefix, av[0]);
|
||||||
branch = ac < 2 ? "HEAD" : av[1];
|
branch = ac < 2 ? "HEAD" : av[1];
|
||||||
|
used_new_branch_options = new_branch || new_branch_force;
|
||||||
|
|
||||||
if (!strcmp(branch, "-"))
|
if (!strcmp(branch, "-"))
|
||||||
branch = "@{-1}";
|
branch = "@{-1}";
|
||||||
|
@ -728,6 +745,15 @@ static int add(int ac, const char **av, const char *prefix)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!opts.orphan && !lookup_commit_reference_by_name(branch)) {
|
if (!opts.orphan && !lookup_commit_reference_by_name(branch)) {
|
||||||
|
int attempt_hint = !opts.quiet && (ac < 2);
|
||||||
|
if (attempt_hint && used_new_branch_options) {
|
||||||
|
advise_if_enabled(ADVICE_WORKTREE_ADD_ORPHAN,
|
||||||
|
WORKTREE_ADD_ORPHAN_WITH_DASH_B_HINT_TEXT,
|
||||||
|
new_branch, path);
|
||||||
|
} else if (attempt_hint) {
|
||||||
|
advise_if_enabled(ADVICE_WORKTREE_ADD_ORPHAN,
|
||||||
|
WORKTREE_ADD_ORPHAN_NO_DASH_B_HINT_TEXT, path);
|
||||||
|
}
|
||||||
die(_("invalid reference: %s"), branch);
|
die(_("invalid reference: %s"), branch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -401,6 +401,43 @@ test_expect_success '"add" worktree with orphan branch, lock, and reason' '
|
||||||
test_cmp expect .git/worktrees/orphan-with-lock-reason/locked
|
test_cmp expect .git/worktrees/orphan-with-lock-reason/locked
|
||||||
'
|
'
|
||||||
|
|
||||||
|
# Note: Quoted arguments containing spaces are not supported.
|
||||||
|
test_wt_add_orphan_hint () {
|
||||||
|
local context="$1" &&
|
||||||
|
local use_branch=$2 &&
|
||||||
|
shift 2 &&
|
||||||
|
local opts="$*" &&
|
||||||
|
test_expect_success "'worktree add' show orphan hint in bad/orphan HEAD w/ $context" '
|
||||||
|
test_when_finished "rm -rf repo" &&
|
||||||
|
git init repo &&
|
||||||
|
(cd repo && test_commit commit) &&
|
||||||
|
git -C repo switch --orphan noref &&
|
||||||
|
test_must_fail git -C repo worktree add $opts foobar/ 2>actual &&
|
||||||
|
! grep "error: unknown switch" actual &&
|
||||||
|
grep "hint: If you meant to create a worktree containing a new orphan branch" actual &&
|
||||||
|
if [ $use_branch -eq 1 ]
|
||||||
|
then
|
||||||
|
grep -E "^hint:\s+git worktree add --orphan -b \S+ \S+\s*$" actual
|
||||||
|
else
|
||||||
|
grep -E "^hint:\s+git worktree add --orphan \S+\s*$" actual
|
||||||
|
fi
|
||||||
|
|
||||||
|
'
|
||||||
|
}
|
||||||
|
|
||||||
|
test_wt_add_orphan_hint 'no opts' 0
|
||||||
|
test_wt_add_orphan_hint '-b' 1 -b foobar_branch
|
||||||
|
test_wt_add_orphan_hint '-B' 1 -B foobar_branch
|
||||||
|
|
||||||
|
test_expect_success "'worktree add' doesn't show orphan hint in bad/orphan HEAD w/ --quiet" '
|
||||||
|
test_when_finished "rm -rf repo" &&
|
||||||
|
git init repo &&
|
||||||
|
(cd repo && test_commit commit) &&
|
||||||
|
test_must_fail git -C repo worktree add --quiet foobar_branch foobar/ 2>actual &&
|
||||||
|
! grep "error: unknown switch" actual &&
|
||||||
|
! grep "hint: If you meant to create a worktree containing a new orphan branch" actual
|
||||||
|
'
|
||||||
|
|
||||||
test_expect_success 'local clone from linked checkout' '
|
test_expect_success 'local clone from linked checkout' '
|
||||||
git clone --local here here-clone &&
|
git clone --local here here-clone &&
|
||||||
( cd here-clone && git fsck )
|
( cd here-clone && git fsck )
|
||||||
|
|
Загрузка…
Ссылка в новой задаче