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