This is v3 of the series to replace "git checkout --to" with "git worktree add". It's built atop Duy's df0b6cf (worktree: new place for "git prune --worktrees", 2015-06-29). Thanks to Duy for his review of v2[*1*].
A v2 to v3 interdiff is included below for ease of review. Changes since v2: * retire --to from git-checkout documentation (v1 did this, but v2 forgot) * add "git worktree list" to the enumeration of not-yet-implemented commands in the BUGS section of the documentation * state only that "git worktree add" will create <path> rather than mentioning that a pre-existing <path> is valid as long as it is an empty directory[*2*] * fix comment stating that "any valid value" is acceptable as temporary HEAD in the newly created worktree, as patch 8/23 proves this to be false * use test_cmp_rev to simplify a couple new tests * minor grammatical fixes to documentation and a few commit messages [*1*]: http://thread.gmane.org/gmane.comp.version-control.git/273316 [*2*]: http://article.gmane.org/gmane.comp.version-control.git/273358 Eric Sunshine (23): Documentation/git-checkout: fix incorrect worktree prune command Documentation/git-worktree: associate options with commands Documentation: move linked worktree description from checkout to worktree Documentation/git-worktree: add BUGS section Documentation/git-worktree: split technical info from general description Documentation/git-worktree: add high-level 'lock' overview Documentation/git-worktree: add EXAMPLES section checkout: fix bug with --to and relative HEAD checkout: relocate --to's "no branch specified" check checkout: prepare_linked_checkout: drop now-unused 'new' argument checkout: make --to unconditionally verbose checkout: drop 'checkout_opts' dependency from prepare_linked_checkout worktree: introduce "add" command worktree: add --force option worktree: add --detach option worktree: add -b/-B options tests: worktree: retrofit "checkout --to" tests for "worktree add" checkout: retire --to option checkout: require worktree unconditionally worktree: extract basename computation to new function worktree: add: make -b/-B default to HEAD when <branch> is omitted worktree: add: auto-vivify new branch when <branch> is omitted checkout: retire --ignore-other-worktrees in favor of --force Documentation/git-checkout.txt | 81 +-------- Documentation/git-worktree.txt | 141 ++++++++++++++- builtin/checkout.c | 161 +----------------- builtin/worktree.c | 198 ++++++++++++++++++++++ git.c | 2 +- t/{t2025-checkout-to.sh => t2025-worktree-add.sh} | 64 ++++--- t/t2026-prune-linked-checkouts.sh | 2 +- t/t7410-submodule-checkout-to.sh | 4 +- 8 files changed, 382 insertions(+), 271 deletions(-) rename t/{t2025-checkout-to.sh => t2025-worktree-add.sh} (54%) -- 2.5.0.rc1.197.g417e668 --- 8< --- diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt index 41148ce..6c3085d 100644 --- a/Documentation/git-checkout.txt +++ b/Documentation/git-checkout.txt @@ -228,13 +228,6 @@ This means that you can use `git checkout -p` to selectively discard edits from your current working tree. See the ``Interactive Mode'' section of linkgit:git-add[1] to learn how to operate the `--patch` mode. ---to=<path>:: - Check out a branch in a separate working directory at - `<path>`. A new working directory is linked to the current - repository, sharing everything except working directory - specific files such as HEAD, index, etc. See - linkgit:git-worktree[1] for a description of linked worktrees. - <branch>:: Branch to checkout; if it refers to a branch (i.e., a name that, when prepended with "refs/heads/", is a valid ref), then that diff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt index 938bdab..da71f50 100644 --- a/Documentation/git-worktree.txt +++ b/Documentation/git-worktree.txt @@ -47,13 +47,12 @@ COMMANDS -------- add <path> [<branch>]:: -Check out `<branch>` into a separate working directory, `<path>`, creating -`<path>` if necessary. The new working directory is linked to the current -repository, sharing everything except working directory specific files -such as HEAD, index, etc. If `<path>` already exists, it must be empty. +Create `<path>` and checkout `<branch>` into it. The new working directory +is linked to the current repository, sharing everything except working +directory specific files such as HEAD, index, etc. + -If `<branch>` is omitted and neither `-b` nor `-B` used, then, as a -convenience, a new branch rooted at HEAD is created automatically, as if +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:: @@ -137,10 +136,10 @@ linkgit:gitrepository-layout[5] for details. EXAMPLES -------- -You are middle of a refactoring session and your boss comes in and demands -that you fix something immediately. You might typically use +You are in the middle of a refactoring session and your boss comes in and +demands that you fix something immediately. You might typically use linkgit:git-stash[1] to store your changes away temporarily, however, your -worktree is in such a state of disarray (with new, removed, moved files, +worktree is in such a state of disarray (with new, moved, and removed files, and other bits and pieces strewn around) that you don't want to risk disturbing any of it. Instead, you create a temporary linked worktree to make the emergency fix, remove it when done, and then resume your earlier @@ -167,6 +166,7 @@ performed manually, such as: - `remove` to remove a linked worktree and its administrative files (and warn if the worktree is dirty) - `mv` to move or rename a worktree and update its administrative files +- `list` to list linked worktrees - `lock` to prevent automatic pruning of administrative files (for instance, for a worktree on a portable device) diff --git a/builtin/worktree.c b/builtin/worktree.c index 8a6c7fa..050b443 100644 --- a/builtin/worktree.c +++ b/builtin/worktree.c @@ -227,9 +227,14 @@ static int add_worktree(const char *path, const char **child_argv) real_path(get_git_common_dir()), name); /* * This is to keep resolve_ref() happy. We need a valid HEAD - * or is_git_directory() will reject the directory. Any valid - * value would do because this value will be ignored and - * replaced at the next (real) checkout. + * or is_git_directory() will reject the directory. Moreover, HEAD + * in the new worktree must resolve to the same value as HEAD in + * the current tree since the command invoked to populate the new + * worktree will be handed the branch/ref specified by the user. + * For instance, if the user asks for the new worktree to be based + * at HEAD~5, then the resolved HEAD~5 in the new worktree must + * match the resolved HEAD~5 in the current tree in order to match + * the user's expectation. */ if (!resolve_ref_unsafe("HEAD", 0, rev, NULL)) die(_("unable to resolve HEAD")); diff --git a/t/t2025-worktree-add.sh b/t/t2025-worktree-add.sh index 59d73ff..8fe242f 100755 --- a/t/t2025-worktree-add.sh +++ b/t/t2025-worktree-add.sh @@ -141,17 +141,13 @@ test_expect_success '"add" from relative HEAD' ' ' test_expect_success '"add -b" with <branch> omitted' ' - git rev-parse HEAD >expected && git worktree add -b burble flornk && - git rev-parse burble >actual && - test_cmp expected actual + test_cmp_rev HEAD burble ' test_expect_success '"add" with <branch> omitted' ' - git rev-parse HEAD >expected && git worktree add wiffle/bat && - git rev-parse bat >actual && - test_cmp expected actual + test_cmp_rev HEAD bat ' test_done --- 8< --- -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html