worktree: add --guess-remote flag to add subcommand
Currently 'git worktree add <path>' creates a new branch named after the basename of the <path>, that matches the HEAD of whichever worktree we were on when calling "git worktree add <path>". It's sometimes useful to have 'git worktree add <path> behave more like the dwim machinery in 'git checkout <new-branch>', i.e. check if the new branch name, derived from the basename of the <path>, uniquely matches the branch name of a remote-tracking branch, and if so check out that branch and set the upstream to the remote-tracking branch. Add a new --guess-remote option that enables exactly that behaviour. Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
4e85333197
commit
71d6682d8c
@ -115,6 +115,13 @@ OPTIONS
|
|||||||
such as configuring sparse-checkout. See "Sparse checkout"
|
such as configuring sparse-checkout. See "Sparse checkout"
|
||||||
in linkgit:git-read-tree[1].
|
in linkgit:git-read-tree[1].
|
||||||
|
|
||||||
|
--[no-]guess-remote::
|
||||||
|
With `worktree add <path>`, without `<commit-ish>`, instead
|
||||||
|
of creating a new branch from HEAD, if there exists a tracking
|
||||||
|
branch in exactly one remote matching the basename of `<path>,
|
||||||
|
base the new branch on the remote-tracking branch, and mark
|
||||||
|
the remote-tracking branch as "upstream" from the new branch.
|
||||||
|
|
||||||
--[no-]track::
|
--[no-]track::
|
||||||
When creating a new branch, if `<commit-ish>` is a branch,
|
When creating a new branch, if `<commit-ish>` is a branch,
|
||||||
mark it as "upstream" from the new branch. This is the
|
mark it as "upstream" from the new branch. This is the
|
||||||
|
@ -343,6 +343,7 @@ static int add(int ac, const char **av, const char *prefix)
|
|||||||
char *path;
|
char *path;
|
||||||
const char *branch;
|
const char *branch;
|
||||||
const char *opt_track = NULL;
|
const char *opt_track = NULL;
|
||||||
|
int guess_remote = 0;
|
||||||
struct option options[] = {
|
struct option options[] = {
|
||||||
OPT__FORCE(&opts.force, N_("checkout <branch> even if already checked out in other worktree")),
|
OPT__FORCE(&opts.force, N_("checkout <branch> even if already checked out in other worktree")),
|
||||||
OPT_STRING('b', NULL, &opts.new_branch, N_("branch"),
|
OPT_STRING('b', NULL, &opts.new_branch, N_("branch"),
|
||||||
@ -355,6 +356,8 @@ static int add(int ac, const char **av, const char *prefix)
|
|||||||
OPT_PASSTHRU(0, "track", &opt_track, NULL,
|
OPT_PASSTHRU(0, "track", &opt_track, NULL,
|
||||||
N_("set up tracking mode (see git-branch(1))"),
|
N_("set up tracking mode (see git-branch(1))"),
|
||||||
PARSE_OPT_NOARG | PARSE_OPT_OPTARG),
|
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_END()
|
OPT_END()
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -389,6 +392,13 @@ static int add(int ac, const char **av, const char *prefix)
|
|||||||
int n;
|
int n;
|
||||||
const char *s = worktree_basename(path, &n);
|
const char *s = worktree_basename(path, &n);
|
||||||
opts.new_branch = xstrndup(s, n);
|
opts.new_branch = xstrndup(s, n);
|
||||||
|
if (guess_remote) {
|
||||||
|
struct object_id oid;
|
||||||
|
const char *remote =
|
||||||
|
unique_tracking_name(opts.new_branch, &oid);
|
||||||
|
if (remote)
|
||||||
|
branch = remote;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ac == 2 && !opts.new_branch && !opts.detach) {
|
if (ac == 2 && !opts.new_branch && !opts.detach) {
|
||||||
|
@ -384,4 +384,33 @@ test_expect_success '"add" <path> <branch> dwims' '
|
|||||||
)
|
)
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success 'git worktree add does not match remote' '
|
||||||
|
test_when_finished rm -rf repo_a repo_b foo &&
|
||||||
|
setup_remote_repo repo_a repo_b &&
|
||||||
|
(
|
||||||
|
cd repo_b &&
|
||||||
|
git worktree add ../foo
|
||||||
|
) &&
|
||||||
|
(
|
||||||
|
cd foo &&
|
||||||
|
test_must_fail git config "branch.foo.remote" &&
|
||||||
|
test_must_fail git config "branch.foo.merge" &&
|
||||||
|
! test_cmp_rev refs/remotes/repo_a/foo refs/heads/foo
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'git worktree add --guess-remote sets up tracking' '
|
||||||
|
test_when_finished rm -rf repo_a repo_b foo &&
|
||||||
|
setup_remote_repo repo_a repo_b &&
|
||||||
|
(
|
||||||
|
cd repo_b &&
|
||||||
|
git worktree add --guess-remote ../foo
|
||||||
|
) &&
|
||||||
|
(
|
||||||
|
cd foo &&
|
||||||
|
test_branch_upstream foo repo_a foo &&
|
||||||
|
test_cmp_rev refs/remotes/repo_a/foo refs/heads/foo
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
Loading…
Reference in New Issue
Block a user