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