worktree: add --[no-]track option to the add subcommand

Currently 'git worktree add' sets up tracking branches if '<branch>' is a remote tracking branch, and doesn't set them up otherwise, as is the default for 'git branch'. This may or may not be what the user wants. Allow overriding this behaviour with a --[no-]track flag that gets passed through to 'git branch'. We already respect branch.autoSetupMerge, as 'git worktree' just calls 'git branch' internally. Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Thomas Gummerer committed Nov 26, 2017 at 19:43 UTC e284e892ca278e4eb1e7eabd53a000bc897c3f25
3 files changed +65
Documentation/git-worktree.txt
+6
@@ -107,6 +107,12 @@ OPTIONS
107 such as configuring sparse-checkout. See "Sparse checkout"
108 in linkgit:git-read-tree[1].
109
110 +--[no-]track::
111 + When creating a new branch, if `<commit-ish>` is a branch,
112 + mark it as "upstream" from the new branch. This is the
113 + default if `<commit-ish>` is a remote-tracking branch. See
114 + "--track" in linkgit:git-branch[1] for details.
115 +
116 --lock::
117 Keep the working tree locked after creation. This is the
118 equivalent of `git worktree lock` after `git worktree add`,
builtin/worktree.c
+8
@@ -341,6 +341,7 @@ static int add(int ac, const char **av, const char *prefix)
341 const char *new_branch_force = NULL;
342 char *path;
343 const char *branch;
344 + const char *opt_track = NULL;
345 struct option options[] = {
346 OPT__FORCE(&opts.force, N_("checkout <branch> even if already checked out in other worktree")),
347 OPT_STRING('b', NULL, &opts.new_branch, N_("branch"),
@@ -350,6 +351,9 @@ static int add(int ac, const char **av, const char *prefix)
351 OPT_BOOL(0, "detach", &opts.detach, N_("detach HEAD at named commit")),
352 OPT_BOOL(0, "checkout", &opts.checkout, N_("populate the new working tree")),
353 OPT_BOOL(0, "lock", &opts.keep_locked, N_("keep the new working tree locked")),
354 + OPT_PASSTHRU(0, "track", &opt_track, NULL,
355 + N_("set up tracking mode (see git-branch(1))"),
356 + PARSE_OPT_NOARG | PARSE_OPT_OPTARG),
357 OPT_END()
358 };
359
@@ -394,9 +398,13 @@ static int add(int ac, const char **av, const char *prefix)
398 argv_array_push(&cp.args, "--force");
399 argv_array_push(&cp.args, opts.new_branch);
400 argv_array_push(&cp.args, branch);
401 + if (opt_track)
402 + argv_array_push(&cp.args, opt_track);
403 if (run_command(&cp))
404 return -1;
405 branch = opts.new_branch;
406 + } else if (opt_track) {
407 + die(_("--[no-]track can only be used if a new branch is created"));
408 }
409
410 UNLEAK(path);
t/t2025-worktree-add.sh
+51
@@ -313,5 +313,56 @@ test_expect_success 'checkout a branch under bisect' '
313 test_expect_success 'rename a branch under bisect not allowed' '
314 test_must_fail git branch -M under-bisect bisect-with-new-name
315 '
316 +# Is branch "refs/heads/$1" set to pull from "$2/$3"?
317 +test_branch_upstream () {
318 + printf "%s\n" "$2" "refs/heads/$3" >expect.upstream &&
319 + {
320 + git config "branch.$1.remote" &&
321 + git config "branch.$1.merge"
322 + } >actual.upstream &&
323 + test_cmp expect.upstream actual.upstream
324 +}
325 +
326 +test_expect_success '--track sets up tracking' '
327 + test_when_finished rm -rf track &&
328 + git worktree add --track -b track track master &&
329 + test_branch_upstream track . master
330 +'
331 +
332 +# setup remote repository $1 and repository $2 with $1 set up as
333 +# remote. The remote has two branches, master and foo.
334 +setup_remote_repo () {
335 + git init $1 &&
336 + (
337 + cd $1 &&
338 + test_commit $1_master &&
339 + git checkout -b foo &&
340 + test_commit upstream_foo
341 + ) &&
342 + git init $2 &&
343 + (
344 + cd $2 &&
345 + test_commit $2_master &&
346 + git remote add $1 ../$1 &&
347 + git config remote.$1.fetch \
348 + "refs/heads/*:refs/remotes/$1/*" &&
349 + git fetch --all
350 + )
351 +}
352 +
353 +test_expect_success '--no-track avoids setting up tracking' '
354 + test_when_finished rm -rf repo_upstream repo_local foo &&
355 + setup_remote_repo repo_upstream repo_local &&
356 + (
357 + cd repo_local &&
358 + git worktree add --no-track -b foo ../foo repo_upstream/foo
359 + ) &&
360 + (
361 + cd foo &&
362 + test_must_fail git config "branch.foo.remote" &&
363 + test_must_fail git config "branch.foo.merge" &&
364 + test_cmp_rev refs/remotes/repo_upstream/foo refs/heads/foo
365 + )
366 +'
367
368 test_done