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