t / t0090-cache-tree.shon commit untracked-cache: be defensive about missing NULs in index (c6909f9)
   1#!/bin/sh
   2
   3test_description="Test whether cache-tree is properly updated
   4
   5Tests whether various commands properly update and/or rewrite the
   6cache-tree extension.
   7"
   8 . ./test-lib.sh
   9
  10cmp_cache_tree () {
  11        test-tool dump-cache-tree | sed -e '/#(ref)/d' >actual &&
  12        sed "s/$OID_REGEX/SHA/" <actual >filtered &&
  13        test_cmp "$1" filtered
  14}
  15
  16# We don't bother with actually checking the SHA1:
  17# test-tool dump-cache-tree already verifies that all existing data is
  18# correct.
  19generate_expected_cache_tree_rec () {
  20        dir="$1${1:+/}" &&
  21        parent="$2" &&
  22        # ls-files might have foo/bar, foo/bar/baz, and foo/bar/quux
  23        # We want to count only foo because it's the only direct child
  24        subtrees=$(git ls-files|grep /|cut -d / -f 1|uniq) &&
  25        subtree_count=$(echo "$subtrees"|awk -v c=0 '$1 != "" {++c} END {print c}') &&
  26        entries=$(git ls-files|wc -l) &&
  27        printf "SHA $dir (%d entries, %d subtrees)\n" "$entries" "$subtree_count" &&
  28        for subtree in $subtrees
  29        do
  30                cd "$subtree"
  31                generate_expected_cache_tree_rec "$dir$subtree" "$dir" || return 1
  32                cd ..
  33        done &&
  34        dir=$parent
  35}
  36
  37generate_expected_cache_tree () {
  38        (
  39                generate_expected_cache_tree_rec
  40        )
  41}
  42
  43test_cache_tree () {
  44        generate_expected_cache_tree >expect &&
  45        cmp_cache_tree expect
  46}
  47
  48test_invalid_cache_tree () {
  49        printf "invalid                                  %s ()\n" "" "$@" >expect &&
  50        test-tool dump-cache-tree |
  51        sed -n -e "s/[0-9]* subtrees//" -e '/#(ref)/d' -e '/^invalid /p' >actual &&
  52        test_cmp expect actual
  53}
  54
  55test_no_cache_tree () {
  56        : >expect &&
  57        cmp_cache_tree expect
  58}
  59
  60test_expect_success 'initial commit has cache-tree' '
  61        test_commit foo &&
  62        test_cache_tree
  63'
  64
  65test_expect_success 'read-tree HEAD establishes cache-tree' '
  66        git read-tree HEAD &&
  67        test_cache_tree
  68'
  69
  70test_expect_success 'git-add invalidates cache-tree' '
  71        test_when_finished "git reset --hard; git read-tree HEAD" &&
  72        echo "I changed this file" >foo &&
  73        git add foo &&
  74        test_invalid_cache_tree
  75'
  76
  77test_expect_success 'git-add in subdir invalidates cache-tree' '
  78        test_when_finished "git reset --hard; git read-tree HEAD" &&
  79        mkdir dirx &&
  80        echo "I changed this file" >dirx/foo &&
  81        git add dirx/foo &&
  82        test_invalid_cache_tree
  83'
  84
  85cat >before <<\EOF
  86SHA  (3 entries, 2 subtrees)
  87SHA dir1/ (1 entries, 0 subtrees)
  88SHA dir2/ (1 entries, 0 subtrees)
  89EOF
  90
  91cat >expect <<\EOF
  92invalid                                   (2 subtrees)
  93invalid                                  dir1/ (0 subtrees)
  94SHA dir2/ (1 entries, 0 subtrees)
  95EOF
  96
  97test_expect_success 'git-add in subdir does not invalidate sibling cache-tree' '
  98        git tag no-children &&
  99        test_when_finished "git reset --hard no-children; git read-tree HEAD" &&
 100        mkdir dir1 dir2 &&
 101        test_commit dir1/a &&
 102        test_commit dir2/b &&
 103        echo "I changed this file" >dir1/a &&
 104        cmp_cache_tree before &&
 105        echo "I changed this file" >dir1/a &&
 106        git add dir1/a &&
 107        cmp_cache_tree expect
 108'
 109
 110test_expect_success 'update-index invalidates cache-tree' '
 111        test_when_finished "git reset --hard; git read-tree HEAD" &&
 112        echo "I changed this file" >foo &&
 113        git update-index --add foo &&
 114        test_invalid_cache_tree
 115'
 116
 117test_expect_success 'write-tree establishes cache-tree' '
 118        test-tool scrap-cache-tree &&
 119        git write-tree &&
 120        test_cache_tree
 121'
 122
 123test_expect_success 'test-tool scrap-cache-tree works' '
 124        git read-tree HEAD &&
 125        test-tool scrap-cache-tree &&
 126        test_no_cache_tree
 127'
 128
 129test_expect_success 'second commit has cache-tree' '
 130        test_commit bar &&
 131        test_cache_tree
 132'
 133
 134test_expect_success PERL 'commit --interactive gives cache-tree on partial commit' '
 135        cat <<-\EOT >foo.c &&
 136        int foo()
 137        {
 138                return 42;
 139        }
 140        int bar()
 141        {
 142                return 42;
 143        }
 144        EOT
 145        git add foo.c &&
 146        test_invalid_cache_tree &&
 147        git commit -m "add a file" &&
 148        test_cache_tree &&
 149        cat <<-\EOT >foo.c &&
 150        int foo()
 151        {
 152                return 43;
 153        }
 154        int bar()
 155        {
 156                return 44;
 157        }
 158        EOT
 159        test_write_lines p 1 "" s n y q |
 160        git commit --interactive -m foo &&
 161        test_cache_tree
 162'
 163
 164test_expect_success PERL 'commit -p with shrinking cache-tree' '
 165        mkdir -p deep/subdir &&
 166        echo content >deep/subdir/file &&
 167        git add deep &&
 168        git commit -m add &&
 169        git rm -r deep &&
 170
 171        before=$(wc -c <.git/index) &&
 172        git commit -m delete -p &&
 173        after=$(wc -c <.git/index) &&
 174
 175        # double check that the index shrank
 176        test $before -gt $after &&
 177
 178        # and that our index was not corrupted
 179        git fsck
 180'
 181
 182test_expect_success 'commit in child dir has cache-tree' '
 183        mkdir dir &&
 184        >dir/child.t &&
 185        git add dir/child.t &&
 186        git commit -m dir/child.t &&
 187        test_cache_tree
 188'
 189
 190test_expect_success 'reset --hard gives cache-tree' '
 191        test-tool scrap-cache-tree &&
 192        git reset --hard &&
 193        test_cache_tree
 194'
 195
 196test_expect_success 'reset --hard without index gives cache-tree' '
 197        rm -f .git/index &&
 198        git reset --hard &&
 199        test_cache_tree
 200'
 201
 202test_expect_success 'checkout gives cache-tree' '
 203        git tag current &&
 204        git checkout HEAD^ &&
 205        test_cache_tree
 206'
 207
 208test_expect_success 'checkout -b gives cache-tree' '
 209        git checkout current &&
 210        git checkout -b prev HEAD^ &&
 211        test_cache_tree
 212'
 213
 214test_expect_success 'checkout -B gives cache-tree' '
 215        git checkout current &&
 216        git checkout -B prev HEAD^ &&
 217        test_cache_tree
 218'
 219
 220test_expect_success 'merge --ff-only maintains cache-tree' '
 221        git checkout current &&
 222        git checkout -b changes &&
 223        test_commit llamas &&
 224        test_commit pachyderm &&
 225        test_cache_tree &&
 226        git checkout current &&
 227        test_cache_tree &&
 228        git merge --ff-only changes &&
 229        test_cache_tree
 230'
 231
 232test_expect_success 'merge maintains cache-tree' '
 233        git checkout current &&
 234        git checkout -b changes2 &&
 235        test_commit alpacas &&
 236        test_cache_tree &&
 237        git checkout current &&
 238        test_commit struthio &&
 239        test_cache_tree &&
 240        git merge changes2 &&
 241        test_cache_tree
 242'
 243
 244test_expect_success 'partial commit gives cache-tree' '
 245        git checkout -b partial no-children &&
 246        test_commit one &&
 247        test_commit two &&
 248        echo "some change" >one.t &&
 249        git add one.t &&
 250        echo "some other change" >two.t &&
 251        git commit two.t -m partial &&
 252        test_cache_tree
 253'
 254
 255test_expect_success 'no phantom error when switching trees' '
 256        mkdir newdir &&
 257        >newdir/one &&
 258        git add newdir/one &&
 259        git checkout 2>errors &&
 260        test_must_be_empty errors
 261'
 262
 263test_expect_success 'switching trees does not invalidate shared index' '
 264        (
 265                sane_unset GIT_TEST_SPLIT_INDEX &&
 266                git update-index --split-index &&
 267                >split &&
 268                git add split &&
 269                test-tool dump-split-index .git/index | grep -v ^own >before &&
 270                git commit -m "as-is" &&
 271                test-tool dump-split-index .git/index | grep -v ^own >after &&
 272                test_cmp before after
 273        )
 274'
 275
 276test_done