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