@@ -352,12 +352,11 @@ DETAILS
-------
Each linked worktree has a private sub-directory in the repository's
`$GIT_DIR/worktrees` directory. The private sub-directory's name is usually
-the base name of the linked worktree's path, possibly appended with a
+the base name of the linked worktree's path, appended with a random
number to make it unique. For example, when `$GIT_DIR=/path/main/.git` the
command `git worktree add /path/other/test-next next` creates the linked
worktree in `/path/other/test-next` and also creates a
-`$GIT_DIR/worktrees/test-next` directory (or `$GIT_DIR/worktrees/test-next1`
-if `test-next` is already taken).
+`$GIT_DIR/worktrees/test-next-#######` directory.
Within a linked worktree, `$GIT_DIR` is set to point to this private
directory (e.g. `/path/main/.git/worktrees/test-next` in the example) and
@@ -421,6 +421,7 @@ static int add_worktree(const char *path, const char *refname,
struct strbuf sb_git = STRBUF_INIT, sb_repo = STRBUF_INIT;
struct strbuf sb = STRBUF_INIT;
const char *name;
+ const char *suffix;
struct strvec child_env = STRVEC_INIT;
unsigned int counter = 0;
int len, ret;
@@ -455,6 +456,11 @@ static int add_worktree(const char *path, const char *refname,
strbuf_reset(&sb);
name = sb_name.buf;
git_path_buf(&sb_repo, "worktrees/%s", name);
+ suffix = getenv("GIT_TEST_WORKTREE_SUFFIX");
+ if (suffix)
+ strbuf_addf(&sb_repo, "-%s", suffix);
+ else
+ strbuf_addf(&sb_repo, "-%u", git_rand());
len = sb_repo.len;
if (safe_create_leading_directories_const(sb_repo.buf))
die_errno(_("could not create leading directories of '%s'"),
@@ -41,7 +41,7 @@ test_expect_success 'setup an embedded bare repo, secondary worktree and submodu
git -c protocol.file.allow=always \
submodule add --name subn -- ./bare-repo subd
) &&
- test_path_is_dir outer-repo/.git/worktrees/outer-secondary &&
+ test_path_is_dir outer-repo/.git/worktrees/outer-secondary-* &&
test_path_is_dir outer-repo/.git/modules/subn
'
@@ -97,7 +97,7 @@ test_expect_success 'no trace when "bare repository" is a subdir of .git' '
'
test_expect_success 'no trace in $GIT_DIR of secondary worktree' '
- expect_accepted_implicit -C outer-repo/.git/worktrees/outer-secondary
+ expect_accepted_implicit -C outer-repo/.git/worktrees/outer-secondary-*
'
test_expect_success 'no trace in $GIT_DIR of a submodule' '
@@ -256,12 +256,12 @@ test_expect_success 'delete fails cleanly if packed-refs.new write fails' '
test_cmp unchanged actual
'
-RWT="test-tool ref-store worktree:wt"
+RWT="test-tool ref-store worktree:wt-123"
RMAIN="test-tool ref-store worktree:main"
test_expect_success 'setup worktree' '
test_commit first &&
- git worktree add -b wt-main wt &&
+ GIT_TEST_WORKTREE_SUFFIX=123 git worktree add -b wt-main wt &&
(
cd wt &&
test_commit second
@@ -279,9 +279,9 @@ test_expect_success 'for_each_reflog()' '
mkdir -p .git/logs/refs/bisect &&
echo $ZERO_OID >.git/logs/refs/bisect/random &&
- echo $ZERO_OID >.git/worktrees/wt/logs/PSEUDO_WT_HEAD &&
- mkdir -p .git/worktrees/wt/logs/refs/bisect &&
- echo $ZERO_OID >.git/worktrees/wt/logs/refs/bisect/wt-random &&
+ echo $ZERO_OID >.git/worktrees/wt-123/logs/PSEUDO_WT_HEAD &&
+ mkdir -p .git/worktrees/wt-123/logs/refs/bisect &&
+ echo $ZERO_OID >.git/worktrees/wt-123/logs/refs/bisect/wt-random &&
$RWT for-each-reflog >actual &&
cat >expected <<-\EOF &&
@@ -326,8 +326,8 @@ test_expect_success 'refs/worktree must not be packed' '
git pack-refs --all &&
test_path_is_missing .git/refs/tags/wt1 &&
test_path_is_file .git/refs/worktree/foo &&
- test_path_is_file .git/worktrees/wt1/refs/worktree/foo &&
- test_path_is_file .git/worktrees/wt2/refs/worktree/foo
+ test_path_is_file .git/worktrees/wt1-*/refs/worktree/foo &&
+ test_path_is_file .git/worktrees/wt2-*/refs/worktree/foo
'
# we do not want to count on running pack-refs to
@@ -965,11 +965,11 @@ test_expect_success 'worktree: adding worktree creates separate stack' '
test_commit -C repo A &&
git -C repo worktree add ../worktree &&
- test_path_is_file repo/.git/worktrees/worktree/refs/heads &&
+ test_path_is_file repo/.git/worktrees/worktree-*/refs/heads &&
echo "ref: refs/heads/.invalid" >expect &&
- test_cmp expect repo/.git/worktrees/worktree/HEAD &&
- test_path_is_dir repo/.git/worktrees/worktree/reftable &&
- test_path_is_file repo/.git/worktrees/worktree/reftable/tables.list
+ test_cmp expect repo/.git/worktrees/worktree-*/HEAD &&
+ test_path_is_dir repo/.git/worktrees/worktree-*/reftable &&
+ test_path_is_file repo/.git/worktrees/worktree-*/reftable/tables.list
'
test_expect_success 'worktree: pack-refs in main repo packs main refs' '
@@ -982,10 +982,10 @@ test_expect_success 'worktree: pack-refs in main repo packs main refs' '
GIT_TEST_REFTABLE_AUTOCOMPACTION=false \
git -C worktree update-ref refs/worktree/per-worktree HEAD &&
- test_line_count = 4 repo/.git/worktrees/worktree/reftable/tables.list &&
+ test_line_count = 4 repo/.git/worktrees/worktree-*/reftable/tables.list &&
test_line_count = 3 repo/.git/reftable/tables.list &&
git -C repo pack-refs &&
- test_line_count = 4 repo/.git/worktrees/worktree/reftable/tables.list &&
+ test_line_count = 4 repo/.git/worktrees/worktree-*/reftable/tables.list &&
test_line_count = 1 repo/.git/reftable/tables.list
'
@@ -999,10 +999,10 @@ test_expect_success 'worktree: pack-refs in worktree packs worktree refs' '
GIT_TEST_REFTABLE_AUTOCOMPACTION=false \
git -C worktree update-ref refs/worktree/per-worktree HEAD &&
- test_line_count = 4 repo/.git/worktrees/worktree/reftable/tables.list &&
+ test_line_count = 4 repo/.git/worktrees/worktree-*/reftable/tables.list &&
test_line_count = 3 repo/.git/reftable/tables.list &&
git -C worktree pack-refs &&
- test_line_count = 1 repo/.git/worktrees/worktree/reftable/tables.list &&
+ test_line_count = 1 repo/.git/worktrees/worktree-*/reftable/tables.list &&
test_line_count = 3 repo/.git/reftable/tables.list
'
@@ -1014,12 +1014,12 @@ test_expect_success 'worktree: creating shared ref updates main stack' '
git -C repo worktree add ../worktree &&
git -C repo pack-refs &&
git -C worktree pack-refs &&
- test_line_count = 1 repo/.git/worktrees/worktree/reftable/tables.list &&
+ test_line_count = 1 repo/.git/worktrees/worktree-*/reftable/tables.list &&
test_line_count = 1 repo/.git/reftable/tables.list &&
GIT_TEST_REFTABLE_AUTOCOMPACTION=false \
git -C worktree update-ref refs/heads/shared HEAD &&
- test_line_count = 1 repo/.git/worktrees/worktree/reftable/tables.list &&
+ test_line_count = 1 repo/.git/worktrees/worktree-*/reftable/tables.list &&
test_line_count = 2 repo/.git/reftable/tables.list
'
@@ -1031,11 +1031,11 @@ test_expect_success 'worktree: creating per-worktree ref updates worktree stack'
git -C repo worktree add ../worktree &&
git -C repo pack-refs &&
git -C worktree pack-refs &&
- test_line_count = 1 repo/.git/worktrees/worktree/reftable/tables.list &&
+ test_line_count = 1 repo/.git/worktrees/worktree-*/reftable/tables.list &&
test_line_count = 1 repo/.git/reftable/tables.list &&
git -C worktree update-ref refs/bisect/per-worktree HEAD &&
- test_line_count = 2 repo/.git/worktrees/worktree/reftable/tables.list &&
+ test_line_count = 2 repo/.git/worktrees/worktree-*/reftable/tables.list &&
test_line_count = 1 repo/.git/reftable/tables.list
'
@@ -1044,14 +1044,14 @@ test_expect_success 'worktree: creating per-worktree ref from main repo' '
git init repo &&
test_commit -C repo A &&
- git -C repo worktree add ../worktree &&
+ GIT_TEST_WORKTREE_SUFFIX=456 git -C repo worktree add ../worktree &&
git -C repo pack-refs &&
git -C worktree pack-refs &&
- test_line_count = 1 repo/.git/worktrees/worktree/reftable/tables.list &&
+ test_line_count = 1 repo/.git/worktrees/worktree-456/reftable/tables.list &&
test_line_count = 1 repo/.git/reftable/tables.list &&
- git -C repo update-ref worktrees/worktree/refs/bisect/per-worktree HEAD &&
- test_line_count = 2 repo/.git/worktrees/worktree/reftable/tables.list &&
+ git -C repo update-ref worktrees/worktree-456/refs/bisect/per-worktree HEAD &&
+ test_line_count = 2 repo/.git/worktrees/worktree-456/reftable/tables.list &&
test_line_count = 1 repo/.git/reftable/tables.list
'
@@ -1060,18 +1060,18 @@ test_expect_success 'worktree: creating per-worktree ref from second worktree' '
git init repo &&
test_commit -C repo A &&
- git -C repo worktree add ../wt1 &&
- git -C repo worktree add ../wt2 &&
+ GIT_TEST_WORKTREE_SUFFIX=123 git -C repo worktree add ../wt1 &&
+ GIT_TEST_WORKTREE_SUFFIX=456 git -C repo worktree add ../wt2 &&
git -C repo pack-refs &&
git -C wt1 pack-refs &&
git -C wt2 pack-refs &&
- test_line_count = 1 repo/.git/worktrees/wt1/reftable/tables.list &&
- test_line_count = 1 repo/.git/worktrees/wt2/reftable/tables.list &&
+ test_line_count = 1 repo/.git/worktrees/wt1-123/reftable/tables.list &&
+ test_line_count = 1 repo/.git/worktrees/wt2-456/reftable/tables.list &&
test_line_count = 1 repo/.git/reftable/tables.list &&
- git -C wt1 update-ref worktrees/wt2/refs/bisect/per-worktree HEAD &&
- test_line_count = 1 repo/.git/worktrees/wt1/reftable/tables.list &&
- test_line_count = 2 repo/.git/worktrees/wt2/reftable/tables.list &&
+ git -C wt1 update-ref worktrees/wt2-456/refs/bisect/per-worktree HEAD &&
+ test_line_count = 1 repo/.git/worktrees/wt1-123/reftable/tables.list &&
+ test_line_count = 2 repo/.git/worktrees/wt2-456/reftable/tables.list &&
test_line_count = 1 repo/.git/reftable/tables.list
'
@@ -1080,18 +1080,18 @@ test_expect_success 'worktree: can create shared and per-worktree ref in one tra
git init repo &&
test_commit -C repo A &&
- git -C repo worktree add ../worktree &&
+ GIT_TEST_WORKTREE_SUFFIX=123 git -C repo worktree add ../worktree &&
git -C repo pack-refs &&
git -C worktree pack-refs &&
- test_line_count = 1 repo/.git/worktrees/worktree/reftable/tables.list &&
+ test_line_count = 1 repo/.git/worktrees/worktree-123/reftable/tables.list &&
test_line_count = 1 repo/.git/reftable/tables.list &&
cat >stdin <<-EOF &&
- create worktrees/worktree/refs/bisect/per-worktree HEAD
+ create worktrees/worktree-123/refs/bisect/per-worktree HEAD
create refs/branches/shared HEAD
EOF
git -C repo update-ref --stdin <stdin &&
- test_line_count = 2 repo/.git/worktrees/worktree/reftable/tables.list &&
+ test_line_count = 2 repo/.git/worktrees/worktree-123/reftable/tables.list &&
test_line_count = 2 repo/.git/reftable/tables.list
'
@@ -8,12 +8,12 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
-RWT="test-tool ref-store worktree:wt"
+RWT="test-tool ref-store worktree:wt-456"
RMAIN="test-tool ref-store worktree:main"
test_expect_success 'setup' '
test_commit first &&
- git worktree add -b wt-main wt &&
+ GIT_TEST_WORKTREE_SUFFIX=456 git worktree add -b wt-main wt &&
(
cd wt &&
test_commit second
@@ -402,12 +402,12 @@ test_expect_success 'expire with multiple worktrees' '
cd main-wt &&
test_tick &&
test_commit foo &&
- git worktree add link-wt &&
+ GIT_TEST_WORKTREE_SUFFIX=123 git worktree add link-wt &&
test_tick &&
test_commit -C link-wt foobar &&
test_tick &&
git reflog expire --verbose --all --expire=$test_tick &&
- test-tool ref-store worktree:link-wt for-each-reflog-ent HEAD >actual &&
+ test-tool ref-store worktree:link-wt-123 for-each-reflog-ent HEAD >actual &&
test_must_be_empty actual
)
'
@@ -418,17 +418,17 @@ test_expect_success 'expire one of multiple worktrees' '
cd main-wt2 &&
test_tick &&
test_commit foo &&
- git worktree add link-wt &&
+ GIT_TEST_WORKTREE_SUFFIX=456 git worktree add link-wt &&
test_tick &&
test_commit -C link-wt foobar &&
test_tick &&
- test-tool ref-store worktree:link-wt for-each-reflog-ent HEAD \
+ test-tool ref-store worktree:link-wt-456 for-each-reflog-ent HEAD \
>expect-link-wt &&
git reflog expire --verbose --all --expire=$test_tick \
--single-worktree &&
test-tool ref-store worktree:main for-each-reflog-ent HEAD \
>actual-main &&
- test-tool ref-store worktree:link-wt for-each-reflog-ent HEAD \
+ test-tool ref-store worktree:link-wt-456 for-each-reflog-ent HEAD \
>actual-link-wt &&
test_must_be_empty actual-main &&
test_cmp expect-link-wt actual-link-wt
@@ -9,8 +9,8 @@ test_expect_success 'setup' '
test_commit initial &&
test_commit wt1 &&
test_commit wt2 &&
- git worktree add wt1 wt1 &&
- git worktree add wt2 wt2 &&
+ GIT_TEST_WORKTREE_SUFFIX=123 git worktree add wt1 wt1 &&
+ GIT_TEST_WORKTREE_SUFFIX=456 git worktree add wt2 wt2 &&
git checkout initial &&
git update-ref refs/worktree/foo HEAD &&
git -C wt1 update-ref refs/worktree/foo HEAD &&
@@ -37,16 +37,16 @@ test_expect_success 'ambiguous main-worktree/HEAD' '
'
test_expect_success 'resolve worktrees/xx/HEAD' '
- test_cmp_rev worktrees/wt1/HEAD wt1 &&
- ( cd wt1 && test_cmp_rev worktrees/wt1/HEAD wt1 ) &&
- ( cd wt2 && test_cmp_rev worktrees/wt1/HEAD wt1 )
+ test_cmp_rev worktrees/wt1-123/HEAD wt1 &&
+ ( cd wt1 && test_cmp_rev worktrees/wt1-123/HEAD wt1 ) &&
+ ( cd wt2 && test_cmp_rev worktrees/wt1-123/HEAD wt1 )
'
test_expect_success 'ambiguous worktrees/xx/HEAD' '
- git update-ref refs/heads/worktrees/wt1/HEAD $(git rev-parse HEAD) &&
- test_when_finished git update-ref -d refs/heads/worktrees/wt1/HEAD &&
- git rev-parse worktrees/wt1/HEAD 2>warn &&
- grep "worktrees/wt1/HEAD.*ambiguous" warn
+ git update-ref refs/heads/worktrees/wt1-123/HEAD $(git rev-parse HEAD) &&
+ test_when_finished git update-ref -d refs/heads/worktrees/wt1-123/HEAD &&
+ git rev-parse worktrees/wt1-123/HEAD 2>warn &&
+ grep "worktrees/wt1-123/HEAD.*ambiguous" warn
'
test_expect_success 'reflog of main-worktree/HEAD' '
@@ -58,12 +58,12 @@ test_expect_success 'reflog of main-worktree/HEAD' '
'
test_expect_success 'reflog of worktrees/xx/HEAD' '
- git -C wt2 reflog HEAD | sed "s/HEAD/worktrees\/wt2\/HEAD/" >expected &&
- git reflog worktrees/wt2/HEAD >actual &&
+ git -C wt2 reflog HEAD | sed "s/HEAD/worktrees\/wt2-456\/HEAD/" >expected &&
+ git reflog worktrees/wt2-456/HEAD >actual &&
test_cmp expected actual &&
- git -C wt1 reflog worktrees/wt2/HEAD >actual.wt1 &&
+ git -C wt1 reflog worktrees/wt2-456/HEAD >actual.wt1 &&
test_cmp expected actual.wt1 &&
- git -C wt2 reflog worktrees/wt2/HEAD >actual.wt2 &&
+ git -C wt2 reflog worktrees/wt2-456/HEAD >actual.wt2 &&
test_cmp expected actual.wt2
'
@@ -152,10 +152,10 @@ test_expect_success REFFILES 'HEAD link pointing at a funny object (from differe
test_expect_success REFFILES 'other worktree HEAD link pointing at a funny object' '
test_when_finished "git worktree remove -f other" &&
- git worktree add other &&
- echo $ZERO_OID >.git/worktrees/other/HEAD &&
+ GIT_TEST_WORKTREE_SUFFIX=123 git worktree add other &&
+ echo $ZERO_OID >.git/worktrees/other-123/HEAD &&
test_must_fail git fsck 2>out &&
- test_grep "worktrees/other/HEAD: detached HEAD points" out
+ test_grep "worktrees/other-123/HEAD: detached HEAD points" out
'
test_expect_success 'other worktree HEAD link pointing at missing object' '
@@ -164,7 +164,7 @@ test_expect_success 'other worktree HEAD link pointing at missing object' '
object_id=$(echo "Contents missing from repo" | git hash-object --stdin) &&
test-tool -C other ref-store main update-ref msg HEAD $object_id "" REF_NO_DEREF,REF_SKIP_OID_VERIFICATION &&
test_must_fail git fsck 2>out &&
- test_grep "worktrees/other/HEAD: invalid sha1 pointer" out
+ test_grep "worktrees/other-.*/HEAD: invalid sha1 pointer" out
'
test_expect_success 'other worktree HEAD link pointing at a funny place' '
@@ -172,7 +172,7 @@ test_expect_success 'other worktree HEAD link pointing at a funny place' '
git worktree add other &&
git -C other symbolic-ref HEAD refs/funny/place &&
test_must_fail git fsck 2>out &&
- test_grep "worktrees/other/HEAD points to something strange" out
+ test_grep "worktrees/other-.*/HEAD points to something strange" out
'
test_expect_success 'commit with multiple signatures is okay' '
@@ -1033,7 +1033,7 @@ test_expect_success 'fsck error on gitattributes with excessive size' '
test_expect_success 'fsck detects problems in worktree index' '
test_when_finished "git worktree remove -f wt" &&
- git worktree add wt &&
+ GIT_TEST_WORKTREE_SUFFIX=123 git worktree add wt &&
echo "this will be removed to break the worktree index" >wt/file &&
git -C wt add file &&
@@ -1042,7 +1042,7 @@ test_expect_success 'fsck detects problems in worktree index' '
test_must_fail git fsck --name-objects >actual 2>&1 &&
cat >expect <<-EOF &&
- missing blob $blob (.git/worktrees/wt/index:file)
+ missing blob $blob (.git/worktrees/wt-123/index:file)
EOF
test_cmp expect actual
'
@@ -80,7 +80,7 @@ test_expect_success 'setup' '
git checkout -b side &&
test_commit def &&
git checkout main &&
- git worktree add worktree side
+ GIT_TEST_WORKTREE_SUFFIX=123 git worktree add worktree side
'
test_rev_parse toplevel false false true '' .git "$ROOT/.git"
@@ -113,7 +113,7 @@ test_expect_success 'rev-parse --path-format=absolute' '
test_one "." "$ROOT/.git" --path-format=absolute --git-common-dir &&
test_one "sub/dir" "$ROOT/.git" --path-format=absolute --git-dir &&
test_one "sub/dir" "$ROOT/.git" --path-format=absolute --git-common-dir &&
- test_one "worktree" "$ROOT/.git/worktrees/worktree" --path-format=absolute --git-dir &&
+ test_one "worktree" "$ROOT/.git/worktrees/worktree-123" --path-format=absolute --git-dir &&
test_one "worktree" "$ROOT/.git" --path-format=absolute --git-common-dir &&
test_one "." "$ROOT" --path-format=absolute --show-toplevel &&
test_one "." "$ROOT/.git/objects" --path-format=absolute --git-path objects &&
@@ -125,7 +125,7 @@ test_expect_success 'rev-parse --path-format=relative' '
test_one "." ".git" --path-format=relative --git-common-dir &&
test_one "sub/dir" "../../.git" --path-format=relative --git-dir &&
test_one "sub/dir" "../../.git" --path-format=relative --git-common-dir &&
- test_one "worktree" "../.git/worktrees/worktree" --path-format=relative --git-dir &&
+ test_one "worktree" "../.git/worktrees/worktree-123" --path-format=relative --git-dir &&
test_one "worktree" "../.git" --path-format=relative --git-common-dir &&
test_one "." "./" --path-format=relative --show-toplevel &&
test_one "." ".git/objects" --path-format=relative --git-path objects &&
@@ -71,21 +71,21 @@ test_expect_success '"add" worktree' '
test_expect_success '"add" worktree with lock' '
git worktree add --detach --lock here-with-lock main &&
test_when_finished "git worktree unlock here-with-lock || :" &&
- test -f .git/worktrees/here-with-lock/locked
+ test -f .git/worktrees/here-with-lock-*/locked
'
test_expect_success '"add" worktree with lock and reason' '
lock_reason="why not" &&
git worktree add --detach --lock --reason "$lock_reason" here-with-lock-reason main &&
test_when_finished "git worktree unlock here-with-lock-reason || :" &&
- test -f .git/worktrees/here-with-lock-reason/locked &&
+ test -f .git/worktrees/here-with-lock-reason-*/locked &&
echo "$lock_reason" >expect &&
- test_cmp expect .git/worktrees/here-with-lock-reason/locked
+ test_cmp expect .git/worktrees/here-with-lock-reason-*/locked
'
test_expect_success '"add" worktree with reason but no lock' '
test_must_fail git worktree add --detach --reason "why not" here-with-reason-only main &&
- test_path_is_missing .git/worktrees/here-with-reason-only/locked
+ test_path_is_missing .git/worktrees/here-with-reason-only-*/locked
'
test_expect_success '"add" worktree from a subdir' '
@@ -413,16 +413,16 @@ test_expect_success '"add --orphan" with empty repository' '
test_expect_success '"add" worktree with orphan branch and lock' '
git worktree add --lock --orphan -b orphanbr orphan-with-lock &&
test_when_finished "git worktree unlock orphan-with-lock || :" &&
- test -f .git/worktrees/orphan-with-lock/locked
+ test -f .git/worktrees/orphan-with-lock-*/locked
'
test_expect_success '"add" worktree with orphan branch, lock, and reason' '
lock_reason="why not" &&
git worktree add --detach --lock --reason "$lock_reason" orphan-with-lock-reason main &&
test_when_finished "git worktree unlock orphan-with-lock-reason || :" &&
- test -f .git/worktrees/orphan-with-lock-reason/locked &&
+ test -f .git/worktrees/orphan-with-lock-reason-*/locked &&
echo "$lock_reason" >expect &&
- test_cmp expect .git/worktrees/orphan-with-lock-reason/locked
+ test_cmp expect .git/worktrees/orphan-with-lock-reason-*/locked
'
# Note: Quoted arguments containing spaces are not supported.
@@ -1088,10 +1088,10 @@ test_expect_success '"add" invokes post-checkout hook (branch)' '
post_checkout_hook &&
{
echo $ZERO_OID $(git rev-parse HEAD) 1 &&
- echo $(pwd)/.git/worktrees/gumby &&
+ echo $(pwd)/.git/worktrees/gumby-123 &&
echo $(pwd)/gumby
} >hook.expect &&
- git worktree add gumby &&
+ GIT_TEST_WORKTREE_SUFFIX="123" git worktree add gumby &&
test_cmp hook.expect gumby/hook.actual
'
@@ -1099,10 +1099,10 @@ test_expect_success '"add" invokes post-checkout hook (detached)' '
post_checkout_hook &&
{
echo $ZERO_OID $(git rev-parse HEAD) 1 &&
- echo $(pwd)/.git/worktrees/grumpy &&
+ echo $(pwd)/.git/worktrees/grumpy-456 &&
echo $(pwd)/grumpy
} >hook.expect &&
- git worktree add --detach grumpy &&
+ GIT_TEST_WORKTREE_SUFFIX="456" git worktree add --detach grumpy &&
test_cmp hook.expect grumpy/hook.actual
'
@@ -1117,10 +1117,10 @@ test_expect_success '"add" in other worktree invokes post-checkout hook' '
post_checkout_hook &&
{
echo $ZERO_OID $(git rev-parse HEAD) 1 &&
- echo $(pwd)/.git/worktrees/guppy &&
+ echo $(pwd)/.git/worktrees/guppy-789 &&
echo $(pwd)/guppy
} >hook.expect &&
- git -C gloopy worktree add --detach ../guppy &&
+ GIT_TEST_WORKTREE_SUFFIX="789" git -C gloopy worktree add --detach ../guppy &&
test_cmp hook.expect guppy/hook.actual
'
@@ -1129,11 +1129,11 @@ test_expect_success '"add" in bare repo invokes post-checkout hook' '
git clone --bare . bare &&
{
echo $ZERO_OID $(git --git-dir=bare rev-parse HEAD) 1 &&
- echo $(pwd)/bare/worktrees/goozy &&
+ echo $(pwd)/bare/worktrees/goozy-651 &&
echo $(pwd)/goozy
} >hook.expect &&
post_checkout_hook bare &&
- git -C bare worktree add --detach ../goozy &&
+ GIT_TEST_WORKTREE_SUFFIX="651" git -C bare worktree add --detach ../goozy &&
test_cmp hook.expect goozy/hook.actual
'
@@ -1165,8 +1165,9 @@ test_expect_success '"add" not tripped up by magic worktree matching"' '
'
test_expect_success FUNNYNAMES 'sanitize generated worktree name' '
- git worktree add --detach ". weird*..?.lock.lock" &&
- test -d .git/worktrees/---weird-.-
+ GIT_TEST_WORKTREE_SUFFIX="1234" \
+ git worktree add --detach ". weird*..?.lock.lock" &&
+ test -d .git/worktrees/---weird-.--1234
'
test_expect_success '"add" should not fail because of another bad worktree' '
@@ -1210,23 +1211,23 @@ test_expect_success '"add" with initialized submodule, with submodule.recurse se
test_expect_success 'can create worktrees with relative paths' '
test_when_finished "git worktree remove relative" &&
test_config worktree.useRelativePaths false &&
- git worktree add --relative-paths ./relative &&
- echo "gitdir: ../.git/worktrees/relative" >expect &&
+ GIT_TEST_WORKTREE_SUFFIX=123 git worktree add --relative-paths ./relative &&
+ echo "gitdir: ../.git/worktrees/relative-123" >expect &&
test_cmp expect relative/.git &&
echo "../../../relative/.git" >expect &&
- test_cmp expect .git/worktrees/relative/gitdir
+ test_cmp expect .git/worktrees/relative-123/gitdir
'
test_expect_success 'can create worktrees with absolute paths' '
test_config worktree.useRelativePaths true &&
- git worktree add ./relative &&
- echo "gitdir: ../.git/worktrees/relative" >expect &&
+ GIT_TEST_WORKTREE_SUFFIX=123 git worktree add ./relative &&
+ echo "gitdir: ../.git/worktrees/relative-123" >expect &&
test_cmp expect relative/.git &&
- git worktree add --no-relative-paths ./absolute &&
- echo "gitdir: $(pwd)/.git/worktrees/absolute" >expect &&
+ GIT_TEST_WORKTREE_SUFFIX=456 git worktree add --no-relative-paths ./absolute &&
+ echo "gitdir: $(pwd)/.git/worktrees/absolute-456" >expect &&
test_cmp expect absolute/.git &&
echo "$(pwd)/absolute/.git" >expect &&
- test_cmp expect .git/worktrees/absolute/gitdir
+ test_cmp expect .git/worktrees/absolute-456/gitdir
'
test_expect_success 'move repo without breaking relative internal links' '
@@ -83,29 +83,29 @@ test_expect_success 'not prune locked checkout' '
test_expect_success 'not prune recent checkouts' '
test_when_finished rm -r .git/worktrees &&
git worktree add jlm HEAD &&
- test -d .git/worktrees/jlm &&
+ test -d .git/worktrees/jlm-* &&
rm -rf jlm &&
git worktree prune --verbose --expire=2.days.ago &&
- test -d .git/worktrees/jlm
+ test -d .git/worktrees/jlm-*
'
test_expect_success 'not prune proper checkouts' '
test_when_finished rm -r .git/worktrees &&
git worktree add --detach "$PWD/nop" main &&
git worktree prune &&
- test -d .git/worktrees/nop
+ test -d .git/worktrees/nop-*
'
test_expect_success 'prune duplicate (linked/linked)' '
test_when_finished rm -fr .git/worktrees w1 w2 &&
- git worktree add --detach w1 &&
- git worktree add --detach w2 &&
- sed "s/w2/w1/" .git/worktrees/w2/gitdir >.git/worktrees/w2/gitdir.new &&
- mv .git/worktrees/w2/gitdir.new .git/worktrees/w2/gitdir &&
+ GIT_TEST_WORKTREE_SUFFIX=1 git worktree add --detach w1 &&
+ GIT_TEST_WORKTREE_SUFFIX=2 git worktree add --detach w2 &&
+ sed "s/w2/w1/" .git/worktrees/w2-2/gitdir >.git/worktrees/w2-2/gitdir.new &&
+ mv .git/worktrees/w2-2/gitdir.new .git/worktrees/w2-2/gitdir &&
git worktree prune --verbose 2>actual &&
test_grep "duplicate entry" actual &&
- test -d .git/worktrees/w1 &&
- ! test -d .git/worktrees/w2
+ test -d .git/worktrees/w1-1 &&
+ ! test -d .git/worktrees/w2-2
'
test_expect_success 'prune duplicate (main/linked)' '
@@ -117,7 +117,7 @@ test_expect_success 'prune duplicate (main/linked)' '
mv repo wt &&
git -C wt worktree prune --verbose 2>actual &&
test_grep "duplicate entry" actual &&
- ! test -d .git/worktrees/wt
+ ! test -d .git/worktrees/wt-*
'
test_expect_success 'not prune proper worktrees inside linked worktree with relative paths' '
@@ -24,27 +24,27 @@ test_expect_success 'lock main worktree' '
test_expect_success 'lock linked worktree' '
git worktree lock --reason hahaha source &&
echo hahaha >expected &&
- test_cmp expected .git/worktrees/source/locked
+ test_cmp expected .git/worktrees/source-*/locked
'
test_expect_success 'lock linked worktree from another worktree' '
- rm .git/worktrees/source/locked &&
+ rm .git/worktrees/source-*/locked &&
git worktree add elsewhere &&
git -C elsewhere worktree lock --reason hahaha ../source &&
echo hahaha >expected &&
- test_cmp expected .git/worktrees/source/locked
+ test_cmp expected .git/worktrees/source-*/locked
'
test_expect_success 'lock worktree twice' '
test_must_fail git worktree lock source &&
echo hahaha >expected &&
- test_cmp expected .git/worktrees/source/locked
+ test_cmp expected .git/worktrees/source-*/locked
'
test_expect_success 'lock worktree twice (from the locked worktree)' '
test_must_fail git -C source worktree lock . &&
echo hahaha >expected &&
- test_cmp expected .git/worktrees/source/locked
+ test_cmp expected .git/worktrees/source-*/locked
'
test_expect_success 'unlock main worktree' '
@@ -183,19 +183,19 @@ test_expect_success 'force remove worktree with untracked file' '
test_expect_success 'remove missing worktree' '
git worktree add to-be-gone &&
- test -d .git/worktrees/to-be-gone &&
+ test -d .git/worktrees/to-be-gone-* &&
mv to-be-gone gone &&
git worktree remove to-be-gone &&
- test_path_is_missing .git/worktrees/to-be-gone
+ test_path_is_missing .git/worktrees/to-be-gone-*
'
test_expect_success 'NOT remove missing-but-locked worktree' '
git worktree add gone-but-locked &&
git worktree lock gone-but-locked &&
- test -d .git/worktrees/gone-but-locked &&
+ test -d .git/worktrees/gone-but-locked-* &&
mv gone-but-locked really-gone-now &&
test_must_fail git worktree remove gone-but-locked &&
- test_path_is_dir .git/worktrees/gone-but-locked
+ test_path_is_dir .git/worktrees/gone-but-locked-*
'
test_expect_success 'proper error when worktree not found' '
@@ -249,27 +249,27 @@ test_expect_success 'not remove a repo with initialized submodule' '
test_expect_success 'move worktree with absolute path to relative path' '
test_config worktree.useRelativePaths false &&
- git worktree add ./absolute &&
+ GIT_TEST_WORKTREE_SUFFIX=123 git worktree add ./absolute &&
git worktree move --relative-paths absolute relative &&
- echo "gitdir: ../.git/worktrees/absolute" >expect &&
+ echo "gitdir: ../.git/worktrees/absolute-123" >expect &&
test_cmp expect relative/.git &&
echo "../../../relative/.git" >expect &&
- test_cmp expect .git/worktrees/absolute/gitdir &&
+ test_cmp expect .git/worktrees/absolute-123/gitdir &&
test_config worktree.useRelativePaths true &&
git worktree move relative relative2 &&
- echo "gitdir: ../.git/worktrees/absolute" >expect &&
+ echo "gitdir: ../.git/worktrees/absolute-123" >expect &&
test_cmp expect relative2/.git &&
echo "../../../relative2/.git" >expect &&
- test_cmp expect .git/worktrees/absolute/gitdir
+ test_cmp expect .git/worktrees/absolute-123/gitdir
'
test_expect_success 'move worktree with relative path to absolute path' '
test_config worktree.useRelativePaths true &&
git worktree move --no-relative-paths relative2 absolute &&
- echo "gitdir: $(pwd)/.git/worktrees/absolute" >expect &&
+ echo "gitdir: $(pwd)/.git/worktrees/absolute-123" >expect &&
test_cmp expect absolute/.git &&
echo "$(pwd)/absolute/.git" >expect &&
- test_cmp expect .git/worktrees/absolute/gitdir
+ test_cmp expect .git/worktrees/absolute-123/gitdir
'
test_done
@@ -9,6 +9,7 @@ TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
base_path=$(pwd -P)
+suffix=4567
test_expect_success 'setup: create origin repos' '
git config --global protocol.file.allow always &&
@@ -61,9 +62,10 @@ test_expect_success 'submodule is checked out after manually adding submodule wo
'
test_expect_success 'checkout --recurse-submodules uses $GIT_DIR for submodules in a linked worktree' '
- git -C main worktree add "$base_path/checkout-recurse" --detach &&
+ GIT_TEST_WORKTREE_SUFFIX=$suffix \
+ git -C main worktree add "$base_path/checkout-recurse" --detach &&
git -C checkout-recurse submodule update --init &&
- echo "gitdir: ../../main/.git/worktrees/checkout-recurse/modules/sub" >expect-gitfile &&
+ echo "gitdir: ../../main/.git/worktrees/checkout-recurse-$suffix/modules/sub" >expect-gitfile &&
cat checkout-recurse/sub/.git >actual-gitfile &&
test_cmp expect-gitfile actual-gitfile &&
git -C main/sub rev-parse HEAD >expect-head-main &&
@@ -82,14 +84,14 @@ test_expect_success 'core.worktree is removed in $GIT_DIR/modules/<name>/config,
git -C checkout-recurse/sub config --get core.worktree >actual-linked &&
test_cmp expect-linked actual-linked &&
git -C checkout-recurse checkout --recurse-submodules first &&
- test_expect_code 1 git -C main/.git/worktrees/checkout-recurse/modules/sub config --get core.worktree >linked-config &&
+ test_expect_code 1 git -C main/.git/worktrees/checkout-recurse-$suffix/modules/sub config --get core.worktree >linked-config &&
test_must_be_empty linked-config &&
git -C main/sub config --get core.worktree >actual-main &&
test_cmp expect-main actual-main
'
test_expect_success 'unsetting core.worktree does not prevent running commands directly against the submodule repository' '
- git -C main/.git/worktrees/checkout-recurse/modules/sub log
+ git -C main/.git/worktrees/checkout-recurse-$suffix/modules/sub log
'
test_done
@@ -106,8 +106,8 @@ test_expect_success 'repo not found; .git not file' '
test_expect_success 'repo not found; .git not referencing repo' '
test_when_finished "rm -rf side not-a-repo && git worktree prune" &&
- git worktree add --detach side &&
- sed s,\.git/worktrees/side$,not-a-repo, side/.git >side/.newgit &&
+ GIT_TEST_WORKTREE_SUFFIX=1234 git worktree add --detach side &&
+ sed s,\.git/worktrees/side-1234$,not-a-repo, side/.git >side/.newgit &&
mv side/.newgit side/.git &&
mkdir not-a-repo &&
test_must_fail git worktree repair side 2>err &&
@@ -127,41 +127,41 @@ test_expect_success 'repo not found; .git file broken' '
test_expect_success 'repair broken gitdir' '
test_when_finished "rm -rf orig moved && git worktree prune" &&
git worktree add --detach orig &&
- sed s,orig/\.git$,moved/.git, .git/worktrees/orig/gitdir >expect &&
- rm .git/worktrees/orig/gitdir &&
+ sed s,orig/\.git$,moved/.git, .git/worktrees/orig-*/gitdir >expect &&
+ rm .git/worktrees/orig-*/gitdir &&
mv orig moved &&
git worktree repair moved 2>err &&
- test_cmp expect .git/worktrees/orig/gitdir &&
+ test_cmp expect .git/worktrees/orig-*/gitdir &&
test_grep "gitdir unreadable" err
'
test_expect_success 'repair incorrect gitdir' '
test_when_finished "rm -rf orig moved && git worktree prune" &&
git worktree add --detach orig &&
- sed s,orig/\.git$,moved/.git, .git/worktrees/orig/gitdir >expect &&
+ sed s,orig/\.git$,moved/.git, .git/worktrees/orig-*/gitdir >expect &&
mv orig moved &&
git worktree repair moved 2>err &&
- test_cmp expect .git/worktrees/orig/gitdir &&
+ test_cmp expect .git/worktrees/orig-*/gitdir &&
test_grep "gitdir incorrect" err
'
test_expect_success 'repair gitdir (implicit) from linked worktree' '
test_when_finished "rm -rf orig moved && git worktree prune" &&
git worktree add --detach orig &&
- sed s,orig/\.git$,moved/.git, .git/worktrees/orig/gitdir >expect &&
+ sed s,orig/\.git$,moved/.git, .git/worktrees/orig-*/gitdir >expect &&
mv orig moved &&
git -C moved worktree repair 2>err &&
- test_cmp expect .git/worktrees/orig/gitdir &&
+ test_cmp expect .git/worktrees/orig-*/gitdir &&
test_grep "gitdir incorrect" err
'
test_expect_success 'unable to repair gitdir (implicit) from main worktree' '
test_when_finished "rm -rf orig moved && git worktree prune" &&
git worktree add --detach orig &&
- cat .git/worktrees/orig/gitdir >expect &&
+ cat .git/worktrees/orig-*/gitdir >expect &&
mv orig moved &&
git worktree repair 2>err &&
- test_cmp expect .git/worktrees/orig/gitdir &&
+ test_cmp expect .git/worktrees/orig-*/gitdir &&
test_must_be_empty err
'
@@ -170,15 +170,15 @@ test_expect_success 'repair multiple gitdir files' '
git worktree prune" &&
git worktree add --detach orig1 &&
git worktree add --detach orig2 &&
- sed s,orig1/\.git$,moved1/.git, .git/worktrees/orig1/gitdir >expect1 &&
- sed s,orig2/\.git$,moved2/.git, .git/worktrees/orig2/gitdir >expect2 &&
+ sed s,orig1/\.git$,moved1/.git, .git/worktrees/orig1-*/gitdir >expect1 &&
+ sed s,orig2/\.git$,moved2/.git, .git/worktrees/orig2-*/gitdir >expect2 &&
mv orig1 moved1 &&
mv orig2 moved2 &&
git worktree repair moved1 moved2 2>err &&
- test_cmp expect1 .git/worktrees/orig1/gitdir &&
- test_cmp expect2 .git/worktrees/orig2/gitdir &&
- test_grep "gitdir incorrect:.*orig1/gitdir$" err &&
- test_grep "gitdir incorrect:.*orig2/gitdir$" err
+ test_cmp expect1 .git/worktrees/orig1-*/gitdir &&
+ test_cmp expect2 .git/worktrees/orig2-*/gitdir &&
+ test_grep "gitdir incorrect:.*orig1-.*/gitdir$" err &&
+ test_grep "gitdir incorrect:.*orig2-.*/gitdir$" err
'
test_expect_success 'repair moved main and linked worktrees' '
@@ -186,14 +186,12 @@ test_expect_success 'repair moved main and linked worktrees' '
test_create_repo main &&
test_commit -C main init &&
git -C main worktree add --detach ../side &&
- sed "s,side/\.git$,sidemoved/.git," \
- main/.git/worktrees/side/gitdir >expect-gitdir &&
- sed "s,main/.git/worktrees/side$,mainmoved/.git/worktrees/side," \
- side/.git >expect-gitfile &&
+ sed "s,side,sidemoved," main/.git/worktrees/side-*/gitdir >expect-gitdir &&
+ sed "s,main,mainmoved," side/.git >expect-gitfile &&
mv main mainmoved &&
mv side sidemoved &&
git -C mainmoved worktree repair ../sidemoved &&
- test_cmp expect-gitdir mainmoved/.git/worktrees/side/gitdir &&
+ test_cmp expect-gitdir mainmoved/.git/worktrees/side-*/gitdir &&
test_cmp expect-gitfile sidemoved/.git
'
@@ -203,16 +201,15 @@ test_expect_success 'repair copied main and linked worktrees' '
git -C orig init main &&
test_commit -C orig/main nothing &&
git -C orig/main worktree add ../linked &&
- cp orig/main/.git/worktrees/linked/gitdir orig/main.expect &&
+ cp orig/main/.git/worktrees/linked-*/gitdir orig/main.expect &&
cp orig/linked/.git orig/linked.expect &&
cp -R orig dup &&
sed "s,orig/linked/\.git$,dup/linked/.git," orig/main.expect >dup/main.expect &&
- sed "s,orig/main/\.git/worktrees/linked$,dup/main/.git/worktrees/linked," \
- orig/linked.expect >dup/linked.expect &&
+ sed "s,orig,dup," orig/linked.expect >dup/linked.expect &&
git -C dup/main worktree repair ../linked &&
- test_cmp orig/main.expect orig/main/.git/worktrees/linked/gitdir &&
+ test_cmp orig/main.expect orig/main/.git/worktrees/linked-*/gitdir &&
test_cmp orig/linked.expect orig/linked/.git &&
- test_cmp dup/main.expect dup/main/.git/worktrees/linked/gitdir &&
+ test_cmp dup/main.expect dup/main/.git/worktrees/linked-*/gitdir &&
test_cmp dup/linked.expect dup/linked/.git
'
@@ -221,11 +218,11 @@ test_expect_success 'repair worktree with relative path with missing gitfile' '
test_create_repo main &&
git -C main config worktree.useRelativePaths true &&
test_commit -C main init &&
- git -C main worktree add --detach ../wt &&
+ GIT_TEST_WORKTREE_SUFFIX=123 git -C main worktree add --detach ../wt &&
rm wt/.git &&
test_path_is_missing wt/.git &&
git -C main worktree repair &&
- echo "gitdir: ../main/.git/worktrees/wt" >expect &&
+ echo "gitdir: ../main/.git/worktrees/wt-123" >expect &&
test_cmp expect wt/.git
'
@@ -233,12 +230,12 @@ test_expect_success 'repair absolute worktree to use relative paths' '
test_when_finished "rm -rf main side sidemoved" &&
test_create_repo main &&
test_commit -C main init &&
- git -C main worktree add --detach ../side &&
+ GIT_TEST_WORKTREE_SUFFIX=456 git -C main worktree add --detach ../side &&
echo "../../../../sidemoved/.git" >expect-gitdir &&
- echo "gitdir: ../main/.git/worktrees/side" >expect-gitfile &&
+ echo "gitdir: ../main/.git/worktrees/side-456" >expect-gitfile &&
mv side sidemoved &&
git -C main worktree repair --relative-paths ../sidemoved &&
- test_cmp expect-gitdir main/.git/worktrees/side/gitdir &&
+ test_cmp expect-gitdir main/.git/worktrees/side-456/gitdir &&
test_cmp expect-gitfile sidemoved/.git
'
@@ -246,13 +243,39 @@ test_expect_success 'repair relative worktree to use absolute paths' '
test_when_finished "rm -rf main side sidemoved" &&
test_create_repo main &&
test_commit -C main init &&
- git -C main worktree add --relative-paths --detach ../side &&
+ GIT_TEST_WORKTREE_SUFFIX=789 git -C main worktree add --relative-paths --detach ../side &&
echo "$(pwd)/sidemoved/.git" >expect-gitdir &&
- echo "gitdir: $(pwd)/main/.git/worktrees/side" >expect-gitfile &&
+ echo "gitdir: $(pwd)/main/.git/worktrees/side-789" >expect-gitfile &&
mv side sidemoved &&
git -C main worktree repair ../sidemoved &&
- test_cmp expect-gitdir main/.git/worktrees/side/gitdir &&
+ test_cmp expect-gitdir main/.git/worktrees/side-789/gitdir &&
test_cmp expect-gitfile sidemoved/.git
'
+test_expect_success 'does not repair worktrees from another repo' '
+ test_when_finished "rm -rf repo1 repo2" &&
+ mkdir -p repo1 &&
+ git -C repo1 init main &&
+ test_commit -C repo1/main nothing &&
+ git -C repo1/main worktree add ../linked &&
+ cp repo1/main/.git/worktrees/linked-*/gitdir repo1/main.expect &&
+ cp repo1/linked/.git repo1/linked.expect &&
+ mkdir -p repo2 &&
+ git -C repo2 init main &&
+ test_commit -C repo2/main nothing &&
+ git -C repo2/main worktree add ../linked &&
+ cp repo2/main/.git/worktrees/linked-*/gitdir repo2/main.expect &&
+ cp repo2/linked/.git repo2/linked.expect &&
+ git -C repo1/main worktree repair ../../repo2/linked &&
+ test_cmp repo1/main.expect repo1/main/.git/worktrees/linked-*/gitdir &&
+ test_cmp repo1/linked.expect repo1/linked/.git &&
+ test_cmp repo2/main.expect repo2/main/.git/worktrees/linked-*/gitdir &&
+ test_cmp repo2/linked.expect repo2/linked/.git &&
+ git -C repo2/main worktree repair ../../repo1/linked &&
+ test_cmp repo1/main.expect repo1/main/.git/worktrees/linked-*/gitdir &&
+ test_cmp repo1/linked.expect repo1/linked/.git &&
+ test_cmp repo2/main.expect repo2/main/.git/worktrees/linked-*/gitdir &&
+ test_cmp repo2/linked.expect repo2/linked/.git
+'
+
test_done
@@ -19,7 +19,8 @@ test_expect_success 'setup' '
test_commit $i &&
git branch wt-$i &&
git branch fake-$i &&
- git worktree add wt-$i wt-$i || return 1
+ GIT_TEST_WORKTREE_SUFFIX=$i \
+ git worktree add wt-$i wt-$i || return 1
done &&
# Create a server that updates each branch by one commit
@@ -132,20 +133,20 @@ test_expect_success 'refuse to overwrite when in error states' '
test_when_finished rm -rf .git/worktrees/wt-*/BISECT_* &&
# Both branches are currently under rebase.
- mkdir -p .git/worktrees/wt-3/rebase-merge &&
- touch .git/worktrees/wt-3/rebase-merge/interactive &&
- echo refs/heads/fake-1 >.git/worktrees/wt-3/rebase-merge/head-name &&
- echo refs/heads/fake-2 >.git/worktrees/wt-3/rebase-merge/onto &&
- mkdir -p .git/worktrees/wt-4/rebase-merge &&
- touch .git/worktrees/wt-4/rebase-merge/interactive &&
- echo refs/heads/fake-2 >.git/worktrees/wt-4/rebase-merge/head-name &&
- echo refs/heads/fake-1 >.git/worktrees/wt-4/rebase-merge/onto &&
+ mkdir -p .git/worktrees/wt-3-3/rebase-merge &&
+ touch .git/worktrees/wt-3-3/rebase-merge/interactive &&
+ echo refs/heads/fake-1 >.git/worktrees/wt-3-3/rebase-merge/head-name &&
+ echo refs/heads/fake-2 >.git/worktrees/wt-3-3/rebase-merge/onto &&
+ mkdir -p .git/worktrees/wt-4-4/rebase-merge &&
+ touch .git/worktrees/wt-4-4/rebase-merge/interactive &&
+ echo refs/heads/fake-2 >.git/worktrees/wt-4-4/rebase-merge/head-name &&
+ echo refs/heads/fake-1 >.git/worktrees/wt-4-4/rebase-merge/onto &&
# Both branches are currently under bisect.
- touch .git/worktrees/wt-4/BISECT_LOG &&
- echo refs/heads/fake-2 >.git/worktrees/wt-4/BISECT_START &&
- touch .git/worktrees/wt-1/BISECT_LOG &&
- echo refs/heads/fake-1 >.git/worktrees/wt-1/BISECT_START &&
+ touch .git/worktrees/wt-4-4/BISECT_LOG &&
+ echo refs/heads/fake-2 >.git/worktrees/wt-4-4/BISECT_START &&
+ touch .git/worktrees/wt-1-1/BISECT_LOG &&
+ echo refs/heads/fake-1 >.git/worktrees/wt-1-1/BISECT_START &&
for i in 1 2
do
@@ -246,14 +246,14 @@ test_expect_success 'git branch -M baz bam should succeed when baz is checked ou
'
test_expect_success REFFILES 'git branch -M fails if updating any linked working tree fails' '
- git worktree add -b baz bazdir1 &&
- git worktree add -f bazdir2 baz &&
- touch .git/worktrees/bazdir1/HEAD.lock &&
+ GIT_TEST_WORKTREE_SUFFIX=123 git worktree add -b baz bazdir1 &&
+ GIT_TEST_WORKTREE_SUFFIX=456 git worktree add -f bazdir2 baz &&
+ touch .git/worktrees/bazdir1-123/HEAD.lock &&
test_must_fail git branch -M baz bam &&
test $(git -C bazdir2 rev-parse --abbrev-ref HEAD) = bam &&
git branch -M bam baz &&
- rm .git/worktrees/bazdir1/HEAD.lock &&
- touch .git/worktrees/bazdir2/HEAD.lock &&
+ rm .git/worktrees/bazdir1-123/HEAD.lock &&
+ touch .git/worktrees/bazdir2-456/HEAD.lock &&
test_must_fail git branch -M baz bam &&
test $(git -C bazdir1 rev-parse --abbrev-ref HEAD) = bam &&
rm -rf bazdir1 bazdir2 &&
@@ -293,7 +293,7 @@ test_expect_success 'prune: handle HEAD in multiple worktrees' '
echo "new blob for third-worktree" >third-worktree/blob &&
git -C third-worktree add blob &&
git -C third-worktree commit -m "third" &&
- rm .git/worktrees/third-worktree/index &&
+ rm .git/worktrees/third-worktree-*/index &&
test_must_fail git -C third-worktree show :blob &&
git prune --expire=now &&
git -C third-worktree show HEAD:blob >actual &&
@@ -123,7 +123,7 @@ test_expect_success 'absorb the git dir outside of primary worktree' '
test_when_finished "rm -rf repo-bare.git" &&
git clone --bare . repo-bare.git &&
test_when_finished "rm -rf repo-wt" &&
- git -C repo-bare.git worktree add ../repo-wt &&
+ GIT_TEST_WORKTREE_SUFFIX=123 git -C repo-bare.git worktree add ../repo-wt &&
test_when_finished "rm -f .gitconfig" &&
test_config_global protocol.file.allow always &&
@@ -134,7 +134,7 @@ test_expect_success 'absorb the git dir outside of primary worktree' '
cat >expect <<-EOF &&
Migrating git directory of '\''sub2'\'' from
'\''$cwd/repo-wt/sub2/.git'\'' to
- '\''$cwd/repo-bare.git/worktrees/repo-wt/modules/sub2'\''
+ '\''$cwd/repo-bare.git/worktrees/repo-wt-123/modules/sub2'\''
EOF
git -C repo-wt submodule absorbgitdirs 2>actual &&
test_cmp expect actual
The `es/worktree-repair-copied` topic added support for repairing a worktree from a copy scenario. However, the topic added the ability for a repository to "take over" a worktree from another repository if the worktree_id matched a worktree inside the current repository which can happen if two repositories use the same worktree name. This teaches Git to create worktrees with a unique suffix so the worktree_id is unique across all repositories even if they have the same name. For example creating a worktree `develop` would look like: foo/ ├── .git/worktrees/develop-5445874156/ └── develop/ bar/ ├── .git/worktrees/develop-1549518426/ └── develop/ The actual worktree directory name is still `develop`, but the worktree_id is unique and prevents the "take over" scenario. The suffix is given by the `git_rand()` function. Worktree ids can already differ from the actual directory name (appended with a number like `develop1`) if the worktree name was already taken, so this should not be a drastic change. Signed-off-by: Caleb White <cdwhite3@pm.me> --- Documentation/git-worktree.txt | 5 +- builtin/worktree.c | 6 +++ t/t0035-safe-bare-repository.sh | 4 +- t/t0600-reffiles-backend.sh | 10 ++-- t/t0601-reffiles-pack-refs.sh | 4 +- t/t0610-reftable-basics.sh | 54 +++++++++++----------- t/t1407-worktree-ref-store.sh | 4 +- t/t1410-reflog.sh | 10 ++-- t/t1415-worktree-refs.sh | 26 +++++------ t/t1450-fsck.sh | 14 +++--- t/t1500-rev-parse.sh | 6 +-- t/t2400-worktree-add.sh | 51 +++++++++++---------- t/t2401-worktree-prune.sh | 20 ++++---- t/t2403-worktree-move.sh | 32 ++++++------- t/t2405-worktree-submodule.sh | 10 ++-- t/t2406-worktree-repair.sh | 93 ++++++++++++++++++++++++-------------- t/t2407-worktree-heads.sh | 27 +++++------ t/t3200-branch.sh | 10 ++-- t/t5304-prune.sh | 2 +- t/t7412-submodule-absorbgitdirs.sh | 4 +- 20 files changed, 212 insertions(+), 180 deletions(-)