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