worktree: add: auto-vivify new branch when <branch> is omitted

As a convenience, when <branch> is omitted from "git worktree <path> <branch>" and neither -b nor -B is used, automatically create a new branch named after <path>, as if "-b $(basename <path>)" was specified. Thus, "git worktree add ../hotfix" creates a new branch named "hotfix" and associates it with new worktree "../hotfix". Signed-off-by: Eric Sunshine <sunshine@sunshineco.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Eric Sunshine committed Jul 6, 2015 at 13:30 UTC 1eb07d829f3f0992c93c6b44fdcc4e95ebab12f3
3 files changed +26 -4
Documentation/git-worktree.txt
+6 -2
@@ -9,7 +9,7 @@ git-worktree - Manage multiple worktrees
9 SYNOPSIS
10 --------
11 [verse]
12 -'git worktree add' [-f] [--detach] [-b <new-branch>] <path> <branch>
12 +'git worktree add' [-f] [--detach] [-b <new-branch>] <path> [<branch>]
13 'git worktree prune' [-n] [-v] [--expire <expire>]
14
15 DESCRIPTION
@@ -45,11 +45,15 @@ pruning should be suppressed. See section "DETAILS" for more information.
45
46 COMMANDS
47 --------
48 -add <path> <branch>::
48 +add <path> [<branch>]::
49
50 Create `<path>` and checkout `<branch>` into it. The new working directory
51 is linked to the current repository, sharing everything except working
52 directory specific files such as HEAD, index, etc.
53 ++
54 +If `<branch>` is omitted and neither `-b` nor `-B` is used, then, as a
55 +convenience, a new branch based at HEAD is created automatically, as if
56 +`-b $(basename <path>)` was specified.
57
58 prune::
59
builtin/worktree.c
+6 -2
@@ -291,12 +291,16 @@ static int add(int ac, const char **av, const char *prefix)
291 die(_("-b and -B are mutually exclusive"));
292 if (ac < 1 || ac > 2)
293 usage_with_options(worktree_usage, options);
294 - if (ac < 2 && !new_branch && !new_branch_force)
295 - usage_with_options(worktree_usage, options);
294
295 path = prefix ? prefix_filename(prefix, strlen(prefix), av[0]) : av[0];
296 branch = ac < 2 ? "HEAD" : av[1];
297
298 + if (ac < 2 && !new_branch && !new_branch_force) {
299 + int n;
300 + const char *s = worktree_basename(path, &n);
301 + new_branch = xstrndup(s, n);
302 + }
303 +
304 argv_array_push(&cmd, "checkout");
305 if (force)
306 argv_array_push(&cmd, "--ignore-other-worktrees");
t/t2025-worktree-add.sh
+14
@@ -145,4 +145,18 @@ test_expect_success '"add -b" with <branch> omitted' '
145 test_cmp_rev HEAD burble
146 '
147
148 +test_expect_success '"add" with <branch> omitted' '
149 + git worktree add wiffle/bat &&
150 + test_cmp_rev HEAD bat
151 +'
152 +
153 +test_expect_success '"add" auto-vivify does not clobber existing branch' '
154 + test_commit c1 &&
155 + test_commit c2 &&
156 + git branch precious HEAD~1 &&
157 + test_must_fail git worktree add precious &&
158 + test_cmp_rev HEAD~1 precious &&
159 + test_path_is_missing precious
160 +'
161 +
162 test_done