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>
This commit is contained in:
Eric Sunshine 2015-07-06 13:30:59 -04:00 committed by Junio C Hamano
parent 0f4af3b9ea
commit 1eb07d829f
3 changed files with 26 additions and 4 deletions

View file

@ -9,7 +9,7 @@ git-worktree - Manage multiple worktrees
SYNOPSIS SYNOPSIS
-------- --------
[verse] [verse]
'git worktree add' [-f] [--detach] [-b <new-branch>] <path> <branch> 'git worktree add' [-f] [--detach] [-b <new-branch>] <path> [<branch>]
'git worktree prune' [-n] [-v] [--expire <expire>] 'git worktree prune' [-n] [-v] [--expire <expire>]
DESCRIPTION DESCRIPTION
@ -45,11 +45,15 @@ pruning should be suppressed. See section "DETAILS" for more information.
COMMANDS COMMANDS
-------- --------
add <path> <branch>:: add <path> [<branch>]::
Create `<path>` and checkout `<branch>` into it. The new working directory Create `<path>` and checkout `<branch>` into it. The new working directory
is linked to the current repository, sharing everything except working is linked to the current repository, sharing everything except working
directory specific files such as HEAD, index, etc. directory specific files such as HEAD, index, etc.
+
If `<branch>` is omitted and neither `-b` nor `-B` is used, then, as a
convenience, a new branch based at HEAD is created automatically, as if
`-b $(basename <path>)` was specified.
prune:: prune::

View file

@ -291,12 +291,16 @@ static int add(int ac, const char **av, const char *prefix)
die(_("-b and -B are mutually exclusive")); die(_("-b and -B are mutually exclusive"));
if (ac < 1 || ac > 2) if (ac < 1 || ac > 2)
usage_with_options(worktree_usage, options); usage_with_options(worktree_usage, options);
if (ac < 2 && !new_branch && !new_branch_force)
usage_with_options(worktree_usage, options);
path = prefix ? prefix_filename(prefix, strlen(prefix), av[0]) : av[0]; path = prefix ? prefix_filename(prefix, strlen(prefix), av[0]) : av[0];
branch = ac < 2 ? "HEAD" : av[1]; branch = ac < 2 ? "HEAD" : av[1];
if (ac < 2 && !new_branch && !new_branch_force) {
int n;
const char *s = worktree_basename(path, &n);
new_branch = xstrndup(s, n);
}
argv_array_push(&cmd, "checkout"); argv_array_push(&cmd, "checkout");
if (force) if (force)
argv_array_push(&cmd, "--ignore-other-worktrees"); argv_array_push(&cmd, "--ignore-other-worktrees");

View file

@ -145,4 +145,18 @@ test_expect_success '"add -b" with <branch> omitted' '
test_cmp_rev HEAD burble test_cmp_rev HEAD burble
' '
test_expect_success '"add" with <branch> omitted' '
git worktree add wiffle/bat &&
test_cmp_rev HEAD bat
'
test_expect_success '"add" auto-vivify does not clobber existing branch' '
test_commit c1 &&
test_commit c2 &&
git branch precious HEAD~1 &&
test_must_fail git worktree add precious &&
test_cmp_rev HEAD~1 precious &&
test_path_is_missing precious
'
test_done test_done