2ef96e92406406409f10788d827a1d937ce69561
[git/git.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=iso8859-1" commit -a -m "$(commit_msg iso8859-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 (iso8859-1 logoutputencoding)' '
66 hex=$(git log -1 --format="%h") &&
67 git -c "i18n.logOutputEncoding=iso8859-1" reset --hard > .actual &&
68 echo HEAD is now at $hex $(commit_msg iso8859-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=iso8859-1" commit -a -m "$(commit_msg iso8859-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