Merge branch 'js/rebase-config-bitfix'
[git] / t / t3420-rebase-autostash.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2013 Ramkumar Ramachandra
4 #
5
6 test_description='git rebase --autostash tests'
7 . ./test-lib.sh
8
9 test_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
36 create_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
47 create_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
56 create_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
69 create_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
80 testrebase () {
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
216 test_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
227 test_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
238 testrebase "" .git/rebase-apply
239 testrebase " --merge" .git/rebase-merge
240 testrebase " --interactive" .git/rebase-merge
241
242 test_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
257 test_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
268 test_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
288 test_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
298 test_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
306 test_done