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