t / t1700-split-index.shon commit t4208: abstract away SHA-1-specific constants (0b2c4af)
   1#!/bin/sh
   2
   3test_description='split index mode tests'
   4
   5. ./test-lib.sh
   6
   7# We need total control of index splitting here
   8sane_unset GIT_TEST_SPLIT_INDEX
   9sane_unset GIT_FSMONITOR_TEST
  10
  11test_expect_success 'enable split index' '
  12        git config splitIndex.maxPercentChange 100 &&
  13        git update-index --split-index &&
  14        test-tool dump-split-index .git/index >actual &&
  15        indexversion=$(test-tool index-version <.git/index) &&
  16        if test "$indexversion" = "4"
  17        then
  18                own=432ef4b63f32193984f339431fd50ca796493569
  19                base=508851a7f0dfa8691e9f69c7f055865389012491
  20        else
  21                own=8299b0bcd1ac364e5f1d7768efb62fa2da79a339
  22                base=39d890139ee5356c7ef572216cebcd27aa41f9df
  23        fi &&
  24        cat >expect <<-EOF &&
  25        own $own
  26        base $base
  27        replacements:
  28        deletions:
  29        EOF
  30        test_cmp expect actual
  31'
  32
  33test_expect_success 'add one file' '
  34        : >one &&
  35        git update-index --add one &&
  36        git ls-files --stage >ls-files.actual &&
  37        cat >ls-files.expect <<-EOF &&
  38        100644 $EMPTY_BLOB 0    one
  39        EOF
  40        test_cmp ls-files.expect ls-files.actual &&
  41
  42        test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
  43        cat >expect <<-EOF &&
  44        base $base
  45        100644 $EMPTY_BLOB 0    one
  46        replacements:
  47        deletions:
  48        EOF
  49        test_cmp expect actual
  50'
  51
  52test_expect_success 'disable split index' '
  53        git update-index --no-split-index &&
  54        git ls-files --stage >ls-files.actual &&
  55        cat >ls-files.expect <<-EOF &&
  56        100644 $EMPTY_BLOB 0    one
  57        EOF
  58        test_cmp ls-files.expect ls-files.actual &&
  59
  60        BASE=$(test-tool dump-split-index .git/index | grep "^own" | sed "s/own/base/") &&
  61        test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
  62        cat >expect <<-EOF &&
  63        not a split index
  64        EOF
  65        test_cmp expect actual
  66'
  67
  68test_expect_success 'enable split index again, "one" now belongs to base index"' '
  69        git update-index --split-index &&
  70        git ls-files --stage >ls-files.actual &&
  71        cat >ls-files.expect <<-EOF &&
  72        100644 $EMPTY_BLOB 0    one
  73        EOF
  74        test_cmp ls-files.expect ls-files.actual &&
  75
  76        test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
  77        cat >expect <<-EOF &&
  78        $BASE
  79        replacements:
  80        deletions:
  81        EOF
  82        test_cmp expect actual
  83'
  84
  85test_expect_success 'modify original file, base index untouched' '
  86        echo modified >one &&
  87        git update-index one &&
  88        git ls-files --stage >ls-files.actual &&
  89        cat >ls-files.expect <<-EOF &&
  90        100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0       one
  91        EOF
  92        test_cmp ls-files.expect ls-files.actual &&
  93
  94        test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
  95        q_to_tab >expect <<-EOF &&
  96        $BASE
  97        100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0Q
  98        replacements: 0
  99        deletions:
 100        EOF
 101        test_cmp expect actual
 102'
 103
 104test_expect_success 'add another file, which stays index' '
 105        : >two &&
 106        git update-index --add two &&
 107        git ls-files --stage >ls-files.actual &&
 108        cat >ls-files.expect <<-EOF &&
 109        100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0       one
 110        100644 $EMPTY_BLOB 0    two
 111        EOF
 112        test_cmp ls-files.expect ls-files.actual &&
 113
 114        test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
 115        q_to_tab >expect <<-EOF &&
 116        $BASE
 117        100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0Q
 118        100644 $EMPTY_BLOB 0    two
 119        replacements: 0
 120        deletions:
 121        EOF
 122        test_cmp expect actual
 123'
 124
 125test_expect_success 'remove file not in base index' '
 126        git update-index --force-remove two &&
 127        git ls-files --stage >ls-files.actual &&
 128        cat >ls-files.expect <<-EOF &&
 129        100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0       one
 130        EOF
 131        test_cmp ls-files.expect ls-files.actual &&
 132
 133        test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
 134        q_to_tab >expect <<-EOF &&
 135        $BASE
 136        100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0Q
 137        replacements: 0
 138        deletions:
 139        EOF
 140        test_cmp expect actual
 141'
 142
 143test_expect_success 'remove file in base index' '
 144        git update-index --force-remove one &&
 145        git ls-files --stage >ls-files.actual &&
 146        cat >ls-files.expect <<-EOF &&
 147        EOF
 148        test_cmp ls-files.expect ls-files.actual &&
 149
 150        test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
 151        cat >expect <<-EOF &&
 152        $BASE
 153        replacements:
 154        deletions: 0
 155        EOF
 156        test_cmp expect actual
 157'
 158
 159test_expect_success 'add original file back' '
 160        : >one &&
 161        git update-index --add one &&
 162        git ls-files --stage >ls-files.actual &&
 163        cat >ls-files.expect <<-EOF &&
 164        100644 $EMPTY_BLOB 0    one
 165        EOF
 166        test_cmp ls-files.expect ls-files.actual &&
 167
 168        test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
 169        cat >expect <<-EOF &&
 170        $BASE
 171        100644 $EMPTY_BLOB 0    one
 172        replacements:
 173        deletions: 0
 174        EOF
 175        test_cmp expect actual
 176'
 177
 178test_expect_success 'add new file' '
 179        : >two &&
 180        git update-index --add two &&
 181        git ls-files --stage >actual &&
 182        cat >expect <<-EOF &&
 183        100644 $EMPTY_BLOB 0    one
 184        100644 $EMPTY_BLOB 0    two
 185        EOF
 186        test_cmp expect actual
 187'
 188
 189test_expect_success 'unify index, two files remain' '
 190        git update-index --no-split-index &&
 191        git ls-files --stage >ls-files.actual &&
 192        cat >ls-files.expect <<-EOF &&
 193        100644 $EMPTY_BLOB 0    one
 194        100644 $EMPTY_BLOB 0    two
 195        EOF
 196        test_cmp ls-files.expect ls-files.actual &&
 197
 198        test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
 199        cat >expect <<-EOF &&
 200        not a split index
 201        EOF
 202        test_cmp expect actual
 203'
 204
 205test_expect_success 'rev-parse --shared-index-path' '
 206        test_create_repo split-index &&
 207        (
 208                cd split-index &&
 209                git update-index --split-index &&
 210                echo .git/sharedindex* >expect &&
 211                git rev-parse --shared-index-path >actual &&
 212                test_cmp expect actual &&
 213                mkdir subdirectory &&
 214                cd subdirectory &&
 215                echo ../.git/sharedindex* >expect &&
 216                git rev-parse --shared-index-path >actual &&
 217                test_cmp expect actual
 218        )
 219'
 220
 221test_expect_success 'set core.splitIndex config variable to true' '
 222        git config core.splitIndex true &&
 223        : >three &&
 224        git update-index --add three &&
 225        git ls-files --stage >ls-files.actual &&
 226        cat >ls-files.expect <<-EOF &&
 227        100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       one
 228        100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       three
 229        100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       two
 230        EOF
 231        test_cmp ls-files.expect ls-files.actual &&
 232        BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
 233        test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
 234        cat >expect <<-EOF &&
 235        $BASE
 236        replacements:
 237        deletions:
 238        EOF
 239        test_cmp expect actual
 240'
 241
 242test_expect_success 'set core.splitIndex config variable to false' '
 243        git config core.splitIndex false &&
 244        git update-index --force-remove three &&
 245        git ls-files --stage >ls-files.actual &&
 246        cat >ls-files.expect <<-EOF &&
 247        100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       one
 248        100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       two
 249        EOF
 250        test_cmp ls-files.expect ls-files.actual &&
 251        test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
 252        cat >expect <<-EOF &&
 253        not a split index
 254        EOF
 255        test_cmp expect actual
 256'
 257
 258test_expect_success 'set core.splitIndex config variable to true' '
 259        git config core.splitIndex true &&
 260        : >three &&
 261        git update-index --add three &&
 262        BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
 263        test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
 264        cat >expect <<-EOF &&
 265        $BASE
 266        replacements:
 267        deletions:
 268        EOF
 269        test_cmp expect actual &&
 270        : >four &&
 271        git update-index --add four &&
 272        test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
 273        cat >expect <<-EOF &&
 274        $BASE
 275        100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       four
 276        replacements:
 277        deletions:
 278        EOF
 279        test_cmp expect actual
 280'
 281
 282test_expect_success 'check behavior with splitIndex.maxPercentChange unset' '
 283        git config --unset splitIndex.maxPercentChange &&
 284        : >five &&
 285        git update-index --add five &&
 286        BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
 287        test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
 288        cat >expect <<-EOF &&
 289        $BASE
 290        replacements:
 291        deletions:
 292        EOF
 293        test_cmp expect actual &&
 294        : >six &&
 295        git update-index --add six &&
 296        test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
 297        cat >expect <<-EOF &&
 298        $BASE
 299        100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       six
 300        replacements:
 301        deletions:
 302        EOF
 303        test_cmp expect actual
 304'
 305
 306test_expect_success 'check splitIndex.maxPercentChange set to 0' '
 307        git config splitIndex.maxPercentChange 0 &&
 308        : >seven &&
 309        git update-index --add seven &&
 310        BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
 311        test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
 312        cat >expect <<-EOF &&
 313        $BASE
 314        replacements:
 315        deletions:
 316        EOF
 317        test_cmp expect actual &&
 318        : >eight &&
 319        git update-index --add eight &&
 320        BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
 321        test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
 322        cat >expect <<-EOF &&
 323        $BASE
 324        replacements:
 325        deletions:
 326        EOF
 327        test_cmp expect actual
 328'
 329
 330test_expect_success 'shared index files expire after 2 weeks by default' '
 331        : >ten &&
 332        git update-index --add ten &&
 333        test $(ls .git/sharedindex.* | wc -l) -gt 2 &&
 334        just_under_2_weeks_ago=$((5-14*86400)) &&
 335        test-tool chmtime =$just_under_2_weeks_ago .git/sharedindex.* &&
 336        : >eleven &&
 337        git update-index --add eleven &&
 338        test $(ls .git/sharedindex.* | wc -l) -gt 2 &&
 339        just_over_2_weeks_ago=$((-1-14*86400)) &&
 340        test-tool chmtime =$just_over_2_weeks_ago .git/sharedindex.* &&
 341        : >twelve &&
 342        git update-index --add twelve &&
 343        test $(ls .git/sharedindex.* | wc -l) -le 2
 344'
 345
 346test_expect_success 'check splitIndex.sharedIndexExpire set to 16 days' '
 347        git config splitIndex.sharedIndexExpire "16.days.ago" &&
 348        test-tool chmtime =$just_over_2_weeks_ago .git/sharedindex.* &&
 349        : >thirteen &&
 350        git update-index --add thirteen &&
 351        test $(ls .git/sharedindex.* | wc -l) -gt 2 &&
 352        just_over_16_days_ago=$((-1-16*86400)) &&
 353        test-tool chmtime =$just_over_16_days_ago .git/sharedindex.* &&
 354        : >fourteen &&
 355        git update-index --add fourteen &&
 356        test $(ls .git/sharedindex.* | wc -l) -le 2
 357'
 358
 359test_expect_success 'check splitIndex.sharedIndexExpire set to "never" and "now"' '
 360        git config splitIndex.sharedIndexExpire never &&
 361        just_10_years_ago=$((-365*10*86400)) &&
 362        test-tool chmtime =$just_10_years_ago .git/sharedindex.* &&
 363        : >fifteen &&
 364        git update-index --add fifteen &&
 365        test $(ls .git/sharedindex.* | wc -l) -gt 2 &&
 366        git config splitIndex.sharedIndexExpire now &&
 367        just_1_second_ago=-1 &&
 368        test-tool chmtime =$just_1_second_ago .git/sharedindex.* &&
 369        : >sixteen &&
 370        git update-index --add sixteen &&
 371        test $(ls .git/sharedindex.* | wc -l) -le 2
 372'
 373
 374while read -r mode modebits
 375do
 376        test_expect_success POSIXPERM "split index respects core.sharedrepository $mode" '
 377                # Remove existing shared index files
 378                git config core.splitIndex false &&
 379                git update-index --force-remove one &&
 380                rm -f .git/sharedindex.* &&
 381                # Create one new shared index file
 382                git config core.sharedrepository "$mode" &&
 383                git config core.splitIndex true &&
 384                : >one &&
 385                git update-index --add one &&
 386                echo "$modebits" >expect &&
 387                test_modebits .git/index >actual &&
 388                test_cmp expect actual &&
 389                shared=$(ls .git/sharedindex.*) &&
 390                case "$shared" in
 391                *" "*)
 392                        # we have more than one???
 393                        false ;;
 394                *)
 395                        test_modebits "$shared" >actual &&
 396                        test_cmp expect actual ;;
 397                esac
 398        '
 399done <<\EOF
 4000666 -rw-rw-rw-
 4010642 -rw-r---w-
 402EOF
 403
 404test_expect_success POSIXPERM,SANITY 'graceful handling when splitting index is not allowed' '
 405        test_create_repo ro &&
 406        (
 407                cd ro &&
 408                test_commit initial &&
 409                git update-index --split-index &&
 410                test -f .git/sharedindex.*
 411        ) &&
 412        cp ro/.git/index new-index &&
 413        test_when_finished "chmod u+w ro/.git" &&
 414        chmod u-w ro/.git &&
 415        GIT_INDEX_FILE="$(pwd)/new-index" git -C ro update-index --split-index &&
 416        chmod u+w ro/.git &&
 417        rm ro/.git/sharedindex.* &&
 418        GIT_INDEX_FILE=new-index git ls-files >actual &&
 419        echo initial.t >expected &&
 420        test_cmp expected actual
 421'
 422
 423test_expect_success 'writing split index with null sha1 does not write cache tree' '
 424        git config core.splitIndex true &&
 425        git config splitIndex.maxPercentChange 0 &&
 426        git commit -m "commit" &&
 427        {
 428                git ls-tree HEAD &&
 429                printf "160000 commit $ZERO_OID\\tbroken\\n"
 430        } >broken-tree &&
 431        echo "add broken entry" >msg &&
 432
 433        tree=$(git mktree <broken-tree) &&
 434        test_tick &&
 435        commit=$(git commit-tree $tree -p HEAD <msg) &&
 436        git update-ref HEAD "$commit" &&
 437        GIT_ALLOW_NULL_SHA1=1 git reset --hard &&
 438        (test-tool dump-cache-tree >cache-tree.out || true) &&
 439        test_line_count = 0 cache-tree.out
 440'
 441
 442test_done