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