1#!/bin/sh
2#
3# Copyright (c) 2007 Carlos Rica
4#
5
6test_description='git reset
7
8Documented tests for git reset'
9
10. ./test-lib.sh
11
12commit_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
23test_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
47check_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
58test_expect_failure '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
65test_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
74cat >.cat_expect <<EOF
75secondfile:
761st line 2nd file
772nd line 2nd file
78EOF
79
80test_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
88test_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
97test_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
106test_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
118test_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
142test_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
165test_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
186cat >.cached_expect <<EOF
187diff --git a/secondfile b/secondfile
188index 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
195EOF
196cat >.cat_expect <<EOF
197secondfile:
1981st line 2nd file
1992nd line 2nd file
200EOF
201test_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
210cat >.cat_expect <<EOF
211secondfile:
2121st line 2nd file
2132nd line 2nd file
2143rd line 2nd file
215EOF
216test_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
228cat >.cat_expect <<EOF
229first:
2301st file
2312nd line 1st file
232second:
2332nd file
234EOF
235test_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
244cat >.cached_expect <<EOF
245diff --git a/first b/first
246deleted file mode 100644
247index 8206c22..0000000
248--- a/first
249+++ /dev/null
250@@ -1,2 +0,0 @@
251-1st file
252-2nd line 1st file
253diff --git a/second b/second
254deleted file mode 100644
255index 1bbba79..0000000
256--- a/second
257+++ /dev/null
258@@ -1 +0,0 @@
259-2nd file
260diff --git a/secondfile b/secondfile
261new file mode 100644
262index 0000000..44c5b58
263--- /dev/null
264+++ b/secondfile
265@@ -0,0 +1,2 @@
266+1st line 2nd file
267+2nd line 2nd file
268EOF
269cat >.cat_expect <<EOF
270secondfile:
2711st line 2nd file
2722nd line 2nd file
273EOF
274test_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
285cat >.diff_expect <<EOF
286diff --git a/first b/first
287deleted file mode 100644
288index 8206c22..0000000
289--- a/first
290+++ /dev/null
291@@ -1,2 +0,0 @@
292-1st file
293-2nd line 1st file
294diff --git a/second b/second
295deleted file mode 100644
296index 1bbba79..0000000
297--- a/second
298+++ /dev/null
299@@ -1 +0,0 @@
300-2nd file
301EOF
302>.cached_expect
303cat >.cat_expect <<EOF
304secondfile:
3051st line 2nd file
3062nd line 2nd file
307EOF
308test_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
317cat >.cat_expect <<EOF
318secondfile:
3191st line 2nd file
3202nd line 2nd file
321EOF
322test_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
338cat >.cat_expect <<EOF
339secondfile:
3401st line 2nd file
3412nd line 2nd file
3423rd line in branch2
343EOF
344test_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
364cat >.cat_expect <<EOF
365secondfile:
3661st line 2nd file
3672nd line 2nd file
368EOF
369test_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
383cat > expect << EOF
384diff --git a/file1 b/file1
385index d00491f..7ed6ff8 100644
386--- a/file1
387+++ b/file1
388@@ -1 +1 @@
389-1
390+5
391diff --git a/file2 b/file2
392deleted file mode 100644
393index 0cfbf08..0000000
394--- a/file2
395+++ /dev/null
396@@ -1 +0,0 @@
397-2
398EOF
399cat > cached_expect << EOF
400diff --git a/file4 b/file4
401new file mode 100644
402index 0000000..b8626c4
403--- /dev/null
404+++ b/file4
405@@ -0,0 +1 @@
406+4
407EOF
408test_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
427test_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
444test_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
451cat > expect << EOF
452Unstaged changes after reset:
453M file2
454EOF
455
456test_expect_success '--mixed refreshes the index' '
457 echo 123 >> file2 &&
458 git reset --mixed HEAD > output &&
459 test_i18ncmp expect output
460'
461
462test_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
478test_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
491test_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
503test_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
516test_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
528test_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
536test_done