doc: fix reference to --ignore-submodules
[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         remove_progress_re="$(printf "s/.*\\r//")"
35 '
36
37 create_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
48 create_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
57 create_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
70 create_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
81 testrebase () {
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
219 test_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
230 test_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
241 testrebase "" .git/rebase-apply
242 testrebase " --merge" .git/rebase-merge
243 testrebase " --interactive" .git/rebase-merge
244
245 test_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
260 test_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
271 test_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
291 test_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
301 test_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
309 test_done