t / t1501-worktree.shon commit Merge branch 'maint' (6c4c9bd)
   1#!/bin/sh
   2
   3test_description='test separate work tree'
   4. ./test-lib.sh
   5
   6test_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/") &&
  13
  14        mkdir -p work/sub/dir &&
  15        mkdir -p work2 &&
  16        mv .git repo.git
  17'
  18
  19test_expect_success 'setup: helper for testing rev-parse' '
  20        test_rev_parse() {
  21                echo $1 >expected.bare &&
  22                echo $2 >expected.inside-git &&
  23                echo $3 >expected.inside-worktree &&
  24                if test $# -ge 4
  25                then
  26                        echo $4 >expected.prefix
  27                fi &&
  28
  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 &&
  32                if test $# -ge 4
  33                then
  34                        git rev-parse --show-prefix >actual.prefix
  35                fi &&
  36
  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 &&
  40                if test $# -ge 4
  41                then
  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
  47                fi
  48        }
  49'
  50
  51test_expect_success 'setup: core.worktree = relative path' '
  52        unset GIT_WORK_TREE;
  53        GIT_DIR=repo.git &&
  54        GIT_CONFIG="$(pwd)"/$GIT_DIR/config &&
  55        export GIT_DIR GIT_CONFIG &&
  56        git config core.worktree ../work
  57'
  58
  59test_expect_success 'outside' '
  60        test_rev_parse false false false
  61'
  62
  63test_expect_success 'inside work tree' '
  64        (
  65                cd work &&
  66                GIT_DIR=../repo.git &&
  67                GIT_CONFIG="$(pwd)"/$GIT_DIR/config &&
  68                test_rev_parse false false true ""
  69        )
  70'
  71
  72test_expect_failure 'empty prefix is actually written out' '
  73        echo >expected &&
  74        (
  75                cd work &&
  76                GIT_DIR=../repo.git &&
  77                GIT_CONFIG="$(pwd)"/$GIT_DIR/config &&
  78                git rev-parse --show-prefix >../actual
  79        ) &&
  80        test_cmp expected actual
  81'
  82
  83test_expect_success 'subdir of work tree' '
  84        (
  85                cd work/sub/dir &&
  86                GIT_DIR=../../../repo.git &&
  87                GIT_CONFIG="$(pwd)"/$GIT_DIR/config &&
  88                test_rev_parse false false true sub/dir/
  89        )
  90'
  91
  92test_expect_success 'setup: core.worktree = absolute path' '
  93        unset GIT_WORK_TREE;
  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"
  98'
  99
 100test_expect_success 'outside' '
 101        test_rev_parse false false false &&
 102        (
 103                cd work2 &&
 104                test_rev_parse false false false
 105        )
 106'
 107
 108test_expect_success 'inside work tree' '
 109        (
 110                cd work &&
 111                test_rev_parse false false true ""
 112        )
 113'
 114
 115test_expect_success 'subdir of work tree' '
 116        (
 117                cd work/sub/dir &&
 118                test_rev_parse false false true sub/dir/
 119        )
 120'
 121
 122test_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
 128'
 129
 130test_expect_success 'outside' '
 131        test_rev_parse false false false &&
 132        (
 133                cd work2 &&
 134                test_rev_parse false false false
 135        )
 136'
 137
 138test_expect_success 'inside work tree' '
 139        (
 140                cd work &&
 141                GIT_WORK_TREE=. &&
 142                test_rev_parse false false true ""
 143        )
 144'
 145
 146test_expect_success 'subdir of work tree' '
 147        (
 148                cd work/sub/dir &&
 149                GIT_WORK_TREE=../.. &&
 150                test_rev_parse false false true sub/dir/
 151        )
 152'
 153
 154test_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
 161'
 162
 163test_expect_success 'outside' '
 164        echo outside &&
 165        test_rev_parse false false false
 166'
 167
 168test_expect_success 'in repo.git' '
 169        (
 170                cd repo.git &&
 171                test_rev_parse false true false
 172        ) &&
 173        (
 174                cd repo.git/objects &&
 175                test_rev_parse false true false
 176        ) &&
 177        (
 178                cd repo.git/work2 &&
 179                test_rev_parse false true false
 180        )
 181'
 182
 183test_expect_success 'inside work tree' '
 184        (
 185                cd repo.git/work &&
 186                test_rev_parse false true true ""
 187        )
 188'
 189
 190test_expect_success 'subdir of work tree' '
 191        (
 192                cd repo.git/work/sub/dir &&
 193                test_rev_parse false true true sub/dir/
 194        )
 195'
 196
 197test_expect_success 'find work tree from repo' '
 198        echo sub/dir/untracked >expected &&
 199        cat <<-\EOF >repo.git/work/.gitignore &&
 200        expected.*
 201        actual.*
 202        .gitignore
 203        EOF
 204        >repo.git/work/sub/dir/untracked &&
 205        (
 206                cd repo.git &&
 207                git ls-files --others --exclude-standard >../actual
 208        ) &&
 209        test_cmp expected actual
 210'
 211
 212test_expect_success 'find work tree from work tree' '
 213        echo sub/dir/tracked >expected &&
 214        >repo.git/work/sub/dir/tracked &&
 215        (
 216                cd repo.git/work/sub/dir &&
 217                git --git-dir=../../.. add tracked
 218        ) &&
 219        (
 220                cd repo.git &&
 221                git ls-files >../actual
 222        ) &&
 223        test_cmp expected actual
 224'
 225
 226test_expect_success '_gently() groks relative GIT_DIR & GIT_WORK_TREE' '
 227        (
 228                cd repo.git/work/sub/dir &&
 229                GIT_DIR=../../.. &&
 230                GIT_WORK_TREE=../.. &&
 231                GIT_PAGER= &&
 232                export GIT_DIR GIT_WORK_TREE GIT_PAGER &&
 233
 234                git diff --exit-code tracked &&
 235                echo changed >tracked &&
 236                test_must_fail git diff --exit-code tracked
 237        )
 238'
 239
 240test_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
 243        EOF
 244        cat >diff-index.expected <<-EOF &&
 245        :000000 100644 $ZEROES $ZEROES A        sub/dir/tracked
 246        EOF
 247
 248        (
 249                GIT_DIR=repo.git &&
 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
 254        ) &&
 255        test_cmp diff-index.expected diff-index.actual &&
 256        test_cmp diff-index-cached.expected diff-index-cached.actual
 257'
 258
 259test_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
 262        EOF
 263
 264        (
 265                GIT_DIR=repo.git &&
 266                GIT_WORK_TREE=repo.git/work &&
 267                export GIT_DIR GIT_WORK_TREE &&
 268                git diff-files >diff-files.actual
 269        ) &&
 270        test_cmp diff-files.expected diff-files.actual
 271'
 272
 273test_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
 276        new file mode 100644
 277        index 0000000..$CHANGED_BLOB7
 278        --- /dev/null
 279        +++ b/sub/dir/tracked
 280        @@ -0,0 +1 @@
 281        +changed
 282        EOF
 283        cat >diff-TREE-cached.expected <<-EOF &&
 284        diff --git a/sub/dir/tracked b/sub/dir/tracked
 285        new file mode 100644
 286        index 0000000..$EMPTY_BLOB7
 287        EOF
 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
 293        @@ -0,0 +1 @@
 294        +changed
 295        EOF
 296
 297        (
 298                GIT_DIR=repo.git &&
 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
 304        ) &&
 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
 308'
 309
 310test_expect_success 'git grep' '
 311        echo dir/tracked >expected.grep &&
 312        (
 313                cd repo.git/work/sub &&
 314                GIT_DIR=../.. &&
 315                GIT_WORK_TREE=.. &&
 316                export GIT_DIR GIT_WORK_TREE &&
 317                git grep -l changed >../../../actual.grep
 318        ) &&
 319        test_cmp expected.grep actual.grep
 320'
 321
 322test_expect_success 'git commit' '
 323        (
 324                cd repo.git &&
 325                GIT_DIR=. GIT_WORK_TREE=work git commit -a -m done
 326        )
 327'
 328
 329test_expect_success 'absolute pathspec should fail gracefully' '
 330        (
 331                cd repo.git &&
 332                test_might_fail git config --unset core.worktree &&
 333                test_must_fail git log HEAD -- /home
 334        )
 335'
 336
 337test_expect_success 'make_relative_path handles double slashes in GIT_DIR' '
 338        >dummy_file
 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
 341'
 342
 343test_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 "$(pwd)/repo.git/work" >expected &&
 347        test_cmp expected actual
 348'
 349
 350test_done