| #!/bin/sh | 
 |  | 
 | # This test can give false success if your machine is sufficiently | 
 | # slow or all trials happened to happen on second boundaries. | 
 |  | 
 | test_description='racy split index' | 
 |  | 
 | . ./test-lib.sh | 
 |  | 
 | test_expect_success 'setup' ' | 
 | 	# Only split the index when the test explicitly says so. | 
 | 	sane_unset GIT_TEST_SPLIT_INDEX && | 
 | 	git config splitIndex.maxPercentChange 100 && | 
 |  | 
 | 	echo "cached content" >racy-file && | 
 | 	git add racy-file && | 
 | 	git commit -m initial && | 
 |  | 
 | 	echo something >other-file && | 
 | 	# No raciness with this file. | 
 | 	test-tool chmtime =-20 other-file && | 
 |  | 
 | 	echo "+cached content" >expect | 
 | ' | 
 |  | 
 | check_cached_diff () { | 
 | 	git diff-index --patch --cached $EMPTY_TREE racy-file >diff && | 
 | 	tail -1 diff >actual && | 
 | 	test_cmp expect actual | 
 | } | 
 |  | 
 | trials="0 1 2 3 4" | 
 | for trial in $trials | 
 | do | 
 | 	test_expect_success "split the index while adding a racily clean file #$trial" ' | 
 | 		rm -f .git/index .git/sharedindex.* && | 
 |  | 
 | 		# The next three commands must be run within the same | 
 | 		# second (so both writes to racy-file result in the same | 
 | 		# mtime) to create the interesting racy situation. | 
 | 		echo "cached content" >racy-file && | 
 |  | 
 | 		# Update and split the index.  The cache entry of | 
 | 		# racy-file will be stored only in the shared index. | 
 | 		git update-index --split-index --add racy-file && | 
 |  | 
 | 		# File size must stay the same. | 
 | 		echo "dirty worktree" >racy-file && | 
 |  | 
 | 		# Subsequent git commands should notice that racy-file | 
 | 		# and the split index have the same mtime, and check | 
 | 		# the content of the file to see if it is actually | 
 | 		# clean. | 
 | 		check_cached_diff | 
 | 	' | 
 | done | 
 |  | 
 | for trial in $trials | 
 | do | 
 | 	test_expect_success "add a racily clean file to an already split index #$trial" ' | 
 | 		rm -f .git/index .git/sharedindex.* && | 
 |  | 
 | 		git update-index --split-index && | 
 |  | 
 | 		# The next three commands must be run within the same | 
 | 		# second. | 
 | 		echo "cached content" >racy-file && | 
 |  | 
 | 		# Update the split index.  The cache entry of racy-file | 
 | 		# will be stored only in the split index. | 
 | 		git update-index --add racy-file && | 
 |  | 
 | 		# File size must stay the same. | 
 | 		echo "dirty worktree" >racy-file && | 
 |  | 
 | 		# Subsequent git commands should notice that racy-file | 
 | 		# and the split index have the same mtime, and check | 
 | 		# the content of the file to see if it is actually | 
 | 		# clean. | 
 | 		check_cached_diff | 
 | 	' | 
 | done | 
 |  | 
 | for trial in $trials | 
 | do | 
 | 	test_expect_success "split the index when the index contains a racily clean cache entry #$trial" ' | 
 | 		rm -f .git/index .git/sharedindex.* && | 
 |  | 
 | 		# The next three commands must be run within the same | 
 | 		# second. | 
 | 		echo "cached content" >racy-file && | 
 |  | 
 | 		git update-index --add racy-file && | 
 |  | 
 | 		# File size must stay the same. | 
 | 		echo "dirty worktree" >racy-file && | 
 |  | 
 | 		# Now wait a bit to ensure that the split index written | 
 | 		# below will get a more recent mtime than racy-file. | 
 | 		sleep 1 && | 
 |  | 
 | 		# Update and split the index when the index contains | 
 | 		# the racily clean cache entry of racy-file. | 
 | 		# A corresponding replacement cache entry with smudged | 
 | 		# stat data should be added to the new split index. | 
 | 		git update-index --split-index --add other-file && | 
 |  | 
 | 		# Subsequent git commands should notice the smudged | 
 | 		# stat data in the replacement cache entry and that it | 
 | 		# doesnt match with the file the worktree. | 
 | 		check_cached_diff | 
 | 	' | 
 | done | 
 |  | 
 | for trial in $trials | 
 | do | 
 | 	test_expect_success "update the split index when it contains a new racily clean cache entry #$trial" ' | 
 | 		rm -f .git/index .git/sharedindex.* && | 
 |  | 
 | 		git update-index --split-index && | 
 |  | 
 | 		# The next three commands must be run within the same | 
 | 		# second. | 
 | 		echo "cached content" >racy-file && | 
 |  | 
 | 		# Update the split index.  The cache entry of racy-file | 
 | 		# will be stored only in the split index. | 
 | 		git update-index --add racy-file && | 
 |  | 
 | 		# File size must stay the same. | 
 | 		echo "dirty worktree" >racy-file && | 
 |  | 
 | 		# Now wait a bit to ensure that the split index written | 
 | 		# below will get a more recent mtime than racy-file. | 
 | 		sleep 1 && | 
 |  | 
 | 		# Update the split index when the racily clean cache | 
 | 		# entry of racy-file is only stored in the split index. | 
 | 		# An updated cache entry with smudged stat data should | 
 | 		# be added to the new split index. | 
 | 		git update-index --add other-file && | 
 |  | 
 | 		# Subsequent git commands should notice the smudged | 
 | 		# stat data. | 
 | 		check_cached_diff | 
 | 	' | 
 | done | 
 |  | 
 | for trial in $trials | 
 | do | 
 | 	test_expect_success "update the split index when a racily clean cache entry is stored only in the shared index #$trial" ' | 
 | 		rm -f .git/index .git/sharedindex.* && | 
 |  | 
 | 		# The next three commands must be run within the same | 
 | 		# second. | 
 | 		echo "cached content" >racy-file && | 
 |  | 
 | 		# Update and split the index.  The cache entry of | 
 | 		# racy-file will be stored only in the shared index. | 
 | 		git update-index --split-index --add racy-file && | 
 |  | 
 | 		# File size must stay the same. | 
 | 		echo "dirty worktree" >racy-file && | 
 |  | 
 | 		# Now wait a bit to ensure that the split index written | 
 | 		# below will get a more recent mtime than racy-file. | 
 | 		sleep 1 && | 
 |  | 
 | 		# Update the split index when the racily clean cache | 
 | 		# entry of racy-file is only stored in the shared index. | 
 | 		# A corresponding replacement cache entry with smudged | 
 | 		# stat data should be added to the new split index. | 
 | 		git update-index --add other-file && | 
 |  | 
 | 		# Subsequent git commands should notice the smudged | 
 | 		# stat data. | 
 | 		check_cached_diff | 
 | 	' | 
 | done | 
 |  | 
 | for trial in $trials | 
 | do | 
 | 	test_expect_success "update the split index after unpack trees() copied a racily clean cache entry from the shared index #$trial" ' | 
 | 		rm -f .git/index .git/sharedindex.* && | 
 |  | 
 | 		# The next three commands must be run within the same | 
 | 		# second. | 
 | 		echo "cached content" >racy-file && | 
 |  | 
 | 		# Update and split the index.  The cache entry of | 
 | 		# racy-file will be stored only in the shared index. | 
 | 		git update-index --split-index --add racy-file && | 
 |  | 
 | 		# File size must stay the same. | 
 | 		echo "dirty worktree" >racy-file && | 
 |  | 
 | 		# Now wait a bit to ensure that the split index written | 
 | 		# below will get a more recent mtime than racy-file. | 
 | 		sleep 1 && | 
 |  | 
 | 		# Update the split index after unpack_trees() copied the | 
 | 		# racily clean cache entry of racy-file from the shared | 
 | 		# index.  A corresponding replacement cache entry | 
 | 		# with smudged stat data should be added to the new | 
 | 		# split index. | 
 | 		git read-tree -m HEAD && | 
 |  | 
 | 		# Subsequent git commands should notice the smudged | 
 | 		# stat data. | 
 | 		check_cached_diff | 
 | 	' | 
 | done | 
 |  | 
 | test_done |