3 test_description
='test separate work tree'
6 test_expect_success
'setup' '
7 EMPTY_TREE=$(git write-tree) &&
8 EMPTY_BLOB=$(git hash-object -t blob --stdin </dev/null) &&
9 CHANGED_BLOB=$(echo changed | git hash-object -t blob --stdin) &&
10 ZEROES=0000000000000000000000000000000000000000 &&
11 EMPTY_BLOB7=$(echo $EMPTY_BLOB | sed "s/\(.......\).*/\1/") &&
12 CHANGED_BLOB7=$(echo $CHANGED_BLOB | sed "s/\(.......\).*/\1/") &&
14 mkdir -p work/sub/dir &&
19 test_expect_success
'setup: helper for testing rev-parse' '
21 echo $1 >expected.bare &&
22 echo $2 >expected.inside-git &&
23 echo $3 >expected.inside-worktree &&
26 echo $4 >expected.prefix
29 git rev-parse --is-bare-repository >actual.bare &&
30 git rev-parse --is-inside-git-dir >actual.inside-git &&
31 git rev-parse --is-inside-work-tree >actual.inside-worktree &&
34 git rev-parse --show-prefix >actual.prefix
37 test_cmp expected.bare actual.bare &&
38 test_cmp expected.inside-git actual.inside-git &&
39 test_cmp expected.inside-worktree actual.inside-worktree &&
42 # rev-parse --show-prefix should output
43 # a single newline when at the top of the work tree,
44 # but we test for that separately.
45 test -z "$4" && ! test -s actual.prefix ||
46 test_cmp expected.prefix actual.prefix
51 test_expect_success
'setup: core.worktree = relative path' '
54 GIT_CONFIG="$(pwd)"/$GIT_DIR/config &&
55 export GIT_DIR GIT_CONFIG &&
56 git config core.worktree ../work
59 test_expect_success
'outside' '
60 test_rev_parse false false false
63 test_expect_success
'inside work tree' '
66 GIT_DIR=../repo.git &&
67 GIT_CONFIG="$(pwd)"/$GIT_DIR/config &&
68 test_rev_parse false false true ""
72 test_expect_failure
'empty prefix is actually written out' '
76 GIT_DIR=../repo.git &&
77 GIT_CONFIG="$(pwd)"/$GIT_DIR/config &&
78 git rev-parse --show-prefix >../actual
80 test_cmp expected actual
83 test_expect_success
'subdir of work tree' '
86 GIT_DIR=../../../repo.git &&
87 GIT_CONFIG="$(pwd)"/$GIT_DIR/config &&
88 test_rev_parse false false true sub/dir/
92 test_expect_success
'setup: core.worktree = absolute path' '
94 GIT_DIR=$(pwd)/repo.git &&
95 GIT_CONFIG=$GIT_DIR/config &&
96 export GIT_DIR GIT_CONFIG &&
97 git config core.worktree "$(pwd)/work"
100 test_expect_success
'outside' '
101 test_rev_parse false false false &&
104 test_rev_parse false false false
108 test_expect_success
'inside work tree' '
111 test_rev_parse false false true ""
115 test_expect_success
'subdir of work tree' '
118 test_rev_parse false false true sub/dir/
122 test_expect_success
'setup: GIT_WORK_TREE=relative (override core.worktree)' '
123 GIT_DIR=$(pwd)/repo.git &&
124 GIT_CONFIG=$GIT_DIR/config &&
125 git config core.worktree non-existent &&
126 GIT_WORK_TREE=work &&
127 export GIT_DIR GIT_CONFIG GIT_WORK_TREE
130 test_expect_success
'outside' '
131 test_rev_parse false false false &&
134 test_rev_parse false false false
138 test_expect_success
'inside work tree' '
142 test_rev_parse false false true ""
146 test_expect_success
'subdir of work tree' '
149 GIT_WORK_TREE=../.. &&
150 test_rev_parse false false true sub/dir/
154 test_expect_success
'setup: GIT_WORK_TREE=absolute, below git dir' '
155 mv work repo.git/work &&
156 mv work2 repo.git/work2 &&
157 GIT_DIR=$(pwd)/repo.git &&
158 GIT_CONFIG=$GIT_DIR/config &&
159 GIT_WORK_TREE=$(pwd)/repo.git/work &&
160 export GIT_DIR GIT_CONFIG GIT_WORK_TREE
163 test_expect_success
'outside' '
165 test_rev_parse false false false
168 test_expect_success
'in repo.git' '
171 test_rev_parse false true false
174 cd repo.git/objects &&
175 test_rev_parse false true false
179 test_rev_parse false true false
183 test_expect_success
'inside work tree' '
186 test_rev_parse false true true ""
190 test_expect_success
'subdir of work tree' '
192 cd repo.git/work/sub/dir &&
193 test_rev_parse false true true sub/dir/
197 test_expect_success
'find work tree from repo' '
198 echo sub/dir/untracked >expected &&
199 cat <<-\EOF >repo.git/work/.gitignore &&
204 >repo.git/work/sub/dir/untracked &&
207 git ls-files --others --exclude-standard >../actual
209 test_cmp expected actual
212 test_expect_success
'find work tree from work tree' '
213 echo sub/dir/tracked >expected &&
214 >repo.git/work/sub/dir/tracked &&
216 cd repo.git/work/sub/dir &&
217 git --git-dir=../../.. add tracked
221 git ls-files >../actual
223 test_cmp expected actual
226 test_expect_success
'_gently() groks relative GIT_DIR & GIT_WORK_TREE' '
228 cd repo.git/work/sub/dir &&
230 GIT_WORK_TREE=../.. &&
232 export GIT_DIR GIT_WORK_TREE GIT_PAGER &&
234 git diff --exit-code tracked &&
235 echo changed >tracked &&
236 test_must_fail git diff --exit-code tracked
240 test_expect_success
'diff-index respects work tree under .git dir' '
241 cat >diff-index-cached.expected <<-EOF &&
242 :000000 100644 $ZEROES $EMPTY_BLOB A sub/dir/tracked
244 cat >diff-index.expected <<-EOF &&
245 :000000 100644 $ZEROES $ZEROES A sub/dir/tracked
250 GIT_WORK_TREE=repo.git/work &&
251 export GIT_DIR GIT_WORK_TREE &&
252 git diff-index $EMPTY_TREE >diff-index.actual &&
253 git diff-index --cached $EMPTY_TREE >diff-index-cached.actual
255 test_cmp diff-index.expected diff-index.actual &&
256 test_cmp diff-index-cached.expected diff-index-cached.actual
259 test_expect_success
'diff-files respects work tree under .git dir' '
260 cat >diff-files.expected <<-EOF &&
261 :100644 100644 $EMPTY_BLOB $ZEROES M sub/dir/tracked
266 GIT_WORK_TREE=repo.git/work &&
267 export GIT_DIR GIT_WORK_TREE &&
268 git diff-files >diff-files.actual
270 test_cmp diff-files.expected diff-files.actual
273 test_expect_success
'git diff respects work tree under .git dir' '
274 cat >diff-TREE.expected <<-EOF &&
275 diff --git a/sub/dir/tracked b/sub/dir/tracked
277 index 0000000..$CHANGED_BLOB7
279 +++ b/sub/dir/tracked
283 cat >diff-TREE-cached.expected <<-EOF &&
284 diff --git a/sub/dir/tracked b/sub/dir/tracked
286 index 0000000..$EMPTY_BLOB7
288 cat >diff-FILES.expected <<-EOF &&
289 diff --git a/sub/dir/tracked b/sub/dir/tracked
290 index $EMPTY_BLOB7..$CHANGED_BLOB7 100644
291 --- a/sub/dir/tracked
292 +++ b/sub/dir/tracked
299 GIT_WORK_TREE=repo.git/work &&
300 export GIT_DIR GIT_WORK_TREE &&
301 git diff $EMPTY_TREE >diff-TREE.actual &&
302 git diff --cached $EMPTY_TREE >diff-TREE-cached.actual &&
303 git diff >diff-FILES.actual
305 test_cmp diff-TREE.expected diff-TREE.actual &&
306 test_cmp diff-TREE-cached.expected diff-TREE-cached.actual &&
307 test_cmp diff-FILES.expected diff-FILES.actual
310 test_expect_success
'git grep' '
311 echo dir/tracked >expected.grep &&
313 cd repo.git/work/sub &&
316 export GIT_DIR GIT_WORK_TREE &&
317 git grep -l changed >../../../actual.grep
319 test_cmp expected.grep actual.grep
322 test_expect_success
'git commit' '
325 GIT_DIR=. GIT_WORK_TREE=work git commit -a -m done
329 test_expect_success
'absolute pathspec should fail gracefully' '
332 test_might_fail git config --unset core.worktree &&
333 test_must_fail git log HEAD -- /home
337 test_expect_success
'make_relative_path handles double slashes in GIT_DIR' '
339 echo git --git-dir="$(pwd)//repo.git" --work-tree="$(pwd)" add dummy_file &&
340 git --git-dir="$(pwd)//repo.git" --work-tree="$(pwd)" add dummy_file
343 test_expect_success
'relative $GIT_WORK_TREE and git subprocesses' '
344 GIT_DIR=repo.git GIT_WORK_TREE=repo.git/work \
345 test-subprocess --setup-work-tree rev-parse --show-toplevel >actual &&
346 echo "$TRASH_DIRECTORY/repo.git/work" >expected &&
347 test_cmp expected actual