827ea7f8b4e28e7c7ae886c45883d21f26455226
   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
  91testrebase () {
  92        type=$1
  93        dotest=$2
  94
  95        test_expect_success "rebase$type: dirty worktree, --no-autostash" '
  96                test_config rebase.autostash true &&
  97                git reset --hard &&
  98                git checkout -b rebased-feature-branch feature-branch &&
  99                test_when_finished git branch -D rebased-feature-branch &&
 100                test_when_finished git checkout feature-branch &&
 101                echo dirty >>file3 &&
 102                test_must_fail git rebase$type --no-autostash unrelated-onto-branch
 103        '
 104
 105        test_expect_success "rebase$type: dirty worktree, non-conflicting rebase" '
 106                test_config rebase.autostash true &&
 107                git reset --hard &&
 108                git checkout -b rebased-feature-branch feature-branch &&
 109                echo dirty >>file3 &&
 110                git rebase$type unrelated-onto-branch >actual 2>&1 &&
 111                grep unrelated file4 &&
 112                grep dirty file3 &&
 113                git checkout feature-branch
 114        '
 115
 116        test_expect_success "rebase$type --autostash: check output" '
 117                test_when_finished git branch -D rebased-feature-branch &&
 118                suffix=${type#\ --} && suffix=${suffix:-am} &&
 119                create_expected_success_$suffix &&
 120                test_cmp expected actual
 121        '
 122
 123        test_expect_success "rebase$type: dirty index, non-conflicting rebase" '
 124                test_config rebase.autostash true &&
 125                git reset --hard &&
 126                git checkout -b rebased-feature-branch feature-branch &&
 127                test_when_finished git branch -D rebased-feature-branch &&
 128                echo dirty >>file3 &&
 129                git add file3 &&
 130                git rebase$type unrelated-onto-branch &&
 131                grep unrelated file4 &&
 132                grep dirty file3 &&
 133                git checkout feature-branch
 134        '
 135
 136        test_expect_success "rebase$type: conflicting rebase" '
 137                test_config rebase.autostash true &&
 138                git reset --hard &&
 139                git checkout -b rebased-feature-branch feature-branch &&
 140                test_when_finished git branch -D rebased-feature-branch &&
 141                echo dirty >>file3 &&
 142                test_must_fail git rebase$type related-onto-branch &&
 143                test_path_is_file $dotest/autostash &&
 144                ! grep dirty file3 &&
 145                rm -rf $dotest &&
 146                git reset --hard &&
 147                git checkout feature-branch
 148        '
 149
 150        test_expect_success "rebase$type: --continue" '
 151                test_config rebase.autostash true &&
 152                git reset --hard &&
 153                git checkout -b rebased-feature-branch feature-branch &&
 154                test_when_finished git branch -D rebased-feature-branch &&
 155                echo dirty >>file3 &&
 156                test_must_fail git rebase$type related-onto-branch &&
 157                test_path_is_file $dotest/autostash &&
 158                ! grep dirty file3 &&
 159                echo "conflicting-plus-goodbye" >file2 &&
 160                git add file2 &&
 161                git rebase --continue &&
 162                test_path_is_missing $dotest/autostash &&
 163                grep dirty file3 &&
 164                git checkout feature-branch
 165        '
 166
 167        test_expect_success "rebase$type: --skip" '
 168                test_config rebase.autostash true &&
 169                git reset --hard &&
 170                git checkout -b rebased-feature-branch feature-branch &&
 171                test_when_finished git branch -D rebased-feature-branch &&
 172                echo dirty >>file3 &&
 173                test_must_fail git rebase$type related-onto-branch &&
 174                test_path_is_file $dotest/autostash &&
 175                ! grep dirty file3 &&
 176                git rebase --skip &&
 177                test_path_is_missing $dotest/autostash &&
 178                grep dirty file3 &&
 179                git checkout feature-branch
 180        '
 181
 182        test_expect_success "rebase$type: --abort" '
 183                test_config rebase.autostash true &&
 184                git reset --hard &&
 185                git checkout -b rebased-feature-branch feature-branch &&
 186                test_when_finished git branch -D rebased-feature-branch &&
 187                echo dirty >>file3 &&
 188                test_must_fail git rebase$type related-onto-branch &&
 189                test_path_is_file $dotest/autostash &&
 190                ! grep dirty file3 &&
 191                git rebase --abort &&
 192                test_path_is_missing $dotest/autostash &&
 193                grep dirty file3 &&
 194                git checkout feature-branch
 195        '
 196
 197        test_expect_success "rebase$type: non-conflicting rebase, conflicting stash" '
 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 >file4 &&
 203                git add file4 &&
 204                git rebase$type unrelated-onto-branch &&
 205                test_path_is_missing $dotest &&
 206                git reset --hard &&
 207                grep unrelated file4 &&
 208                ! grep dirty file4 &&
 209                git checkout feature-branch &&
 210                git stash pop &&
 211                grep dirty file4
 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_done