From: Thomas Gummerer Date: Sun, 26 Nov 2017 19:43:55 GMT Subject: [PATCH v5 5/6] worktree: add --guess-remote flag to add subcommand Message-ID: <20171126194356.16187-6-t.gummerer@gmail.com> In-Reply-To: <20171126194356.16187-1-t.gummerer@gmail.com> Currently 'git worktree add ' creates a new branch named after the basename of the , that matches the HEAD of whichever worktree we were on when calling "git worktree add ". It's sometimes useful to have 'git worktree add behave more like the dwim machinery in 'git checkout ', i.e. check if the new branch name 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 --- Documentation/git-worktree.txt | 7 +++++++ builtin/worktree.c | 10 ++++++++++ t/t2025-worktree-add.sh | 29 +++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+) diff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt index 3044d305a6..a81cfb2229 100644 --- a/Documentation/git-worktree.txt +++ b/Documentation/git-worktree.txt @@ -115,6 +115,13 @@ OPTIONS such as configuring sparse-checkout. See "Sparse checkout" in linkgit:git-read-tree[1]. +--[no-]guess-remote:: + With `add`, instead of creating a new branch from HEAD when + `` is not given, if there exists a tracking branch + in exactly one remote matching the basename of the path, base + the new branch on the remote-tracking branch, and mark the + remote-tracking branch as "upstream" from the new branch. + --[no-]track:: When creating a new branch, if `` is a branch, mark it as "upstream" from the new branch. This is the diff --git a/builtin/worktree.c b/builtin/worktree.c index 7021d02585..15cb1600ee 100644 --- a/builtin/worktree.c +++ b/builtin/worktree.c @@ -343,6 +343,7 @@ static int add(int ac, const char **av, const char *prefix) char *path; const char *branch; const char *opt_track = NULL; + int guess_remote = 0; struct option options[] = { OPT__FORCE(&opts.force, N_("checkout even if already checked out in other worktree")), 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, 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_END() }; @@ -389,6 +392,13 @@ static int add(int ac, const char **av, const char *prefix) int n; const char *s = worktree_basename(path, &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) { diff --git a/t/t2025-worktree-add.sh b/t/t2025-worktree-add.sh index 96ebc63d04..d25c774cb7 100755 --- a/t/t2025-worktree-add.sh +++ b/t/t2025-worktree-add.sh @@ -384,4 +384,33 @@ test_expect_success '"add" 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 -- 2.15.0.426.gb06021eeb