| 1 | #!/bin/sh |
| 2 | |
| 3 | # This test can give false success if your machine is sufficiently |
| 4 | # slow or all trials happened to happen on second boundaries. |
| 5 | |
| 6 | test_description='racy split index' |
| 7 | |
| 8 | . ./test-lib.sh |
| 9 | |
| 10 | test_expect_success 'setup' ' |
| 11 | # Only split the index when the test explicitly says so. |
| 12 | sane_unset GIT_TEST_SPLIT_INDEX && |
| 13 | git config splitIndex.maxPercentChange 100 && |
| 14 | |
| 15 | echo "cached content" >racy-file && |
| 16 | git add racy-file && |
| 17 | git commit -m initial && |
| 18 | |
| 19 | echo something >other-file && |
| 20 | # No raciness with this file. |
| 21 | test-tool chmtime =-20 other-file && |
| 22 | |
| 23 | echo "+cached content" >expect |
| 24 | ' |
| 25 | |
| 26 | check_cached_diff () { |
| 27 | git diff-index --patch --cached $EMPTY_TREE racy-file >diff && |
| 28 | tail -1 diff >actual && |
| 29 | test_cmp expect actual |
| 30 | } |
| 31 | |
| 32 | trials="0 1 2 3 4" |
| 33 | for trial in $trials |
| 34 | do |
| 35 | test_expect_success "split the index while adding a racily clean file #$trial" ' |
| 36 | rm -f .git/index .git/sharedindex.* && |
| 37 | |
| 38 | # The next three commands must be run within the same |
| 39 | # second (so both writes to racy-file result in the same |
| 40 | # mtime) to create the interesting racy situation. |
| 41 | echo "cached content" >racy-file && |
| 42 | |
| 43 | # Update and split the index. The cache entry of |
| 44 | # racy-file will be stored only in the shared index. |
| 45 | git update-index --split-index --add racy-file && |
| 46 | |
| 47 | # File size must stay the same. |
| 48 | echo "dirty worktree" >racy-file && |
| 49 | |
| 50 | # Subsequent git commands should notice that racy-file |
| 51 | # and the split index have the same mtime, and check |
| 52 | # the content of the file to see if it is actually |
| 53 | # clean. |
| 54 | check_cached_diff |
| 55 | ' |
| 56 | done |
| 57 | |
| 58 | for trial in $trials |
| 59 | do |
| 60 | test_expect_success "add a racily clean file to an already split index #$trial" ' |
| 61 | rm -f .git/index .git/sharedindex.* && |
| 62 | |
| 63 | git update-index --split-index && |
| 64 | |
| 65 | # The next three commands must be run within the same |
| 66 | # second. |
| 67 | echo "cached content" >racy-file && |
| 68 | |
| 69 | # Update the split index. The cache entry of racy-file |
| 70 | # will be stored only in the split index. |
| 71 | git update-index --add racy-file && |
| 72 | |
| 73 | # File size must stay the same. |
| 74 | echo "dirty worktree" >racy-file && |
| 75 | |
| 76 | # Subsequent git commands should notice that racy-file |
| 77 | # and the split index have the same mtime, and check |
| 78 | # the content of the file to see if it is actually |
| 79 | # clean. |
| 80 | check_cached_diff |
| 81 | ' |
| 82 | done |
| 83 | |
| 84 | for trial in $trials |
| 85 | do |
| 86 | test_expect_success "split the index when the index contains a racily clean cache entry #$trial" ' |
| 87 | rm -f .git/index .git/sharedindex.* && |
| 88 | |
| 89 | # The next three commands must be run within the same |
| 90 | # second. |
| 91 | echo "cached content" >racy-file && |
| 92 | |
| 93 | git update-index --add racy-file && |
| 94 | |
| 95 | # File size must stay the same. |
| 96 | echo "dirty worktree" >racy-file && |
| 97 | |
| 98 | # Now wait a bit to ensure that the split index written |
| 99 | # below will get a more recent mtime than racy-file. |
| 100 | sleep 1 && |
| 101 | |
| 102 | # Update and split the index when the index contains |
| 103 | # the racily clean cache entry of racy-file. |
| 104 | # A corresponding replacement cache entry with smudged |
| 105 | # stat data should be added to the new split index. |
| 106 | git update-index --split-index --add other-file && |
| 107 | |
| 108 | # Subsequent git commands should notice the smudged |
| 109 | # stat data in the replacement cache entry and that it |
| 110 | # doesnt match with the file the worktree. |
| 111 | check_cached_diff |
| 112 | ' |
| 113 | done |
| 114 | |
| 115 | for trial in $trials |
| 116 | do |
| 117 | test_expect_success "update the split index when it contains a new racily clean cache entry #$trial" ' |
| 118 | rm -f .git/index .git/sharedindex.* && |
| 119 | |
| 120 | git update-index --split-index && |
| 121 | |
| 122 | # The next three commands must be run within the same |
| 123 | # second. |
| 124 | echo "cached content" >racy-file && |
| 125 | |
| 126 | # Update the split index. The cache entry of racy-file |
| 127 | # will be stored only in the split index. |
| 128 | git update-index --add racy-file && |
| 129 | |
| 130 | # File size must stay the same. |
| 131 | echo "dirty worktree" >racy-file && |
| 132 | |
| 133 | # Now wait a bit to ensure that the split index written |
| 134 | # below will get a more recent mtime than racy-file. |
| 135 | sleep 1 && |
| 136 | |
| 137 | # Update the split index when the racily clean cache |
| 138 | # entry of racy-file is only stored in the split index. |
| 139 | # An updated cache entry with smudged stat data should |
| 140 | # be added to the new split index. |
| 141 | git update-index --add other-file && |
| 142 | |
| 143 | # Subsequent git commands should notice the smudged |
| 144 | # stat data. |
| 145 | check_cached_diff |
| 146 | ' |
| 147 | done |
| 148 | |
| 149 | for trial in $trials |
| 150 | do |
| 151 | test_expect_success "update the split index when a racily clean cache entry is stored only in the shared index #$trial" ' |
| 152 | rm -f .git/index .git/sharedindex.* && |
| 153 | |
| 154 | # The next three commands must be run within the same |
| 155 | # second. |
| 156 | echo "cached content" >racy-file && |
| 157 | |
| 158 | # Update and split the index. The cache entry of |
| 159 | # racy-file will be stored only in the shared index. |
| 160 | git update-index --split-index --add racy-file && |
| 161 | |
| 162 | # File size must stay the same. |
| 163 | echo "dirty worktree" >racy-file && |
| 164 | |
| 165 | # Now wait a bit to ensure that the split index written |
| 166 | # below will get a more recent mtime than racy-file. |
| 167 | sleep 1 && |
| 168 | |
| 169 | # Update the split index when the racily clean cache |
| 170 | # entry of racy-file is only stored in the shared index. |
| 171 | # A corresponding replacement cache entry with smudged |
| 172 | # stat data should be added to the new split index. |
| 173 | git update-index --add other-file && |
| 174 | |
| 175 | # Subsequent git commands should notice the smudged |
| 176 | # stat data. |
| 177 | check_cached_diff |
| 178 | ' |
| 179 | done |
| 180 | |
| 181 | for trial in $trials |
| 182 | do |
| 183 | test_expect_success "update the split index after unpack trees() copied a racily clean cache entry from the shared index #$trial" ' |
| 184 | rm -f .git/index .git/sharedindex.* && |
| 185 | |
| 186 | # The next three commands must be run within the same |
| 187 | # second. |
| 188 | echo "cached content" >racy-file && |
| 189 | |
| 190 | # Update and split the index. The cache entry of |
| 191 | # racy-file will be stored only in the shared index. |
| 192 | git update-index --split-index --add racy-file && |
| 193 | |
| 194 | # File size must stay the same. |
| 195 | echo "dirty worktree" >racy-file && |
| 196 | |
| 197 | # Now wait a bit to ensure that the split index written |
| 198 | # below will get a more recent mtime than racy-file. |
| 199 | sleep 1 && |
| 200 | |
| 201 | # Update the split index after unpack_trees() copied the |
| 202 | # racily clean cache entry of racy-file from the shared |
| 203 | # index. A corresponding replacement cache entry |
| 204 | # with smudged stat data should be added to the new |
| 205 | # split index. |
| 206 | git read-tree -m HEAD && |
| 207 | |
| 208 | # Subsequent git commands should notice the smudged |
| 209 | # stat data. |
| 210 | check_cached_diff |
| 211 | ' |
| 212 | done |
| 213 | |
| 214 | test_done |