Merge branch 'jc/triangle-push-fixup'
[git] / t / t4200-rerere.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2006 Johannes E. Schindelin
4 #
5
6 test_description='git rerere
7
8 ! [fifth] version1
9  ! [first] first
10   ! [fourth] version1
11    ! [master] initial
12     ! [second] prefer first over second
13      ! [third] version2
14 ------
15      + [third] version2
16 +      [fifth] version1
17   +    [fourth] version1
18 + +  + [third^] third
19     -  [second] prefer first over second
20  +  +  [first] first
21     +  [second^] second
22 ++++++ [master] initial
23 '
24
25 . ./test-lib.sh
26
27 test_expect_success 'setup' '
28         cat >a1 <<-\EOF &&
29         Some title
30         ==========
31         Whether '\''tis nobler in the mind to suffer
32         The slings and arrows of outrageous fortune,
33         Or to take arms against a sea of troubles,
34         And by opposing end them? To die: to sleep;
35         No more; and by a sleep to say we end
36         The heart-ache and the thousand natural shocks
37         That flesh is heir to, '\''tis a consummation
38         Devoutly to be wish'\''d.
39         EOF
40
41         git add a1 &&
42         test_tick &&
43         git commit -q -a -m initial &&
44
45         cat >>a1 <<-\EOF &&
46         Some title
47         ==========
48         To die, to sleep;
49         To sleep: perchance to dream: ay, there'\''s the rub;
50         For in that sleep of death what dreams may come
51         When we have shuffled off this mortal coil,
52         Must give us pause: there'\''s the respect
53         That makes calamity of so long life;
54         EOF
55
56         git checkout -b first &&
57         test_tick &&
58         git commit -q -a -m first &&
59
60         git checkout -b second master &&
61         git show first:a1 |
62         sed -e "s/To die, t/To die! T/" -e "s/Some title/Some Title/" >a1 &&
63         echo "* END *" >>a1 &&
64         test_tick &&
65         git commit -q -a -m second
66 '
67
68 test_expect_success 'nothing recorded without rerere' '
69         rm -rf .git/rr-cache &&
70         git config rerere.enabled false &&
71         test_must_fail git merge first &&
72         ! test -d .git/rr-cache
73 '
74
75 test_expect_success 'activate rerere, old style (conflicting merge)' '
76         git reset --hard &&
77         mkdir .git/rr-cache &&
78         test_might_fail git config --unset rerere.enabled &&
79         test_must_fail git merge first &&
80
81         sha1=$("$PERL_PATH" -pe "s/     .*//" .git/MERGE_RR) &&
82         rr=.git/rr-cache/$sha1 &&
83         grep "^=======\$" $rr/preimage &&
84         ! test -f $rr/postimage &&
85         ! test -f $rr/thisimage
86 '
87
88 test_expect_success 'rerere.enabled works, too' '
89         rm -rf .git/rr-cache &&
90         git config rerere.enabled true &&
91         git reset --hard &&
92         test_must_fail git merge first &&
93
94         sha1=$("$PERL_PATH" -pe "s/     .*//" .git/MERGE_RR) &&
95         rr=.git/rr-cache/$sha1 &&
96         grep ^=======$ $rr/preimage
97 '
98
99 test_expect_success 'set up rr-cache' '
100         rm -rf .git/rr-cache &&
101         git config rerere.enabled true &&
102         git reset --hard &&
103         test_must_fail git merge first &&
104         sha1=$("$PERL_PATH" -pe "s/     .*//" .git/MERGE_RR) &&
105         rr=.git/rr-cache/$sha1
106 '
107
108 test_expect_success 'rr-cache looks sane' '
109         # no postimage or thisimage yet
110         ! test -f $rr/postimage &&
111         ! test -f $rr/thisimage &&
112
113         # preimage has right number of lines
114         cnt=$(sed -ne "/^<<<<<<</,/^>>>>>>>/p" $rr/preimage | wc -l) &&
115         echo $cnt &&
116         test $cnt = 13
117 '
118
119 test_expect_success 'rerere diff' '
120         git show first:a1 >a1 &&
121         cat >expect <<-\EOF &&
122         --- a/a1
123         +++ b/a1
124         @@ -1,4 +1,4 @@
125         -Some Title
126         +Some title
127          ==========
128          Whether '\''tis nobler in the mind to suffer
129          The slings and arrows of outrageous fortune,
130         @@ -8,21 +8,11 @@
131          The heart-ache and the thousand natural shocks
132          That flesh is heir to, '\''tis a consummation
133          Devoutly to be wish'\''d.
134         -<<<<<<<
135         -Some Title
136         -==========
137         -To die! To sleep;
138         -=======
139          Some title
140          ==========
141          To die, to sleep;
142         ->>>>>>>
143          To sleep: perchance to dream: ay, there'\''s the rub;
144          For in that sleep of death what dreams may come
145          When we have shuffled off this mortal coil,
146          Must give us pause: there'\''s the respect
147          That makes calamity of so long life;
148         -<<<<<<<
149         -=======
150         -* END *
151         ->>>>>>>
152         EOF
153         git rerere diff >out &&
154         test_cmp expect out
155 '
156
157 test_expect_success 'rerere status' '
158         echo a1 >expect &&
159         git rerere status >out &&
160         test_cmp expect out
161 '
162
163 test_expect_success 'first postimage wins' '
164         git show first:a1 | sed "s/To die: t/To die! T/" >expect &&
165
166         git commit -q -a -m "prefer first over second" &&
167         test -f $rr/postimage &&
168
169         oldmtimepost=$(test-chmtime -v -60 $rr/postimage | cut -f 1) &&
170
171         git checkout -b third master &&
172         git show second^:a1 | sed "s/To die: t/To die! T/" >a1 &&
173         git commit -q -a -m third &&
174
175         test_must_fail git pull . first &&
176         # rerere kicked in
177         ! grep "^=======\$" a1 &&
178         test_cmp expect a1
179 '
180
181 test_expect_success 'rerere updates postimage timestamp' '
182         newmtimepost=$(test-chmtime -v +0 $rr/postimage | cut -f 1) &&
183         test $oldmtimepost -lt $newmtimepost
184 '
185
186 test_expect_success 'rerere clear' '
187         rm $rr/postimage &&
188         echo "$sha1     a1" | "$PERL_PATH" -pe "y/\012/\000/" >.git/MERGE_RR &&
189         git rerere clear &&
190         ! test -d $rr
191 '
192
193 test_expect_success 'set up for garbage collection tests' '
194         mkdir -p $rr &&
195         echo Hello >$rr/preimage &&
196         echo World >$rr/postimage &&
197
198         sha2=4000000000000000000000000000000000000000 &&
199         rr2=.git/rr-cache/$sha2 &&
200         mkdir $rr2 &&
201         echo Hello >$rr2/preimage &&
202
203         almost_15_days_ago=$((60-15*86400)) &&
204         just_over_15_days_ago=$((-1-15*86400)) &&
205         almost_60_days_ago=$((60-60*86400)) &&
206         just_over_60_days_ago=$((-1-60*86400)) &&
207
208         test-chmtime =$just_over_60_days_ago $rr/preimage &&
209         test-chmtime =$almost_60_days_ago $rr/postimage &&
210         test-chmtime =$almost_15_days_ago $rr2/preimage
211 '
212
213 test_expect_success 'gc preserves young or recently used records' '
214         git rerere gc &&
215         test -f $rr/preimage &&
216         test -f $rr2/preimage
217 '
218
219 test_expect_success 'old records rest in peace' '
220         test-chmtime =$just_over_60_days_ago $rr/postimage &&
221         test-chmtime =$just_over_15_days_ago $rr2/preimage &&
222         git rerere gc &&
223         ! test -f $rr/preimage &&
224         ! test -f $rr2/preimage
225 '
226
227 test_expect_success 'setup: file2 added differently in two branches' '
228         git reset --hard &&
229
230         git checkout -b fourth &&
231         echo Hallo >file2 &&
232         git add file2 &&
233         test_tick &&
234         git commit -m version1 &&
235
236         git checkout third &&
237         echo Bello >file2 &&
238         git add file2 &&
239         test_tick &&
240         git commit -m version2 &&
241
242         test_must_fail git merge fourth &&
243         echo Cello >file2 &&
244         git add file2 &&
245         git commit -m resolution
246 '
247
248 test_expect_success 'resolution was recorded properly' '
249         echo Cello >expected &&
250
251         git reset --hard HEAD~2 &&
252         git checkout -b fifth &&
253
254         echo Hallo >file3 &&
255         git add file3 &&
256         test_tick &&
257         git commit -m version1 &&
258
259         git checkout third &&
260         echo Bello >file3 &&
261         git add file3 &&
262         test_tick &&
263         git commit -m version2 &&
264         git tag version2 &&
265
266         test_must_fail git merge fifth &&
267         test_cmp expected file3 &&
268         test_must_fail git update-index --refresh
269 '
270
271 test_expect_success 'rerere.autoupdate' '
272         git config rerere.autoupdate true &&
273         git reset --hard &&
274         git checkout version2 &&
275         test_must_fail git merge fifth &&
276         git update-index --refresh
277 '
278
279 test_expect_success 'merge --rerere-autoupdate' '
280         test_might_fail git config --unset rerere.autoupdate &&
281         git reset --hard &&
282         git checkout version2 &&
283         test_must_fail git merge --rerere-autoupdate fifth &&
284         git update-index --refresh
285 '
286
287 test_expect_success 'merge --no-rerere-autoupdate' '
288         headblob=$(git rev-parse version2:file3) &&
289         mergeblob=$(git rev-parse fifth:file3) &&
290         cat >expected <<-EOF &&
291         100644 $headblob 2      file3
292         100644 $mergeblob 3     file3
293         EOF
294
295         git config rerere.autoupdate true &&
296         git reset --hard &&
297         git checkout version2 &&
298         test_must_fail git merge --no-rerere-autoupdate fifth &&
299         git ls-files -u >actual &&
300         test_cmp expected actual
301 '
302
303 test_expect_success 'set up an unresolved merge' '
304         headblob=$(git rev-parse version2:file3) &&
305         mergeblob=$(git rev-parse fifth:file3) &&
306         cat >expected.unresolved <<-EOF &&
307         100644 $headblob 2      file3
308         100644 $mergeblob 3     file3
309         EOF
310
311         test_might_fail git config --unset rerere.autoupdate &&
312         git reset --hard &&
313         git checkout version2 &&
314         fifth=$(git rev-parse fifth) &&
315         echo "$fifth            branch 'fifth' of ." |
316         git fmt-merge-msg >msg &&
317         ancestor=$(git merge-base version2 fifth) &&
318         test_must_fail git merge-recursive "$ancestor" -- HEAD fifth &&
319
320         git ls-files --stage >failedmerge &&
321         cp file3 file3.conflict &&
322
323         git ls-files -u >actual &&
324         test_cmp expected.unresolved actual
325 '
326
327 test_expect_success 'explicit rerere' '
328         test_might_fail git config --unset rerere.autoupdate &&
329         git rm -fr --cached . &&
330         git update-index --index-info <failedmerge &&
331         cp file3.conflict file3 &&
332         test_must_fail git update-index --refresh -q &&
333
334         git rerere &&
335         git ls-files -u >actual &&
336         test_cmp expected.unresolved actual
337 '
338
339 test_expect_success 'explicit rerere with autoupdate' '
340         git config rerere.autoupdate true &&
341         git rm -fr --cached . &&
342         git update-index --index-info <failedmerge &&
343         cp file3.conflict file3 &&
344         test_must_fail git update-index --refresh -q &&
345
346         git rerere &&
347         git update-index --refresh
348 '
349
350 test_expect_success 'explicit rerere --rerere-autoupdate overrides' '
351         git config rerere.autoupdate false &&
352         git rm -fr --cached . &&
353         git update-index --index-info <failedmerge &&
354         cp file3.conflict file3 &&
355         git rerere &&
356         git ls-files -u >actual1 &&
357
358         git rm -fr --cached . &&
359         git update-index --index-info <failedmerge &&
360         cp file3.conflict file3 &&
361         git rerere --rerere-autoupdate &&
362         git update-index --refresh &&
363
364         git rm -fr --cached . &&
365         git update-index --index-info <failedmerge &&
366         cp file3.conflict file3 &&
367         git rerere --rerere-autoupdate --no-rerere-autoupdate &&
368         git ls-files -u >actual2 &&
369
370         git rm -fr --cached . &&
371         git update-index --index-info <failedmerge &&
372         cp file3.conflict file3 &&
373         git rerere --rerere-autoupdate --no-rerere-autoupdate --rerere-autoupdate &&
374         git update-index --refresh &&
375
376         test_cmp expected.unresolved actual1 &&
377         test_cmp expected.unresolved actual2
378 '
379
380 test_expect_success 'rerere --no-no-rerere-autoupdate' '
381         git rm -fr --cached . &&
382         git update-index --index-info <failedmerge &&
383         cp file3.conflict file3 &&
384         test_must_fail git rerere --no-no-rerere-autoupdate 2>err &&
385         test_i18ngrep [Uu]sage err &&
386         test_must_fail git update-index --refresh
387 '
388
389 test_expect_success 'rerere -h' '
390         test_must_fail git rerere -h >help &&
391         test_i18ngrep [Uu]sage help
392 '
393
394 test_done