Git 2.45
[git/gitster.git] / t / t3420-rebase-autostash.sh
blob1a820f148155cbc65e2e1ad07275e25510e083b9
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-lib.sh
12 test_expect_success setup '
13 echo hello-world >file0 &&
14 git add . &&
15 test_tick &&
16 git commit -m "initial commit" &&
17 git checkout -b feature-branch &&
18 echo another-hello >file1 &&
19 echo goodbye >file2 &&
20 git add . &&
21 test_tick &&
22 git commit -m "second commit" &&
23 echo final-goodbye >file3 &&
24 git add . &&
25 test_tick &&
26 git commit -m "third commit" &&
27 git checkout -b unrelated-onto-branch main &&
28 echo unrelated >file4 &&
29 git add . &&
30 test_tick &&
31 git commit -m "unrelated commit" &&
32 git checkout -b related-onto-branch main &&
33 echo conflicting-change >file2 &&
34 git add . &&
35 test_tick &&
36 git commit -m "related commit" &&
37 remove_progress_re="$(printf "s/.*\\r//")"
40 create_expected_success_apply () {
41 cat >expected <<-EOF
42 $(grep "^Created autostash: [0-9a-f][0-9a-f]*\$" actual)
43 First, rewinding head to replay your work on top of it...
44 Applying: second commit
45 Applying: third commit
46 Applied autostash.
47 EOF
50 create_expected_success_merge () {
51 q_to_cr >expected <<-EOF
52 $(grep "^Created autostash: [0-9a-f][0-9a-f]*\$" actual)
53 Applied autostash.
54 Successfully rebased and updated refs/heads/rebased-feature-branch.
55 EOF
58 create_expected_failure_apply () {
59 cat >expected <<-EOF
60 $(grep "^Created autostash: [0-9a-f][0-9a-f]*\$" actual)
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
70 create_expected_failure_merge () {
71 cat >expected <<-EOF
72 $(grep "^Created autostash: [0-9a-f][0-9a-f]*\$" actual)
73 Applying 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
80 testrebase () {
81 type=$1
82 dotest=$2
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
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
105 test_expect_success "rebase$type --autostash: check output" '
106 test_when_finished git branch -D rebased-feature-branch &&
107 suffix=${type#\ --} && suffix=${suffix:-apply} &&
108 if test ${suffix} = "interactive"; then
109 suffix=merge
110 fi &&
111 create_expected_success_$suffix &&
112 sed "$remove_progress_re" <actual >actual2 &&
113 test_cmp expected actual2
116 test_expect_success "rebase$type: dirty index, non-conflicting rebase" '
117 test_config rebase.autostash true &&
118 git reset --hard &&
119 git checkout -b rebased-feature-branch feature-branch &&
120 test_when_finished git branch -D rebased-feature-branch &&
121 echo dirty >>file3 &&
122 git add file3 &&
123 git rebase$type unrelated-onto-branch &&
124 grep unrelated file4 &&
125 grep dirty file3 &&
126 git checkout feature-branch
129 test_expect_success "rebase$type: conflicting rebase" '
130 test_config rebase.autostash true &&
131 git reset --hard &&
132 git checkout -b rebased-feature-branch feature-branch &&
133 test_when_finished git branch -D rebased-feature-branch &&
134 echo dirty >>file3 &&
135 test_must_fail git rebase$type related-onto-branch &&
136 test_path_is_file $dotest/autostash &&
137 test_path_is_missing file3 &&
138 rm -rf $dotest &&
139 git reset --hard &&
140 git checkout feature-branch
143 test_expect_success "rebase$type: --continue" '
144 test_config rebase.autostash true &&
145 git reset --hard &&
146 git checkout -b rebased-feature-branch feature-branch &&
147 test_when_finished git branch -D rebased-feature-branch &&
148 echo dirty >>file3 &&
149 test_must_fail git rebase$type related-onto-branch &&
150 test_path_is_file $dotest/autostash &&
151 test_path_is_missing file3 &&
152 echo "conflicting-plus-goodbye" >file2 &&
153 git add file2 &&
154 git rebase --continue &&
155 test_path_is_missing $dotest/autostash &&
156 grep dirty file3 &&
157 git checkout feature-branch
160 test_expect_success "rebase$type: --skip" '
161 test_config rebase.autostash true &&
162 git reset --hard &&
163 git checkout -b rebased-feature-branch feature-branch &&
164 test_when_finished git branch -D rebased-feature-branch &&
165 echo dirty >>file3 &&
166 test_must_fail git rebase$type related-onto-branch &&
167 test_path_is_file $dotest/autostash &&
168 test_path_is_missing file3 &&
169 git rebase --skip &&
170 test_path_is_missing $dotest/autostash &&
171 grep dirty file3 &&
172 git checkout feature-branch
175 test_expect_success "rebase$type: --abort" '
176 test_config rebase.autostash true &&
177 git reset --hard &&
178 git checkout -b rebased-feature-branch feature-branch &&
179 test_when_finished git branch -D rebased-feature-branch &&
180 echo dirty >>file3 &&
181 test_must_fail git rebase$type related-onto-branch &&
182 test_path_is_file $dotest/autostash &&
183 test_path_is_missing file3 &&
184 git rebase --abort &&
185 test_path_is_missing $dotest/autostash &&
186 grep dirty file3 &&
187 git checkout feature-branch
190 test_expect_success "rebase$type: --quit" '
191 test_config rebase.autostash true &&
192 git reset --hard &&
193 git checkout -b rebased-feature-branch feature-branch &&
194 test_when_finished git branch -D rebased-feature-branch &&
195 echo dirty >>file3 &&
196 git diff >expect &&
197 test_must_fail git rebase$type related-onto-branch &&
198 test_path_is_file $dotest/autostash &&
199 test_path_is_missing file3 &&
200 git rebase --quit &&
201 test_when_finished git stash drop &&
202 test_path_is_missing $dotest/autostash &&
203 ! grep dirty file3 &&
204 git stash show -p >actual &&
205 test_cmp expect actual &&
206 git reset --hard &&
207 git checkout feature-branch
210 test_expect_success "rebase$type: non-conflicting rebase, conflicting stash" '
211 test_config rebase.autostash true &&
212 git reset --hard &&
213 git checkout -b rebased-feature-branch feature-branch &&
214 echo dirty >file4 &&
215 git add file4 &&
216 git rebase$type unrelated-onto-branch >actual 2>&1 &&
217 test_path_is_missing $dotest &&
218 git reset --hard &&
219 grep unrelated file4 &&
220 ! grep dirty file4 &&
221 git checkout feature-branch &&
222 git stash pop &&
223 grep dirty file4
226 test_expect_success "rebase$type: check output with conflicting stash" '
227 test_when_finished git branch -D rebased-feature-branch &&
228 suffix=${type#\ --} && suffix=${suffix:-apply} &&
229 if test ${suffix} = "interactive"; then
230 suffix=merge
231 fi &&
232 create_expected_failure_$suffix &&
233 sed "$remove_progress_re" <actual >actual2 &&
234 test_cmp expected actual2
238 test_expect_success "rebase: fast-forward rebase" '
239 test_config rebase.autostash true &&
240 git reset --hard &&
241 git checkout -b behind-feature-branch feature-branch~1 &&
242 test_when_finished git branch -D behind-feature-branch &&
243 echo dirty >>file1 &&
244 git rebase feature-branch &&
245 grep dirty file1 &&
246 git checkout feature-branch
249 test_expect_success "rebase: noop rebase" '
250 test_config rebase.autostash true &&
251 git reset --hard &&
252 git checkout -b same-feature-branch feature-branch &&
253 test_when_finished git branch -D same-feature-branch &&
254 echo dirty >>file1 &&
255 git rebase feature-branch &&
256 grep dirty file1 &&
257 git checkout feature-branch
260 testrebase " --apply" .git/rebase-apply
261 testrebase " --merge" .git/rebase-merge
262 testrebase " --interactive" .git/rebase-merge
264 test_expect_success 'abort rebase -i with --autostash' '
265 test_when_finished "git reset --hard" &&
266 echo uncommitted-content >file0 &&
268 write_script abort-editor.sh <<-\EOF &&
269 echo >"$1"
271 test_set_editor "$(pwd)/abort-editor.sh" &&
272 test_must_fail git rebase -i --autostash HEAD^ &&
273 rm -f abort-editor.sh
274 ) &&
275 echo uncommitted-content >expected &&
276 test_cmp expected file0
279 test_expect_success 'restore autostash on editor failure' '
280 test_when_finished "git reset --hard" &&
281 echo uncommitted-content >file0 &&
283 test_set_editor "false" &&
284 test_must_fail git rebase -i --autostash HEAD^
285 ) &&
286 echo uncommitted-content >expected &&
287 test_cmp expected file0
290 test_expect_success 'autostash is saved on editor failure with conflict' '
291 test_when_finished "git reset --hard" &&
292 echo uncommitted-content >file0 &&
294 write_script abort-editor.sh <<-\EOF &&
295 echo conflicting-content >file0
296 exit 1
298 test_set_editor "$(pwd)/abort-editor.sh" &&
299 test_must_fail git rebase -i --autostash HEAD^ &&
300 rm -f abort-editor.sh
301 ) &&
302 echo conflicting-content >expected &&
303 test_cmp expected file0 &&
304 git checkout file0 &&
305 git stash pop &&
306 echo uncommitted-content >expected &&
307 test_cmp expected file0
310 test_expect_success 'autostash with dirty submodules' '
311 test_when_finished "git reset --hard && git checkout main" &&
312 git checkout -b with-submodule &&
313 git -c protocol.file.allow=always submodule add ./ sub &&
314 test_tick &&
315 git commit -m add-submodule &&
316 echo changed >sub/file0 &&
317 git rebase -i --autostash HEAD
320 test_expect_success 'branch is left alone when possible' '
321 git checkout -b unchanged-branch &&
322 echo changed >file0 &&
323 git rebase --autostash unchanged-branch &&
324 test changed = "$(cat file0)" &&
325 test unchanged-branch = "$(git rev-parse --abbrev-ref HEAD)"
328 test_expect_success 'never change active branch' '
329 git checkout -b not-the-feature-branch unrelated-onto-branch &&
330 test_when_finished "git reset --hard && git checkout main" &&
331 echo changed >file0 &&
332 git rebase --autostash not-the-feature-branch feature-branch &&
333 test_cmp_rev not-the-feature-branch unrelated-onto-branch
336 test_expect_success 'autostash commit is marked as reachable' '
337 echo changed >file0 &&
338 git rebase --autostash --exec "git prune --expire=now" \
339 feature-branch^ feature-branch &&
340 # git rebase succeeds if the stash cannot be applied so we need to check
341 # the contents of file0
342 echo changed >expect &&
343 test_cmp expect file0
346 test_done