diff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt index 15e58b18f7..3044d305a6 100644 --- a/Documentation/git-worktree.txt +++ b/Documentation/git-worktree.txt @@ -52,6 +52,14 @@ is linked to the current repository, sharing everything except working directory specific files such as HEAD, index, etc. `-` may also be specified as ``; it is synonymous with `@{-1}`. + +If is a branch name (call it `` and is not found, +and neither `-b` nor `-B` nor `--detach` are used, but there does +exist a tracking branch in exactly one remote (call it ``) +with a matching name, treat as equivalent to +------------ +$ git worktree add --track -b / +------------ ++ If `` is omitted and neither `-b` nor `-B` nor `--detach` used, then, as a convenience, a new branch based at HEAD is created automatically, as if `-b $(basename )` was specified. diff --git a/builtin/worktree.c b/builtin/worktree.c index ea9678cac8..7021d02585 100644 --- a/builtin/worktree.c +++ b/builtin/worktree.c @@ -1,4 +1,5 @@ #include "cache.h" +#include "checkout.h" #include "config.h" #include "builtin.h" #include "dir.h" @@ -390,6 +391,21 @@ static int add(int ac, const char **av, const char *prefix) opts.new_branch = xstrndup(s, n); } + if (ac == 2 && !opts.new_branch && !opts.detach) { + struct object_id oid; + struct commit *commit; + const char *remote; + + commit = lookup_commit_reference_by_name(branch); + if (!commit) { + remote = unique_tracking_name(branch, &oid); + if (remote) { + opts.new_branch = branch; + branch = remote; + } + } + } + if (opts.new_branch) { struct child_process cp = CHILD_PROCESS_INIT; cp.git_cmd = 1; diff --git a/t/t2025-worktree-add.sh b/t/t2025-worktree-add.sh index 72e8b62927..96ebc63d04 100755 --- a/t/t2025-worktree-add.sh +++ b/t/t2025-worktree-add.sh @@ -365,4 +365,23 @@ test_expect_success '--no-track avoids setting up tracking' ' ) ' +test_expect_success '"add" fails' ' + test_must_fail git worktree add foo non-existent +' + +test_expect_success '"add" dwims' ' + test_when_finished rm -rf repo_upstream repo_dwim foo && + setup_remote_repo repo_upstream repo_dwim && + git init repo_dwim && + ( + cd repo_dwim && + git worktree add ../foo foo + ) && + ( + cd foo && + test_branch_upstream foo repo_upstream foo && + test_cmp_rev refs/remotes/repo_upstream/foo refs/heads/foo + ) +' + test_done