Skip to content

Commit e284e89

Browse files
tgummerergitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent c4738ae commit e284e89

File tree

3 files changed

+65
-0
lines changed

3 files changed

+65
-0
lines changed

Documentation/git-worktree.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,12 @@ OPTIONS
107107
such as configuring sparse-checkout. See "Sparse checkout"
108108
in linkgit:git-read-tree[1].
109109

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+
110116
--lock::
111117
Keep the working tree locked after creation. This is the
112118
equivalent of `git worktree lock` after `git worktree add`,

builtin/worktree.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,7 @@ static int add(int ac, const char **av, const char *prefix)
341341
const char *new_branch_force = NULL;
342342
char *path;
343343
const char *branch;
344+
const char *opt_track = NULL;
344345
struct option options[] = {
345346
OPT__FORCE(&opts.force, N_("checkout <branch> even if already checked out in other worktree")),
346347
OPT_STRING('b', NULL, &opts.new_branch, N_("branch"),
@@ -350,6 +351,9 @@ static int add(int ac, const char **av, const char *prefix)
350351
OPT_BOOL(0, "detach", &opts.detach, N_("detach HEAD at named commit")),
351352
OPT_BOOL(0, "checkout", &opts.checkout, N_("populate the new working tree")),
352353
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),
353357
OPT_END()
354358
};
355359

@@ -394,9 +398,13 @@ static int add(int ac, const char **av, const char *prefix)
394398
argv_array_push(&cp.args, "--force");
395399
argv_array_push(&cp.args, opts.new_branch);
396400
argv_array_push(&cp.args, branch);
401+
if (opt_track)
402+
argv_array_push(&cp.args, opt_track);
397403
if (run_command(&cp))
398404
return -1;
399405
branch = opts.new_branch;
406+
} else if (opt_track) {
407+
die(_("--[no-]track can only be used if a new branch is created"));
400408
}
401409

402410
UNLEAK(path);

t/t2025-worktree-add.sh

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,5 +313,56 @@ test_expect_success 'checkout a branch under bisect' '
313313
test_expect_success 'rename a branch under bisect not allowed' '
314314
test_must_fail git branch -M under-bisect bisect-with-new-name
315315
'
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+
'
316367

317368
test_done

0 commit comments

Comments
 (0)