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
6test_description='racy split index'
7
8. ./test-lib.sh
9
10test_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
26check_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
32trials="0 1 2 3 4"
33for trial in $trials
34do
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	'
56done
57
58for trial in $trials
59do
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	'
82done
83
84for trial in $trials
85do
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	'
113done
114
115for trial in $trials
116do
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	'
147done
148
149for trial in $trials
150do
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	'
179done
180
181for trial in $trials
182do
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	'
212done
213
214test_done
215