t / t3420-rebase-autostash.shon commit t/helper: merge test-chmtime into test-tool (0e49649)
   1#!/bin/sh
   2#
   3# Copyright (c) 2013 Ramkumar Ramachandra
   4#
   5
   6test_description='git rebase --autostash tests'
   7. ./test-lib.sh
   8
   9test_expect_success setup '
  10        echo hello-world >file0 &&
  11        git add . &&
  12        test_tick &&
  13        git commit -m "initial commit" &&
  14        git checkout -b feature-branch &&
  15        echo another-hello >file1 &&
  16        echo goodbye >file2 &&
  17        git add . &&
  18        test_tick &&
  19        git commit -m "second commit" &&
  20        echo final-goodbye >file3 &&
  21        git add . &&
  22        test_tick &&
  23        git commit -m "third commit" &&
  24        git checkout -b unrelated-onto-branch master &&
  25        echo unrelated >file4 &&
  26        git add . &&
  27        test_tick &&
  28        git commit -m "unrelated commit" &&
  29        git checkout -b related-onto-branch master &&
  30        echo conflicting-change >file2 &&
  31        git add . &&
  32        test_tick &&
  33        git commit -m "related commit"
  34'
  35
  36create_expected_success_am () {
  37        cat >expected <<-EOF
  38        $(grep "^Created autostash: [0-9a-f][0-9a-f]*\$" actual)
  39        HEAD is now at $(git rev-parse --short feature-branch) third commit
  40        First, rewinding head to replay your work on top of it...
  41        Applying: second commit
  42        Applying: third commit
  43        Applied autostash.
  44        EOF
  45}
  46
  47create_expected_success_interactive () {
  48        q_to_cr >expected <<-EOF
  49        $(grep "^Created autostash: [0-9a-f][0-9a-f]*\$" actual)
  50        HEAD is now at $(git rev-parse --short feature-branch) third commit
  51        Rebasing (1/2)QRebasing (2/2)QApplied autostash.
  52        Successfully rebased and updated refs/heads/rebased-feature-branch.
  53        EOF
  54}
  55
  56create_expected_success_merge () {
  57        cat >expected <<-EOF
  58        $(grep "^Created autostash: [0-9a-f][0-9a-f]*\$" actual)
  59        HEAD is now at $(git rev-parse --short feature-branch) third commit
  60        First, rewinding head to replay your work on top of it...
  61        Merging unrelated-onto-branch with HEAD~1
  62        Merging:
  63        $(git rev-parse --short unrelated-onto-branch) unrelated commit
  64        $(git rev-parse --short feature-branch^) second commit
  65        found 1 common ancestor:
  66        $(git rev-parse --short feature-branch~2) initial commit
  67        [detached HEAD $(git rev-parse --short rebased-feature-branch~1)] second commit
  68         Author: A U Thor <author@example.com>
  69         Date: Thu Apr 7 15:14:13 2005 -0700
  70         2 files changed, 2 insertions(+)
  71         create mode 100644 file1
  72         create mode 100644 file2
  73        Committed: 0001 second commit
  74        Merging unrelated-onto-branch with HEAD~0
  75        Merging:
  76        $(git rev-parse --short rebased-feature-branch~1) second commit
  77        $(git rev-parse --short feature-branch) third commit
  78        found 1 common ancestor:
  79        $(git rev-parse --short feature-branch~1) second commit
  80        [detached HEAD $(git rev-parse --short rebased-feature-branch)] third commit
  81         Author: A U Thor <author@example.com>
  82         Date: Thu Apr 7 15:15:13 2005 -0700
  83         1 file changed, 1 insertion(+)
  84         create mode 100644 file3
  85        Committed: 0002 third commit
  86        All done.
  87        Applied autostash.
  88        EOF
  89}
  90
  91create_expected_failure_am () {
  92        cat >expected <<-EOF
  93        $(grep "^Created autostash: [0-9a-f][0-9a-f]*\$" actual)
  94        HEAD is now at $(git rev-parse --short feature-branch) third commit
  95        First, rewinding head to replay your work on top of it...
  96        Applying: second commit
  97        Applying: third commit
  98        Applying autostash resulted in conflicts.
  99        Your changes are safe in the stash.
 100        You can run "git stash pop" or "git stash drop" at any time.
 101        EOF
 102}
 103
 104create_expected_failure_interactive () {
 105        q_to_cr >expected <<-EOF
 106        $(grep "^Created autostash: [0-9a-f][0-9a-f]*\$" actual)
 107        HEAD is now at $(git rev-parse --short feature-branch) third commit
 108        Rebasing (1/2)QRebasing (2/2)QApplying autostash resulted in conflicts.
 109        Your changes are safe in the stash.
 110        You can run "git stash pop" or "git stash drop" at any time.
 111        Successfully rebased and updated refs/heads/rebased-feature-branch.
 112        EOF
 113}
 114
 115create_expected_failure_merge () {
 116        cat >expected <<-EOF
 117        $(grep "^Created autostash: [0-9a-f][0-9a-f]*\$" actual)
 118        HEAD is now at $(git rev-parse --short feature-branch) third commit
 119        First, rewinding head to replay your work on top of it...
 120        Merging unrelated-onto-branch with HEAD~1
 121        Merging:
 122        $(git rev-parse --short unrelated-onto-branch) unrelated commit
 123        $(git rev-parse --short feature-branch^) second commit
 124        found 1 common ancestor:
 125        $(git rev-parse --short feature-branch~2) initial commit
 126        [detached HEAD $(git rev-parse --short rebased-feature-branch~1)] second commit
 127         Author: A U Thor <author@example.com>
 128         Date: Thu Apr 7 15:14:13 2005 -0700
 129         2 files changed, 2 insertions(+)
 130         create mode 100644 file1
 131         create mode 100644 file2
 132        Committed: 0001 second commit
 133        Merging unrelated-onto-branch with HEAD~0
 134        Merging:
 135        $(git rev-parse --short rebased-feature-branch~1) second commit
 136        $(git rev-parse --short feature-branch) third commit
 137        found 1 common ancestor:
 138        $(git rev-parse --short feature-branch~1) second commit
 139        [detached HEAD $(git rev-parse --short rebased-feature-branch)] third commit
 140         Author: A U Thor <author@example.com>
 141         Date: Thu Apr 7 15:15:13 2005 -0700
 142         1 file changed, 1 insertion(+)
 143         create mode 100644 file3
 144        Committed: 0002 third commit
 145        All done.
 146        Applying autostash resulted in conflicts.
 147        Your changes are safe in the stash.
 148        You can run "git stash pop" or "git stash drop" at any time.
 149        EOF
 150}
 151
 152testrebase () {
 153        type=$1
 154        dotest=$2
 155
 156        test_expect_success "rebase$type: dirty worktree, --no-autostash" '
 157                test_config rebase.autostash true &&
 158                git reset --hard &&
 159                git checkout -b rebased-feature-branch feature-branch &&
 160                test_when_finished git branch -D rebased-feature-branch &&
 161                test_when_finished git checkout feature-branch &&
 162                echo dirty >>file3 &&
 163                test_must_fail git rebase$type --no-autostash unrelated-onto-branch
 164        '
 165
 166        test_expect_success "rebase$type: dirty worktree, non-conflicting rebase" '
 167                test_config rebase.autostash true &&
 168                git reset --hard &&
 169                git checkout -b rebased-feature-branch feature-branch &&
 170                echo dirty >>file3 &&
 171                git rebase$type unrelated-onto-branch >actual 2>&1 &&
 172                grep unrelated file4 &&
 173                grep dirty file3 &&
 174                git checkout feature-branch
 175        '
 176
 177        test_expect_success "rebase$type --autostash: check output" '
 178                test_when_finished git branch -D rebased-feature-branch &&
 179                suffix=${type#\ --} && suffix=${suffix:-am} &&
 180                create_expected_success_$suffix &&
 181                test_i18ncmp expected actual
 182        '
 183
 184        test_expect_success "rebase$type: dirty index, non-conflicting rebase" '
 185                test_config rebase.autostash true &&
 186                git reset --hard &&
 187                git checkout -b rebased-feature-branch feature-branch &&
 188                test_when_finished git branch -D rebased-feature-branch &&
 189                echo dirty >>file3 &&
 190                git add file3 &&
 191                git rebase$type unrelated-onto-branch &&
 192                grep unrelated file4 &&
 193                grep dirty file3 &&
 194                git checkout feature-branch
 195        '
 196
 197        test_expect_success "rebase$type: conflicting rebase" '
 198                test_config rebase.autostash true &&
 199                git reset --hard &&
 200                git checkout -b rebased-feature-branch feature-branch &&
 201                test_when_finished git branch -D rebased-feature-branch &&
 202                echo dirty >>file3 &&
 203                test_must_fail git rebase$type related-onto-branch &&
 204                test_path_is_file $dotest/autostash &&
 205                ! grep dirty file3 &&
 206                rm -rf $dotest &&
 207                git reset --hard &&
 208                git checkout feature-branch
 209        '
 210
 211        test_expect_success "rebase$type: --continue" '
 212                test_config rebase.autostash true &&
 213                git reset --hard &&
 214                git checkout -b rebased-feature-branch feature-branch &&
 215                test_when_finished git branch -D rebased-feature-branch &&
 216                echo dirty >>file3 &&
 217                test_must_fail git rebase$type related-onto-branch &&
 218                test_path_is_file $dotest/autostash &&
 219                ! grep dirty file3 &&
 220                echo "conflicting-plus-goodbye" >file2 &&
 221                git add file2 &&
 222                git rebase --continue &&
 223                test_path_is_missing $dotest/autostash &&
 224                grep dirty file3 &&
 225                git checkout feature-branch
 226        '
 227
 228        test_expect_success "rebase$type: --skip" '
 229                test_config rebase.autostash true &&
 230                git reset --hard &&
 231                git checkout -b rebased-feature-branch feature-branch &&
 232                test_when_finished git branch -D rebased-feature-branch &&
 233                echo dirty >>file3 &&
 234                test_must_fail git rebase$type related-onto-branch &&
 235                test_path_is_file $dotest/autostash &&
 236                ! grep dirty file3 &&
 237                git rebase --skip &&
 238                test_path_is_missing $dotest/autostash &&
 239                grep dirty file3 &&
 240                git checkout feature-branch
 241        '
 242
 243        test_expect_success "rebase$type: --abort" '
 244                test_config rebase.autostash true &&
 245                git reset --hard &&
 246                git checkout -b rebased-feature-branch feature-branch &&
 247                test_when_finished git branch -D rebased-feature-branch &&
 248                echo dirty >>file3 &&
 249                test_must_fail git rebase$type related-onto-branch &&
 250                test_path_is_file $dotest/autostash &&
 251                ! grep dirty file3 &&
 252                git rebase --abort &&
 253                test_path_is_missing $dotest/autostash &&
 254                grep dirty file3 &&
 255                git checkout feature-branch
 256        '
 257
 258        test_expect_success "rebase$type: non-conflicting rebase, conflicting stash" '
 259                test_config rebase.autostash true &&
 260                git reset --hard &&
 261                git checkout -b rebased-feature-branch feature-branch &&
 262                echo dirty >file4 &&
 263                git add file4 &&
 264                git rebase$type unrelated-onto-branch >actual 2>&1 &&
 265                test_path_is_missing $dotest &&
 266                git reset --hard &&
 267                grep unrelated file4 &&
 268                ! grep dirty file4 &&
 269                git checkout feature-branch &&
 270                git stash pop &&
 271                grep dirty file4
 272        '
 273
 274        test_expect_success "rebase$type: check output with conflicting stash" '
 275                test_when_finished git branch -D rebased-feature-branch &&
 276                suffix=${type#\ --} && suffix=${suffix:-am} &&
 277                create_expected_failure_$suffix &&
 278                test_i18ncmp expected actual
 279        '
 280}
 281
 282test_expect_success "rebase: fast-forward rebase" '
 283        test_config rebase.autostash true &&
 284        git reset --hard &&
 285        git checkout -b behind-feature-branch feature-branch~1 &&
 286        test_when_finished git branch -D behind-feature-branch &&
 287        echo dirty >>file1 &&
 288        git rebase feature-branch &&
 289        grep dirty file1 &&
 290        git checkout feature-branch
 291'
 292
 293test_expect_success "rebase: noop rebase" '
 294        test_config rebase.autostash true &&
 295        git reset --hard &&
 296        git checkout -b same-feature-branch feature-branch &&
 297        test_when_finished git branch -D same-feature-branch &&
 298        echo dirty >>file1 &&
 299        git rebase feature-branch &&
 300        grep dirty file1 &&
 301        git checkout feature-branch
 302'
 303
 304testrebase "" .git/rebase-apply
 305testrebase " --merge" .git/rebase-merge
 306testrebase " --interactive" .git/rebase-merge
 307
 308test_expect_success 'abort rebase -i with --autostash' '
 309        test_when_finished "git reset --hard" &&
 310        echo uncommitted-content >file0 &&
 311        (
 312                write_script abort-editor.sh <<-\EOF &&
 313                        echo >"$1"
 314                EOF
 315                test_set_editor "$(pwd)/abort-editor.sh" &&
 316                test_must_fail git rebase -i --autostash HEAD^ &&
 317                rm -f abort-editor.sh
 318        ) &&
 319        echo uncommitted-content >expected &&
 320        test_cmp expected file0
 321'
 322
 323test_expect_success 'restore autostash on editor failure' '
 324        test_when_finished "git reset --hard" &&
 325        echo uncommitted-content >file0 &&
 326        (
 327                test_set_editor "false" &&
 328                test_must_fail git rebase -i --autostash HEAD^
 329        ) &&
 330        echo uncommitted-content >expected &&
 331        test_cmp expected file0
 332'
 333
 334test_expect_success 'autostash is saved on editor failure with conflict' '
 335        test_when_finished "git reset --hard" &&
 336        echo uncommitted-content >file0 &&
 337        (
 338                write_script abort-editor.sh <<-\EOF &&
 339                        echo conflicting-content >file0
 340                        exit 1
 341                EOF
 342                test_set_editor "$(pwd)/abort-editor.sh" &&
 343                test_must_fail git rebase -i --autostash HEAD^ &&
 344                rm -f abort-editor.sh
 345        ) &&
 346        echo conflicting-content >expected &&
 347        test_cmp expected file0 &&
 348        git checkout file0 &&
 349        git stash pop &&
 350        echo uncommitted-content >expected &&
 351        test_cmp expected file0
 352'
 353
 354test_done