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