pretty: --format output should honor logOutputEncoding
[git] / t / t7102-reset.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2007 Carlos Rica
4 #
5
6 test_description='git reset
7
8 Documented tests for git reset'
9
10 . ./test-lib.sh
11
12 commit_msg () {
13         # String "modify 2nd file (changed)" partly in German(translated with Google Translate),
14         # encoded in UTF-8, used as a commit log message below.
15         msg=$(printf "modify 2nd file (ge\303\244ndert)")
16         if test -n "$1"
17         then
18                 msg=$(echo $msg | iconv -f utf-8 -t $1)
19         fi
20         echo $msg
21 }
22
23 test_expect_success 'creating initial files and commits' '
24         test_tick &&
25         echo "1st file" >first &&
26         git add first &&
27         git commit -m "create 1st file" &&
28
29         echo "2nd file" >second &&
30         git add second &&
31         git commit -m "create 2nd file" &&
32
33         echo "2nd line 1st file" >>first &&
34         git commit -a -m "modify 1st file" &&
35
36         git rm first &&
37         git mv second secondfile &&
38         git commit -a -m "remove 1st and rename 2nd" &&
39
40         echo "1st line 2nd file" >secondfile &&
41         echo "2nd line 2nd file" >>secondfile &&
42         git -c "i18n.commitEncoding=iso-8859-1" commit -a -m "$(commit_msg iso-8859-1)" &&
43         head5=$(git rev-parse --verify HEAD)
44 '
45 # git log --pretty=oneline # to see those SHA1 involved
46
47 check_changes () {
48         test "$(git rev-parse HEAD)" = "$1" &&
49         git diff | test_cmp .diff_expect - &&
50         git diff --cached | test_cmp .cached_expect - &&
51         for FILE in *
52         do
53                 echo $FILE':'
54                 cat $FILE || return
55         done | test_cmp .cat_expect -
56 }
57
58 test_expect_success 'reset --hard message' '
59         hex=$(git log -1 --format="%h") &&
60         git reset --hard > .actual &&
61         echo HEAD is now at $hex $(commit_msg) > .expected &&
62         test_cmp .expected .actual
63 '
64
65 test_expect_success 'reset --hard message (iso-8859-1 logoutencoding)' '
66         hex=$(git log -1 --format="%h") &&
67         git -c "i18n.logOutputEncoding=iso-8859-1" reset --hard > .actual &&
68         echo HEAD is now at $hex $(commit_msg iso-8859-1) > .expected &&
69         test_cmp .expected .actual
70 '
71
72 >.diff_expect
73 >.cached_expect
74 cat >.cat_expect <<EOF
75 secondfile:
76 1st line 2nd file
77 2nd line 2nd file
78 EOF
79
80 test_expect_success 'giving a non existing revision should fail' '
81         test_must_fail git reset aaaaaa &&
82         test_must_fail git reset --mixed aaaaaa &&
83         test_must_fail git reset --soft aaaaaa &&
84         test_must_fail git reset --hard aaaaaa &&
85         check_changes $head5
86 '
87
88 test_expect_success 'reset --soft with unmerged index should fail' '
89         touch .git/MERGE_HEAD &&
90         echo "100644 44c5b5884550c17758737edcced463447b91d42b 1 un" |
91                 git update-index --index-info &&
92         test_must_fail git reset --soft HEAD &&
93         rm .git/MERGE_HEAD &&
94         git rm --cached -- un
95 '
96
97 test_expect_success \
98         'giving paths with options different than --mixed should fail' '
99         test_must_fail git reset --soft -- first &&
100         test_must_fail git reset --hard -- first &&
101         test_must_fail git reset --soft HEAD^ -- first &&
102         test_must_fail git reset --hard HEAD^ -- first &&
103         check_changes $head5
104 '
105
106 test_expect_success 'giving unrecognized options should fail' '
107         test_must_fail git reset --other &&
108         test_must_fail git reset -o &&
109         test_must_fail git reset --mixed --other &&
110         test_must_fail git reset --mixed -o &&
111         test_must_fail git reset --soft --other &&
112         test_must_fail git reset --soft -o &&
113         test_must_fail git reset --hard --other &&
114         test_must_fail git reset --hard -o &&
115         check_changes $head5
116 '
117
118 test_expect_success \
119         'trying to do reset --soft with pending merge should fail' '
120         git branch branch1 &&
121         git branch branch2 &&
122
123         git checkout branch1 &&
124         echo "3rd line in branch1" >>secondfile &&
125         git commit -a -m "change in branch1" &&
126
127         git checkout branch2 &&
128         echo "3rd line in branch2" >>secondfile &&
129         git commit -a -m "change in branch2" &&
130
131         test_must_fail git merge branch1 &&
132         test_must_fail git reset --soft &&
133
134         printf "1st line 2nd file\n2nd line 2nd file\n3rd line" >secondfile &&
135         git commit -a -m "the change in branch2" &&
136
137         git checkout master &&
138         git branch -D branch1 branch2 &&
139         check_changes $head5
140 '
141
142 test_expect_success \
143         'trying to do reset --soft with pending checkout merge should fail' '
144         git branch branch3 &&
145         git branch branch4 &&
146
147         git checkout branch3 &&
148         echo "3rd line in branch3" >>secondfile &&
149         git commit -a -m "line in branch3" &&
150
151         git checkout branch4 &&
152         echo "3rd line in branch4" >>secondfile &&
153
154         git checkout -m branch3 &&
155         test_must_fail git reset --soft &&
156
157         printf "1st line 2nd file\n2nd line 2nd file\n3rd line" >secondfile &&
158         git commit -a -m "the line in branch3" &&
159
160         git checkout master &&
161         git branch -D branch3 branch4 &&
162         check_changes $head5
163 '
164
165 test_expect_success \
166         'resetting to HEAD with no changes should succeed and do nothing' '
167         git reset --hard &&
168                 check_changes $head5 &&
169         git reset --hard HEAD &&
170                 check_changes $head5 &&
171         git reset --soft &&
172                 check_changes $head5 &&
173         git reset --soft HEAD &&
174                 check_changes $head5 &&
175         git reset --mixed &&
176                 check_changes $head5 &&
177         git reset --mixed HEAD &&
178                 check_changes $head5 &&
179         git reset &&
180                 check_changes $head5 &&
181         git reset HEAD &&
182                 check_changes $head5
183 '
184
185 >.diff_expect
186 cat >.cached_expect <<EOF
187 diff --git a/secondfile b/secondfile
188 index 1bbba79..44c5b58 100644
189 --- a/secondfile
190 +++ b/secondfile
191 @@ -1 +1,2 @@
192 -2nd file
193 +1st line 2nd file
194 +2nd line 2nd file
195 EOF
196 cat >.cat_expect <<EOF
197 secondfile:
198 1st line 2nd file
199 2nd line 2nd file
200 EOF
201 test_expect_success '--soft reset only should show changes in diff --cached' '
202         git reset --soft HEAD^ &&
203         check_changes d1a4bc3abce4829628ae2dcb0d60ef3d1a78b1c4 &&
204         test "$(git rev-parse ORIG_HEAD)" = \
205                         $head5
206 '
207
208 >.diff_expect
209 >.cached_expect
210 cat >.cat_expect <<EOF
211 secondfile:
212 1st line 2nd file
213 2nd line 2nd file
214 3rd line 2nd file
215 EOF
216 test_expect_success \
217         'changing files and redo the last commit should succeed' '
218         echo "3rd line 2nd file" >>secondfile &&
219         git commit -a -C ORIG_HEAD &&
220         head4=$(git rev-parse --verify HEAD) &&
221         check_changes $head4 &&
222         test "$(git rev-parse ORIG_HEAD)" = \
223                         $head5
224 '
225
226 >.diff_expect
227 >.cached_expect
228 cat >.cat_expect <<EOF
229 first:
230 1st file
231 2nd line 1st file
232 second:
233 2nd file
234 EOF
235 test_expect_success \
236         '--hard reset should change the files and undo commits permanently' '
237         git reset --hard HEAD~2 &&
238         check_changes ddaefe00f1da16864591c61fdc7adb5d7cd6b74e &&
239         test "$(git rev-parse ORIG_HEAD)" = \
240                         $head4
241 '
242
243 >.diff_expect
244 cat >.cached_expect <<EOF
245 diff --git a/first b/first
246 deleted file mode 100644
247 index 8206c22..0000000
248 --- a/first
249 +++ /dev/null
250 @@ -1,2 +0,0 @@
251 -1st file
252 -2nd line 1st file
253 diff --git a/second b/second
254 deleted file mode 100644
255 index 1bbba79..0000000
256 --- a/second
257 +++ /dev/null
258 @@ -1 +0,0 @@
259 -2nd file
260 diff --git a/secondfile b/secondfile
261 new file mode 100644
262 index 0000000..44c5b58
263 --- /dev/null
264 +++ b/secondfile
265 @@ -0,0 +1,2 @@
266 +1st line 2nd file
267 +2nd line 2nd file
268 EOF
269 cat >.cat_expect <<EOF
270 secondfile:
271 1st line 2nd file
272 2nd line 2nd file
273 EOF
274 test_expect_success \
275         'redoing changes adding them without commit them should succeed' '
276         git rm first &&
277         git mv second secondfile &&
278
279         echo "1st line 2nd file" >secondfile &&
280         echo "2nd line 2nd file" >>secondfile &&
281         git add secondfile &&
282         check_changes ddaefe00f1da16864591c61fdc7adb5d7cd6b74e
283 '
284
285 cat >.diff_expect <<EOF
286 diff --git a/first b/first
287 deleted file mode 100644
288 index 8206c22..0000000
289 --- a/first
290 +++ /dev/null
291 @@ -1,2 +0,0 @@
292 -1st file
293 -2nd line 1st file
294 diff --git a/second b/second
295 deleted file mode 100644
296 index 1bbba79..0000000
297 --- a/second
298 +++ /dev/null
299 @@ -1 +0,0 @@
300 -2nd file
301 EOF
302 >.cached_expect
303 cat >.cat_expect <<EOF
304 secondfile:
305 1st line 2nd file
306 2nd line 2nd file
307 EOF
308 test_expect_success '--mixed reset to HEAD should unadd the files' '
309         git reset &&
310         check_changes ddaefe00f1da16864591c61fdc7adb5d7cd6b74e &&
311         test "$(git rev-parse ORIG_HEAD)" = \
312                         ddaefe00f1da16864591c61fdc7adb5d7cd6b74e
313 '
314
315 >.diff_expect
316 >.cached_expect
317 cat >.cat_expect <<EOF
318 secondfile:
319 1st line 2nd file
320 2nd line 2nd file
321 EOF
322 test_expect_success 'redoing the last two commits should succeed' '
323         git add secondfile &&
324         git reset --hard ddaefe00f1da16864591c61fdc7adb5d7cd6b74e &&
325
326         git rm first &&
327         git mv second secondfile &&
328         git commit -a -m "remove 1st and rename 2nd" &&
329
330         echo "1st line 2nd file" >secondfile &&
331         echo "2nd line 2nd file" >>secondfile &&
332         git -c "i18n.commitEncoding=iso-8859-1" commit -a -m "$(commit_msg iso-8859-1)" &&
333         check_changes $head5
334 '
335
336 >.diff_expect
337 >.cached_expect
338 cat >.cat_expect <<EOF
339 secondfile:
340 1st line 2nd file
341 2nd line 2nd file
342 3rd line in branch2
343 EOF
344 test_expect_success '--hard reset to HEAD should clear a failed merge' '
345         git branch branch1 &&
346         git branch branch2 &&
347
348         git checkout branch1 &&
349         echo "3rd line in branch1" >>secondfile &&
350         git commit -a -m "change in branch1" &&
351
352         git checkout branch2 &&
353         echo "3rd line in branch2" >>secondfile &&
354         git commit -a -m "change in branch2" &&
355         head3=$(git rev-parse --verify HEAD) &&
356
357         test_must_fail git pull . branch1 &&
358         git reset --hard &&
359         check_changes $head3
360 '
361
362 >.diff_expect
363 >.cached_expect
364 cat >.cat_expect <<EOF
365 secondfile:
366 1st line 2nd file
367 2nd line 2nd file
368 EOF
369 test_expect_success \
370         '--hard reset to ORIG_HEAD should clear a fast-forward merge' '
371         git reset --hard HEAD^ &&
372         check_changes $head5 &&
373
374         git pull . branch1 &&
375         git reset --hard ORIG_HEAD &&
376         check_changes $head5 &&
377
378         git checkout master &&
379         git branch -D branch1 branch2 &&
380         check_changes $head5
381 '
382
383 cat > expect << EOF
384 diff --git a/file1 b/file1
385 index d00491f..7ed6ff8 100644
386 --- a/file1
387 +++ b/file1
388 @@ -1 +1 @@
389 -1
390 +5
391 diff --git a/file2 b/file2
392 deleted file mode 100644
393 index 0cfbf08..0000000
394 --- a/file2
395 +++ /dev/null
396 @@ -1 +0,0 @@
397 -2
398 EOF
399 cat > cached_expect << EOF
400 diff --git a/file4 b/file4
401 new file mode 100644
402 index 0000000..b8626c4
403 --- /dev/null
404 +++ b/file4
405 @@ -0,0 +1 @@
406 +4
407 EOF
408 test_expect_success 'test --mixed <paths>' '
409         echo 1 > file1 &&
410         echo 2 > file2 &&
411         git add file1 file2 &&
412         test_tick &&
413         git commit -m files &&
414         git rm file2 &&
415         echo 3 > file3 &&
416         echo 4 > file4 &&
417         echo 5 > file1 &&
418         git add file1 file3 file4 &&
419         git reset HEAD -- file1 file2 file3 &&
420         test_must_fail git diff --quiet &&
421         git diff > output &&
422         test_cmp output expect &&
423         git diff --cached > output &&
424         test_cmp output cached_expect
425 '
426
427 test_expect_success 'test resetting the index at give paths' '
428
429         mkdir sub &&
430         >sub/file1 &&
431         >sub/file2 &&
432         git update-index --add sub/file1 sub/file2 &&
433         T=$(git write-tree) &&
434         git reset HEAD sub/file2 &&
435         test_must_fail git diff --quiet &&
436         U=$(git write-tree) &&
437         echo "$T" &&
438         echo "$U" &&
439         test_must_fail git diff-index --cached --exit-code "$T" &&
440         test "$T" != "$U"
441
442 '
443
444 test_expect_success 'resetting an unmodified path is a no-op' '
445         git reset --hard &&
446         git reset -- file1 &&
447         git diff-files --exit-code &&
448         git diff-index --cached --exit-code HEAD
449 '
450
451 cat > expect << EOF
452 Unstaged changes after reset:
453 M       file2
454 EOF
455
456 test_expect_success '--mixed refreshes the index' '
457         echo 123 >> file2 &&
458         git reset --mixed HEAD > output &&
459         test_i18ncmp expect output
460 '
461
462 test_expect_success 'resetting specific path that is unmerged' '
463         git rm --cached file2 &&
464         F1=$(git rev-parse HEAD:file1) &&
465         F2=$(git rev-parse HEAD:file2) &&
466         F3=$(git rev-parse HEAD:secondfile) &&
467         {
468                 echo "100644 $F1 1      file2" &&
469                 echo "100644 $F2 2      file2" &&
470                 echo "100644 $F3 3      file2"
471         } | git update-index --index-info &&
472         git ls-files -u &&
473         git reset HEAD file2 &&
474         test_must_fail git diff --quiet &&
475         git diff-index --exit-code --cached HEAD
476 '
477
478 test_expect_success 'disambiguation (1)' '
479
480         git reset --hard &&
481         >secondfile &&
482         git add secondfile &&
483         git reset secondfile &&
484         test_must_fail git diff --quiet -- secondfile &&
485         test -z "$(git diff --cached --name-only)" &&
486         test -f secondfile &&
487         test ! -s secondfile
488
489 '
490
491 test_expect_success 'disambiguation (2)' '
492
493         git reset --hard &&
494         >secondfile &&
495         git add secondfile &&
496         rm -f secondfile &&
497         test_must_fail git reset secondfile &&
498         test -n "$(git diff --cached --name-only -- secondfile)" &&
499         test ! -f secondfile
500
501 '
502
503 test_expect_success 'disambiguation (3)' '
504
505         git reset --hard &&
506         >secondfile &&
507         git add secondfile &&
508         rm -f secondfile &&
509         git reset HEAD secondfile &&
510         test_must_fail git diff --quiet &&
511         test -z "$(git diff --cached --name-only)" &&
512         test ! -f secondfile
513
514 '
515
516 test_expect_success 'disambiguation (4)' '
517
518         git reset --hard &&
519         >secondfile &&
520         git add secondfile &&
521         rm -f secondfile &&
522         git reset -- secondfile &&
523         test_must_fail git diff --quiet &&
524         test -z "$(git diff --cached --name-only)" &&
525         test ! -f secondfile
526 '
527
528 test_expect_success 'reset with paths accepts tree' '
529         # for simpler tests, drop last commit containing added files
530         git reset --hard HEAD^ &&
531         git reset HEAD^^{tree} -- . &&
532         git diff --cached HEAD^ --exit-code &&
533         git diff HEAD --exit-code
534 '
535
536 test_done