Merge branch 'jc/ci-upload-artifact-and-linux32'
[git/gitster.git] / t / t3420-rebase-autostash.sh
blob63e400b89f225a48db6552540195d472a142547e
1 #!/bin/sh
3 # Copyright (c) 2013 Ramkumar Ramachandra
6 test_description='git rebase --autostash tests'
7 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
8 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
10 TEST_PASSES_SANITIZE_LEAK=true
11 . ./test-lib.sh
13 test_expect_success setup '
14 echo hello-world >file0 &&
15 git add . &&
16 test_tick &&
17 git commit -m "initial commit" &&
18 git checkout -b feature-branch &&
19 echo another-hello >file1 &&
20 echo goodbye >file2 &&
21 git add . &&
22 test_tick &&
23 git commit -m "second commit" &&
24 echo final-goodbye >file3 &&
25 git add . &&
26 test_tick &&
27 git commit -m "third commit" &&
28 git checkout -b unrelated-onto-branch main &&
29 echo unrelated >file4 &&
30 git add . &&
31 test_tick &&
32 git commit -m "unrelated commit" &&
33 git checkout -b related-onto-branch main &&
34 echo conflicting-change >file2 &&
35 git add . &&
36 test_tick &&
37 git commit -m "related commit" &&
38 remove_progress_re="$(printf "s/.*\\r//")"
41 create_expected_success_apply () {
42 cat >expected <<-EOF
43 $(grep "^Created autostash: [0-9a-f][0-9a-f]*\$" actual)
44 First, rewinding head to replay your work on top of it...
45 Applying: second commit
46 Applying: third commit
47 Applied autostash.
48 EOF
51 create_expected_success_merge () {
52 q_to_cr >expected <<-EOF
53 $(grep "^Created autostash: [0-9a-f][0-9a-f]*\$" actual)
54 Applied autostash.
55 Successfully rebased and updated refs/heads/rebased-feature-branch.
56 EOF
59 create_expected_failure_apply () {
60 cat >expected <<-EOF
61 $(grep "^Created autostash: [0-9a-f][0-9a-f]*\$" actual)
62 First, rewinding head to replay your work on top of it...
63 Applying: second commit
64 Applying: third commit
65 Applying autostash resulted in conflicts.
66 Your changes are safe in the stash.
67 You can run "git stash pop" or "git stash drop" at any time.
68 EOF
71 create_expected_failure_merge () {
72 cat >expected <<-EOF
73 $(grep "^Created autostash: [0-9a-f][0-9a-f]*\$" actual)
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
81 testrebase () {
82 type=$1
83 dotest=$2
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
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
106 test_expect_success "rebase$type --autostash: check output" '
107 test_when_finished git branch -D rebased-feature-branch &&
108 suffix=${type#\ --} && suffix=${suffix:-apply} &&
109 if test ${suffix} = "interactive"; then
110 suffix=merge
111 fi &&
112 create_expected_success_$suffix &&
113 sed "$remove_progress_re" <actual >actual2 &&
114 test_cmp expected actual2
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
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
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
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
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
191 test_expect_success "rebase$type: --quit" '
192 test_config rebase.autostash true &&
193 git reset --hard &&
194 git checkout -b rebased-feature-branch feature-branch &&
195 test_when_finished git branch -D rebased-feature-branch &&
196 echo dirty >>file3 &&
197 git diff >expect &&
198 test_must_fail git rebase$type related-onto-branch &&
199 test_path_is_file $dotest/autostash &&
200 test_path_is_missing file3 &&
201 git rebase --quit &&
202 test_when_finished git stash drop &&
203 test_path_is_missing $dotest/autostash &&
204 ! grep dirty file3 &&
205 git stash show -p >actual &&
206 test_cmp expect actual &&
207 git reset --hard &&
208 git checkout feature-branch
211 test_expect_success "rebase$type: non-conflicting rebase, conflicting stash" '
212 test_config rebase.autostash true &&
213 git reset --hard &&
214 git checkout -b rebased-feature-branch feature-branch &&
215 echo dirty >file4 &&
216 git add file4 &&
217 git rebase$type unrelated-onto-branch >actual 2>&1 &&
218 test_path_is_missing $dotest &&
219 git reset --hard &&
220 grep unrelated file4 &&
221 ! grep dirty file4 &&
222 git checkout feature-branch &&
223 git stash pop &&
224 grep dirty file4
227 test_expect_success "rebase$type: check output with conflicting stash" '
228 test_when_finished git branch -D rebased-feature-branch &&
229 suffix=${type#\ --} && suffix=${suffix:-apply} &&
230 if test ${suffix} = "interactive"; then
231 suffix=merge
232 fi &&
233 create_expected_failure_$suffix &&
234 sed "$remove_progress_re" <actual >actual2 &&
235 test_cmp expected actual2
239 test_expect_success "rebase: fast-forward rebase" '
240 test_config rebase.autostash true &&
241 git reset --hard &&
242 git checkout -b behind-feature-branch feature-branch~1 &&
243 test_when_finished git branch -D behind-feature-branch &&
244 echo dirty >>file1 &&
245 git rebase feature-branch &&
246 grep dirty file1 &&
247 git checkout feature-branch
250 test_expect_success "rebase: noop rebase" '
251 test_config rebase.autostash true &&
252 git reset --hard &&
253 git checkout -b same-feature-branch feature-branch &&
254 test_when_finished git branch -D same-feature-branch &&
255 echo dirty >>file1 &&
256 git rebase feature-branch &&
257 grep dirty file1 &&
258 git checkout feature-branch
261 testrebase " --apply" .git/rebase-apply
262 testrebase " --merge" .git/rebase-merge
263 testrebase " --interactive" .git/rebase-merge
265 test_expect_success 'abort rebase -i with --autostash' '
266 test_when_finished "git reset --hard" &&
267 echo uncommitted-content >file0 &&
269 write_script abort-editor.sh <<-\EOF &&
270 echo >"$1"
272 test_set_editor "$(pwd)/abort-editor.sh" &&
273 test_must_fail git rebase -i --autostash HEAD^ &&
274 rm -f abort-editor.sh
275 ) &&
276 echo uncommitted-content >expected &&
277 test_cmp expected file0
280 test_expect_success 'restore autostash on editor failure' '
281 test_when_finished "git reset --hard" &&
282 echo uncommitted-content >file0 &&
284 test_set_editor "false" &&
285 test_must_fail git rebase -i --autostash HEAD^
286 ) &&
287 echo uncommitted-content >expected &&
288 test_cmp expected file0
291 test_expect_success 'autostash is saved on editor failure with conflict' '
292 test_when_finished "git reset --hard" &&
293 echo uncommitted-content >file0 &&
295 write_script abort-editor.sh <<-\EOF &&
296 echo conflicting-content >file0
297 exit 1
299 test_set_editor "$(pwd)/abort-editor.sh" &&
300 test_must_fail git rebase -i --autostash HEAD^ &&
301 rm -f abort-editor.sh
302 ) &&
303 echo conflicting-content >expected &&
304 test_cmp expected file0 &&
305 git checkout file0 &&
306 git stash pop &&
307 echo uncommitted-content >expected &&
308 test_cmp expected file0
311 test_expect_success 'autostash with dirty submodules' '
312 test_when_finished "git reset --hard && git checkout main" &&
313 git checkout -b with-submodule &&
314 git -c protocol.file.allow=always submodule add ./ sub &&
315 test_tick &&
316 git commit -m add-submodule &&
317 echo changed >sub/file0 &&
318 git rebase -i --autostash HEAD
321 test_expect_success 'branch is left alone when possible' '
322 git checkout -b unchanged-branch &&
323 echo changed >file0 &&
324 git rebase --autostash unchanged-branch &&
325 test changed = "$(cat file0)" &&
326 test unchanged-branch = "$(git rev-parse --abbrev-ref HEAD)"
329 test_expect_success 'never change active branch' '
330 git checkout -b not-the-feature-branch unrelated-onto-branch &&
331 test_when_finished "git reset --hard && git checkout main" &&
332 echo changed >file0 &&
333 git rebase --autostash not-the-feature-branch feature-branch &&
334 test_cmp_rev not-the-feature-branch unrelated-onto-branch
337 test_expect_success 'autostash commit is marked as reachable' '
338 echo changed >file0 &&
339 git rebase --autostash --exec "git prune --expire=now" \
340 feature-branch^ feature-branch &&
341 # git rebase succeeds if the stash cannot be applied so we need to check
342 # the contents of file0
343 echo changed >expect &&
344 test_cmp expect file0
347 test_done