From c990a4c11dd7bb671da1b30e14568ad986621488 Mon Sep 17 00:00:00 2001 From: Eric Sunshine Date: Mon, 6 Jul 2015 13:30:45 -0400 Subject: checkout: fix bug with --to and relative HEAD Given "git checkout --to HEAD~1", the new worktree's HEAD should begin life at the current branch's HEAD~1, however, it actually ends up at HEAD~2. This happens because: 1. git-checkout resolves HEAD~1 2. to satisfy is_git_directory(), prepare_linked_worktree() creates a HEAD for the new worktree with the value of the resolved HEAD~1 3. git-checkout re-invokes itself with the same arguments within the new worktree to populate the worktree 4. the sub git-checkout resolves HEAD~1 relative to its own HEAD, which is the resolved HEAD~1 from the original invocation, resulting unexpectedly and incorrectly in HEAD~2 (relative to the original) Fix this by unconditionally assigning the current worktree's HEAD as the value of the new worktree's HEAD. As a side-effect, this change also eliminates a dependence within prepare_linked_checkout() upon 'struct branch_info'. The plan is to eventually relocate "git checkout --to" functionality to "git worktree add", and worktree.c won't have knowledge of 'struct branch_info', so removal of this dependency is a step toward that goal. Signed-off-by: Eric Sunshine Signed-off-by: Junio C Hamano --- t/t2025-checkout-to.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 't/t2025-checkout-to.sh') diff --git a/t/t2025-checkout-to.sh b/t/t2025-checkout-to.sh index a8d93366f6..0fd731b4bc 100755 --- a/t/t2025-checkout-to.sh +++ b/t/t2025-checkout-to.sh @@ -134,4 +134,14 @@ test_expect_success 'checkout with grafts' ' test_cmp expected actual ' +test_expect_success 'checkout --to from relative HEAD' ' + test_commit a && + test_commit b && + test_commit c && + git rev-parse HEAD~1 >expected && + git checkout --to relhead HEAD~1 && + git -C relhead rev-parse HEAD >actual && + test_cmp expected actual +' + test_done -- cgit v1.2.3 From f194b1ef6ee81788a45053fa6f7409233fc54276 Mon Sep 17 00:00:00 2001 From: Eric Sunshine Date: Mon, 6 Jul 2015 13:30:54 -0400 Subject: tests: worktree: retrofit "checkout --to" tests for "worktree add" With the introduction of "git worktree add", "git checkout --to" is slated for removal. Therefore, retrofit linked worktree creation tests to use "git worktree add" instead. (The test to check exclusivity of "checkout --to" and "checkout " is dropped altogether since it becomes meaningless with retirement of "checkout --to".) Signed-off-by: Eric Sunshine Signed-off-by: Junio C Hamano --- t/t2025-checkout-to.sh | 147 ------------------------------------------------- 1 file changed, 147 deletions(-) delete mode 100755 t/t2025-checkout-to.sh (limited to 't/t2025-checkout-to.sh') diff --git a/t/t2025-checkout-to.sh b/t/t2025-checkout-to.sh deleted file mode 100755 index 0fd731b4bc..0000000000 --- a/t/t2025-checkout-to.sh +++ /dev/null @@ -1,147 +0,0 @@ -#!/bin/sh - -test_description='test git checkout --to' - -. ./test-lib.sh - -test_expect_success 'setup' ' - test_commit init -' - -test_expect_success 'checkout --to not updating paths' ' - test_must_fail git checkout --to -- init.t -' - -test_expect_success 'checkout --to an existing worktree' ' - mkdir -p existing/subtree && - test_must_fail git checkout --detach --to existing master -' - -test_expect_success 'checkout --to an existing empty worktree' ' - mkdir existing_empty && - git checkout --detach --to existing_empty master -' - -test_expect_success 'checkout --to refuses to checkout locked branch' ' - test_must_fail git checkout --to zere master && - ! test -d zere && - ! test -d .git/worktrees/zere -' - -test_expect_success 'checking out paths not complaining about linked checkouts' ' - ( - cd existing_empty && - echo dirty >>init.t && - git checkout master -- init.t - ) -' - -test_expect_success 'checkout --to a new worktree' ' - git rev-parse HEAD >expect && - git checkout --detach --to here master && - ( - cd here && - test_cmp ../init.t init.t && - test_must_fail git symbolic-ref HEAD && - git rev-parse HEAD >actual && - test_cmp ../expect actual && - git fsck - ) -' - -test_expect_success 'checkout --to a new worktree from a subdir' ' - ( - mkdir sub && - cd sub && - git checkout --detach --to here master && - cd here && - test_cmp ../../init.t init.t - ) -' - -test_expect_success 'checkout --to from a linked checkout' ' - ( - cd here && - git checkout --detach --to nested-here master && - cd nested-here && - git fsck - ) -' - -test_expect_success 'checkout --to a new worktree creating new branch' ' - git checkout --to there -b newmaster master && - ( - cd there && - test_cmp ../init.t init.t && - git symbolic-ref HEAD >actual && - echo refs/heads/newmaster >expect && - test_cmp expect actual && - git fsck - ) -' - -test_expect_success 'die the same branch is already checked out' ' - ( - cd here && - test_must_fail git checkout newmaster - ) -' - -test_expect_success 'not die the same branch is already checked out' ' - ( - cd here && - git checkout --ignore-other-worktrees --to anothernewmaster newmaster - ) -' - -test_expect_success 'not die on re-checking out current branch' ' - ( - cd there && - git checkout newmaster - ) -' - -test_expect_success 'checkout --to from a bare repo' ' - ( - git clone --bare . bare && - cd bare && - git checkout --to ../there2 -b bare-master master - ) -' - -test_expect_success 'checkout from a bare repo without --to' ' - ( - cd bare && - test_must_fail git checkout master - ) -' - -test_expect_success 'checkout with grafts' ' - test_when_finished rm .git/info/grafts && - test_commit abc && - SHA1=`git rev-parse HEAD` && - test_commit def && - test_commit xyz && - echo "`git rev-parse HEAD` $SHA1" >.git/info/grafts && - cat >expected <<-\EOF && - xyz - abc - EOF - git log --format=%s -2 >actual && - test_cmp expected actual && - git checkout --detach --to grafted master && - git --git-dir=grafted/.git log --format=%s -2 >actual && - test_cmp expected actual -' - -test_expect_success 'checkout --to from relative HEAD' ' - test_commit a && - test_commit b && - test_commit c && - git rev-parse HEAD~1 >expected && - git checkout --to relhead HEAD~1 && - git -C relhead rev-parse HEAD >actual && - test_cmp expected actual -' - -test_done -- cgit v1.2.3