t / t3420-rebase-autostash.shon commit Merge branch 'js/mingw-spawn-with-spaces-in-path' into maint (2f72ebf)
   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_failure_am () {
  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        Applying: second commit
  62        Applying: third commit
  63        Applying autostash resulted in conflicts.
  64        Your changes are safe in the stash.
  65        You can run "git stash pop" or "git stash drop" at any time.
  66        EOF
  67}
  68
  69create_expected_failure_interactive () {
  70        q_to_cr >expected <<-EOF
  71        $(grep "^Created autostash: [0-9a-f][0-9a-f]*\$" actual)
  72        HEAD is now at $(git rev-parse --short feature-branch) third commit
  73        Rebasing (1/2)QRebasing (2/2)QApplying autostash resulted in conflicts.
  74        Your changes are safe in the stash.
  75        You can run "git stash pop" or "git stash drop" at any time.
  76        Successfully rebased and updated refs/heads/rebased-feature-branch.
  77        EOF
  78}
  79
  80testrebase () {
  81        type=$1
  82        dotest=$2
  83
  84        test_expect_success "rebase$type: dirty worktree, --no-autostash" '
  85                test_config rebase.autostash true &&
  86                git reset --hard &&
  87                git checkout -b rebased-feature-branch feature-branch &&
  88                test_when_finished git branch -D rebased-feature-branch &&
  89                test_when_finished git checkout feature-branch &&
  90                echo dirty >>file3 &&
  91                test_must_fail git rebase$type --no-autostash unrelated-onto-branch
  92        '
  93
  94        test_expect_success "rebase$type: dirty worktree, non-conflicting rebase" '
  95                test_config rebase.autostash true &&
  96                git reset --hard &&
  97                git checkout -b rebased-feature-branch feature-branch &&
  98                echo dirty >>file3 &&
  99                git rebase$type unrelated-onto-branch >actual 2>&1 &&
 100                grep unrelated file4 &&
 101                grep dirty file3 &&
 102                git checkout feature-branch
 103        '
 104
 105        test_expect_success "rebase$type --autostash: check output" '
 106                test_when_finished git branch -D rebased-feature-branch &&
 107                suffix=${type#\ --} && suffix=${suffix:-am} &&
 108                if test ${suffix} = "merge"; then
 109                        suffix=interactive
 110                fi &&
 111                create_expected_success_$suffix &&
 112                test_i18ncmp expected actual
 113        '
 114
 115        test_expect_success "rebase$type: dirty index, non-conflicting rebase" '
 116                test_config rebase.autostash true &&
 117                git reset --hard &&
 118                git checkout -b rebased-feature-branch feature-branch &&
 119                test_when_finished git branch -D rebased-feature-branch &&
 120                echo dirty >>file3 &&
 121                git add file3 &&
 122                git rebase$type unrelated-onto-branch &&
 123                grep unrelated file4 &&
 124                grep dirty file3 &&
 125                git checkout feature-branch
 126        '
 127
 128        test_expect_success "rebase$type: conflicting rebase" '
 129                test_config rebase.autostash true &&
 130                git reset --hard &&
 131                git checkout -b rebased-feature-branch feature-branch &&
 132                test_when_finished git branch -D rebased-feature-branch &&
 133                echo dirty >>file3 &&
 134                test_must_fail git rebase$type related-onto-branch &&
 135                test_path_is_file $dotest/autostash &&
 136                test_path_is_missing file3 &&
 137                rm -rf $dotest &&
 138                git reset --hard &&
 139                git checkout feature-branch
 140        '
 141
 142        test_expect_success "rebase$type: --continue" '
 143                test_config rebase.autostash true &&
 144                git reset --hard &&
 145                git checkout -b rebased-feature-branch feature-branch &&
 146                test_when_finished git branch -D rebased-feature-branch &&
 147                echo dirty >>file3 &&
 148                test_must_fail git rebase$type related-onto-branch &&
 149                test_path_is_file $dotest/autostash &&
 150                test_path_is_missing file3 &&
 151                echo "conflicting-plus-goodbye" >file2 &&
 152                git add file2 &&
 153                git rebase --continue &&
 154                test_path_is_missing $dotest/autostash &&
 155                grep dirty file3 &&
 156                git checkout feature-branch
 157        '
 158
 159        test_expect_success "rebase$type: --skip" '
 160                test_config rebase.autostash true &&
 161                git reset --hard &&
 162                git checkout -b rebased-feature-branch feature-branch &&
 163                test_when_finished git branch -D rebased-feature-branch &&
 164                echo dirty >>file3 &&
 165                test_must_fail git rebase$type related-onto-branch &&
 166                test_path_is_file $dotest/autostash &&
 167                test_path_is_missing file3 &&
 168                git rebase --skip &&
 169                test_path_is_missing $dotest/autostash &&
 170                grep dirty file3 &&
 171                git checkout feature-branch
 172        '
 173
 174        test_expect_success "rebase$type: --abort" '
 175                test_config rebase.autostash true &&
 176                git reset --hard &&
 177                git checkout -b rebased-feature-branch feature-branch &&
 178                test_when_finished git branch -D rebased-feature-branch &&
 179                echo dirty >>file3 &&
 180                test_must_fail git rebase$type related-onto-branch &&
 181                test_path_is_file $dotest/autostash &&
 182                test_path_is_missing file3 &&
 183                git rebase --abort &&
 184                test_path_is_missing $dotest/autostash &&
 185                grep dirty file3 &&
 186                git checkout feature-branch
 187        '
 188
 189        test_expect_success "rebase$type: non-conflicting rebase, conflicting stash" '
 190                test_config rebase.autostash true &&
 191                git reset --hard &&
 192                git checkout -b rebased-feature-branch feature-branch &&
 193                echo dirty >file4 &&
 194                git add file4 &&
 195                git rebase$type unrelated-onto-branch >actual 2>&1 &&
 196                test_path_is_missing $dotest &&
 197                git reset --hard &&
 198                grep unrelated file4 &&
 199                ! grep dirty file4 &&
 200                git checkout feature-branch &&
 201                git stash pop &&
 202                grep dirty file4
 203        '
 204
 205        test_expect_success "rebase$type: check output with conflicting stash" '
 206                test_when_finished git branch -D rebased-feature-branch &&
 207                suffix=${type#\ --} && suffix=${suffix:-am} &&
 208                if test ${suffix} = "merge"; then
 209                        suffix=interactive
 210                fi &&
 211                create_expected_failure_$suffix &&
 212                test_i18ncmp expected actual
 213        '
 214}
 215
 216test_expect_success "rebase: fast-forward rebase" '
 217        test_config rebase.autostash true &&
 218        git reset --hard &&
 219        git checkout -b behind-feature-branch feature-branch~1 &&
 220        test_when_finished git branch -D behind-feature-branch &&
 221        echo dirty >>file1 &&
 222        git rebase feature-branch &&
 223        grep dirty file1 &&
 224        git checkout feature-branch
 225'
 226
 227test_expect_success "rebase: noop rebase" '
 228        test_config rebase.autostash true &&
 229        git reset --hard &&
 230        git checkout -b same-feature-branch feature-branch &&
 231        test_when_finished git branch -D same-feature-branch &&
 232        echo dirty >>file1 &&
 233        git rebase feature-branch &&
 234        grep dirty file1 &&
 235        git checkout feature-branch
 236'
 237
 238testrebase "" .git/rebase-apply
 239testrebase " --merge" .git/rebase-merge
 240testrebase " --interactive" .git/rebase-merge
 241
 242test_expect_success 'abort rebase -i with --autostash' '
 243        test_when_finished "git reset --hard" &&
 244        echo uncommitted-content >file0 &&
 245        (
 246                write_script abort-editor.sh <<-\EOF &&
 247                        echo >"$1"
 248                EOF
 249                test_set_editor "$(pwd)/abort-editor.sh" &&
 250                test_must_fail git rebase -i --autostash HEAD^ &&
 251                rm -f abort-editor.sh
 252        ) &&
 253        echo uncommitted-content >expected &&
 254        test_cmp expected file0
 255'
 256
 257test_expect_success 'restore autostash on editor failure' '
 258        test_when_finished "git reset --hard" &&
 259        echo uncommitted-content >file0 &&
 260        (
 261                test_set_editor "false" &&
 262                test_must_fail git rebase -i --autostash HEAD^
 263        ) &&
 264        echo uncommitted-content >expected &&
 265        test_cmp expected file0
 266'
 267
 268test_expect_success 'autostash is saved on editor failure with conflict' '
 269        test_when_finished "git reset --hard" &&
 270        echo uncommitted-content >file0 &&
 271        (
 272                write_script abort-editor.sh <<-\EOF &&
 273                        echo conflicting-content >file0
 274                        exit 1
 275                EOF
 276                test_set_editor "$(pwd)/abort-editor.sh" &&
 277                test_must_fail git rebase -i --autostash HEAD^ &&
 278                rm -f abort-editor.sh
 279        ) &&
 280        echo conflicting-content >expected &&
 281        test_cmp expected file0 &&
 282        git checkout file0 &&
 283        git stash pop &&
 284        echo uncommitted-content >expected &&
 285        test_cmp expected file0
 286'
 287
 288test_expect_success 'autostash with dirty submodules' '
 289        test_when_finished "git reset --hard && git checkout master" &&
 290        git checkout -b with-submodule &&
 291        git submodule add ./ sub &&
 292        test_tick &&
 293        git commit -m add-submodule &&
 294        echo changed >sub/file0 &&
 295        git rebase -i --autostash HEAD
 296'
 297
 298test_expect_success 'branch is left alone when possible' '
 299        git checkout -b unchanged-branch &&
 300        echo changed >file0 &&
 301        git rebase --autostash unchanged-branch &&
 302        test changed = "$(cat file0)" &&
 303        test unchanged-branch = "$(git rev-parse --abbrev-ref HEAD)"
 304'
 305
 306test_done