0b52a3497eefb29a71748d99d4cc2c6e59477291
1#!/bin/sh
2
3test_description='pulling into void'
4
5. ./test-lib.sh
6
7modify () {
8 sed -e "$1" <"$2" >"$2.x" &&
9 mv "$2.x" "$2"
10}
11
12test_pull_autostash () {
13 git reset --hard before-rebase &&
14 echo dirty >new_file &&
15 git add new_file &&
16 git pull "$@" . copy &&
17 test_cmp_rev HEAD^ copy &&
18 test "$(cat new_file)" = dirty &&
19 test "$(cat file)" = "modified again"
20}
21
22test_expect_success setup '
23 echo file >file &&
24 git add file &&
25 git commit -a -m original
26'
27
28test_expect_success 'pulling into void' '
29 git init cloned &&
30 (
31 cd cloned &&
32 git pull ..
33 ) &&
34 test -f file &&
35 test -f cloned/file &&
36 test_cmp file cloned/file
37'
38
39test_expect_success 'pulling into void using master:master' '
40 git init cloned-uho &&
41 (
42 cd cloned-uho &&
43 git pull .. master:master
44 ) &&
45 test -f file &&
46 test -f cloned-uho/file &&
47 test_cmp file cloned-uho/file
48'
49
50test_expect_success 'pulling into void does not overwrite untracked files' '
51 git init cloned-untracked &&
52 (
53 cd cloned-untracked &&
54 echo untracked >file &&
55 test_must_fail git pull .. master &&
56 echo untracked >expect &&
57 test_cmp expect file
58 )
59'
60
61test_expect_success 'pulling into void does not overwrite staged files' '
62 git init cloned-staged-colliding &&
63 (
64 cd cloned-staged-colliding &&
65 echo "alternate content" >file &&
66 git add file &&
67 test_must_fail git pull .. master &&
68 echo "alternate content" >expect &&
69 test_cmp expect file &&
70 git cat-file blob :file >file.index &&
71 test_cmp expect file.index
72 )
73'
74
75test_expect_success 'pulling into void does not remove new staged files' '
76 git init cloned-staged-new &&
77 (
78 cd cloned-staged-new &&
79 echo "new tracked file" >newfile &&
80 git add newfile &&
81 git pull .. master &&
82 echo "new tracked file" >expect &&
83 test_cmp expect newfile &&
84 git cat-file blob :newfile >newfile.index &&
85 test_cmp expect newfile.index
86 )
87'
88
89test_expect_success 'pulling into void must not create an octopus' '
90 git init cloned-octopus &&
91 (
92 cd cloned-octopus &&
93 test_must_fail git pull .. master master &&
94 ! test -f file
95 )
96'
97
98test_expect_success 'test . as a remote' '
99 git branch copy master &&
100 git config branch.copy.remote . &&
101 git config branch.copy.merge refs/heads/master &&
102 echo updated >file &&
103 git commit -a -m updated &&
104 git checkout copy &&
105 test "$(cat file)" = file &&
106 git pull &&
107 test "$(cat file)" = updated &&
108 git reflog -1 >reflog.actual &&
109 sed "s/^[0-9a-f][0-9a-f]*/OBJID/" reflog.actual >reflog.fuzzy &&
110 echo "OBJID HEAD@{0}: pull: Fast-forward" >reflog.expected &&
111 test_cmp reflog.expected reflog.fuzzy
112'
113
114test_expect_success 'the default remote . should not break explicit pull' '
115 git checkout -b second master^ &&
116 echo modified >file &&
117 git commit -a -m modified &&
118 git checkout copy &&
119 git reset --hard HEAD^ &&
120 test "$(cat file)" = file &&
121 git pull . second &&
122 test "$(cat file)" = modified &&
123 git reflog -1 >reflog.actual &&
124 sed "s/^[0-9a-f][0-9a-f]*/OBJID/" reflog.actual >reflog.fuzzy &&
125 echo "OBJID HEAD@{0}: pull . second: Fast-forward" >reflog.expected &&
126 test_cmp reflog.expected reflog.fuzzy
127'
128
129test_expect_success 'fail if wildcard spec does not match any refs' '
130 git checkout -b test copy^ &&
131 test_when_finished "git checkout -f copy && git branch -D test" &&
132 test "$(cat file)" = file &&
133 test_must_fail git pull . "refs/nonexisting1/*:refs/nonexisting2/*" 2>err &&
134 test_i18ngrep "no candidates for merging" err &&
135 test "$(cat file)" = file
136'
137
138test_expect_success 'fail if no branches specified with non-default remote' '
139 git remote add test_remote . &&
140 test_when_finished "git remote remove test_remote" &&
141 git checkout -b test copy^ &&
142 test_when_finished "git checkout -f copy && git branch -D test" &&
143 test "$(cat file)" = file &&
144 test_config branch.test.remote origin &&
145 test_must_fail git pull test_remote 2>err &&
146 test_i18ngrep "specify a branch on the command line" err &&
147 test "$(cat file)" = file
148'
149
150test_expect_success 'fail if not on a branch' '
151 git remote add origin . &&
152 test_when_finished "git remote remove origin" &&
153 git checkout HEAD^ &&
154 test_when_finished "git checkout -f copy" &&
155 test "$(cat file)" = file &&
156 test_must_fail git pull 2>err &&
157 test_i18ngrep "not currently on a branch" err &&
158 test "$(cat file)" = file
159'
160
161test_expect_success 'fail if no configuration for current branch' '
162 git remote add test_remote . &&
163 test_when_finished "git remote remove test_remote" &&
164 git checkout -b test copy^ &&
165 test_when_finished "git checkout -f copy && git branch -D test" &&
166 test_config branch.test.remote test_remote &&
167 test "$(cat file)" = file &&
168 test_must_fail git pull 2>err &&
169 test_i18ngrep "no tracking information" err &&
170 test "$(cat file)" = file
171'
172
173test_expect_success 'pull --all: fail if no configuration for current branch' '
174 git remote add test_remote . &&
175 test_when_finished "git remote remove test_remote" &&
176 git checkout -b test copy^ &&
177 test_when_finished "git checkout -f copy && git branch -D test" &&
178 test_config branch.test.remote test_remote &&
179 test "$(cat file)" = file &&
180 test_must_fail git pull --all 2>err &&
181 test_i18ngrep "There is no tracking information" err &&
182 test "$(cat file)" = file
183'
184
185test_expect_success 'fail if upstream branch does not exist' '
186 git checkout -b test copy^ &&
187 test_when_finished "git checkout -f copy && git branch -D test" &&
188 test_config branch.test.remote . &&
189 test_config branch.test.merge refs/heads/nonexisting &&
190 test "$(cat file)" = file &&
191 test_must_fail git pull 2>err &&
192 test_i18ngrep "no such ref was fetched" err &&
193 test "$(cat file)" = file
194'
195
196test_expect_success 'fail if the index has unresolved entries' '
197 git checkout -b third second^ &&
198 test_when_finished "git checkout -f copy && git branch -D third" &&
199 test "$(cat file)" = file &&
200 test_commit modified2 file &&
201 test -z "$(git ls-files -u)" &&
202 test_must_fail git pull . second &&
203 test -n "$(git ls-files -u)" &&
204 cp file expected &&
205 test_must_fail git pull . second 2>err &&
206 test_i18ngrep "Pull is not possible because you have unmerged files" err &&
207 test_cmp expected file &&
208 git add file &&
209 test -z "$(git ls-files -u)" &&
210 test_must_fail git pull . second 2>err &&
211 test_i18ngrep "You have not concluded your merge" err &&
212 test_cmp expected file
213'
214
215test_expect_success 'fast-forwards working tree if branch head is updated' '
216 git checkout -b third second^ &&
217 test_when_finished "git checkout -f copy && git branch -D third" &&
218 test "$(cat file)" = file &&
219 git pull . second:third 2>err &&
220 test_i18ngrep "fetch updated the current branch head" err &&
221 test "$(cat file)" = modified &&
222 test "$(git rev-parse third)" = "$(git rev-parse second)"
223'
224
225test_expect_success 'fast-forward fails with conflicting work tree' '
226 git checkout -b third second^ &&
227 test_when_finished "git checkout -f copy && git branch -D third" &&
228 test "$(cat file)" = file &&
229 echo conflict >file &&
230 test_must_fail git pull . second:third 2>err &&
231 test_i18ngrep "Cannot fast-forward your working tree" err &&
232 test "$(cat file)" = conflict &&
233 test "$(git rev-parse third)" = "$(git rev-parse second)"
234'
235
236test_expect_success '--rebase' '
237 git branch to-rebase &&
238 echo modified again > file &&
239 git commit -m file file &&
240 git checkout to-rebase &&
241 echo new > file2 &&
242 git add file2 &&
243 git commit -m "new file" &&
244 git tag before-rebase &&
245 git pull --rebase . copy &&
246 test "$(git rev-parse HEAD^)" = "$(git rev-parse copy)" &&
247 test new = "$(git show HEAD:file2)"
248'
249
250test_expect_success '--rebase fails with multiple branches' '
251 git reset --hard before-rebase &&
252 test_must_fail git pull --rebase . copy master 2>err &&
253 test "$(git rev-parse HEAD)" = "$(git rev-parse before-rebase)" &&
254 test_i18ngrep "Cannot rebase onto multiple branches" err &&
255 test modified = "$(git show HEAD:file)"
256'
257
258test_expect_success 'pull --rebase succeeds with dirty working directory and rebase.autostash set' '
259 test_config rebase.autostash true &&
260 test_pull_autostash --rebase
261'
262
263test_expect_success 'pull --rebase --autostash & rebase.autostash=true' '
264 test_config rebase.autostash true &&
265 test_pull_autostash --rebase --autostash
266'
267
268test_expect_success 'pull --rebase --autostash & rebase.autostash=false' '
269 test_config rebase.autostash false &&
270 test_pull_autostash --rebase --autostash
271'
272
273test_expect_success 'pull --rebase --autostash & rebase.autostash unset' '
274 test_unconfig rebase.autostash &&
275 test_pull_autostash --rebase --autostash
276'
277
278test_expect_success 'pull --rebase --no-autostash & rebase.autostash=true' '
279 test_config rebase.autostash true &&
280 git reset --hard before-rebase &&
281 echo dirty >new_file &&
282 git add new_file &&
283 test_must_fail git pull --rebase --no-autostash . copy 2>err &&
284 test_i18ngrep "Cannot pull with rebase: Your index contains uncommitted changes." err
285'
286
287test_expect_success 'pull --rebase --no-autostash & rebase.autostash=false' '
288 test_config rebase.autostash false &&
289 git reset --hard before-rebase &&
290 echo dirty >new_file &&
291 git add new_file &&
292 test_must_fail git pull --rebase --no-autostash . copy 2>err &&
293 test_i18ngrep "Cannot pull with rebase: Your index contains uncommitted changes." err
294'
295
296test_expect_success 'pull --rebase --no-autostash & rebase.autostash unset' '
297 test_unconfig rebase.autostash &&
298 git reset --hard before-rebase &&
299 echo dirty >new_file &&
300 git add new_file &&
301 test_must_fail git pull --rebase --no-autostash . copy 2>err &&
302 test_i18ngrep "Cannot pull with rebase: Your index contains uncommitted changes." err
303'
304
305test_expect_success 'pull --autostash (without --rebase) should error out' '
306 test_must_fail git pull --autostash . copy 2>err &&
307 test_i18ngrep "only valid with --rebase" err
308'
309
310test_expect_success 'pull --no-autostash (without --rebase) should error out' '
311 test_must_fail git pull --no-autostash . copy 2>err &&
312 test_i18ngrep "only valid with --rebase" err
313'
314
315test_expect_success 'pull.rebase' '
316 git reset --hard before-rebase &&
317 test_config pull.rebase true &&
318 git pull . copy &&
319 test "$(git rev-parse HEAD^)" = "$(git rev-parse copy)" &&
320 test new = "$(git show HEAD:file2)"
321'
322
323test_expect_success 'branch.to-rebase.rebase' '
324 git reset --hard before-rebase &&
325 test_config branch.to-rebase.rebase true &&
326 git pull . copy &&
327 test "$(git rev-parse HEAD^)" = "$(git rev-parse copy)" &&
328 test new = "$(git show HEAD:file2)"
329'
330
331test_expect_success 'branch.to-rebase.rebase should override pull.rebase' '
332 git reset --hard before-rebase &&
333 test_config pull.rebase true &&
334 test_config branch.to-rebase.rebase false &&
335 git pull . copy &&
336 test "$(git rev-parse HEAD^)" != "$(git rev-parse copy)" &&
337 test new = "$(git show HEAD:file2)"
338'
339
340# add a feature branch, keep-merge, that is merged into master, so the
341# test can try preserving the merge commit (or not) with various
342# --rebase flags/pull.rebase settings.
343test_expect_success 'preserve merge setup' '
344 git reset --hard before-rebase &&
345 git checkout -b keep-merge second^ &&
346 test_commit file3 &&
347 git checkout to-rebase &&
348 git merge keep-merge &&
349 git tag before-preserve-rebase
350'
351
352test_expect_success 'pull.rebase=false create a new merge commit' '
353 git reset --hard before-preserve-rebase &&
354 test_config pull.rebase false &&
355 git pull . copy &&
356 test "$(git rev-parse HEAD^1)" = "$(git rev-parse before-preserve-rebase)" &&
357 test "$(git rev-parse HEAD^2)" = "$(git rev-parse copy)" &&
358 test file3 = "$(git show HEAD:file3.t)"
359'
360
361test_expect_success 'pull.rebase=true flattens keep-merge' '
362 git reset --hard before-preserve-rebase &&
363 test_config pull.rebase true &&
364 git pull . copy &&
365 test "$(git rev-parse HEAD^^)" = "$(git rev-parse copy)" &&
366 test file3 = "$(git show HEAD:file3.t)"
367'
368
369test_expect_success 'pull.rebase=1 is treated as true and flattens keep-merge' '
370 git reset --hard before-preserve-rebase &&
371 test_config pull.rebase 1 &&
372 git pull . copy &&
373 test "$(git rev-parse HEAD^^)" = "$(git rev-parse copy)" &&
374 test file3 = "$(git show HEAD:file3.t)"
375'
376
377test_expect_success 'pull.rebase=preserve rebases and merges keep-merge' '
378 git reset --hard before-preserve-rebase &&
379 test_config pull.rebase preserve &&
380 git pull . copy &&
381 test "$(git rev-parse HEAD^^)" = "$(git rev-parse copy)" &&
382 test "$(git rev-parse HEAD^2)" = "$(git rev-parse keep-merge)"
383'
384
385test_expect_success 'pull.rebase=interactive' '
386 write_script "$TRASH_DIRECTORY/fake-editor" <<-\EOF &&
387 echo I was here >fake.out &&
388 false
389 EOF
390 test_set_editor "$TRASH_DIRECTORY/fake-editor" &&
391 test_must_fail git pull --rebase=interactive . copy &&
392 test "I was here" = "$(cat fake.out)"
393'
394
395test_expect_success 'pull.rebase=invalid fails' '
396 git reset --hard before-preserve-rebase &&
397 test_config pull.rebase invalid &&
398 ! git pull . copy
399'
400
401test_expect_success '--rebase=false create a new merge commit' '
402 git reset --hard before-preserve-rebase &&
403 test_config pull.rebase true &&
404 git pull --rebase=false . copy &&
405 test "$(git rev-parse HEAD^1)" = "$(git rev-parse before-preserve-rebase)" &&
406 test "$(git rev-parse HEAD^2)" = "$(git rev-parse copy)" &&
407 test file3 = "$(git show HEAD:file3.t)"
408'
409
410test_expect_success '--rebase=true rebases and flattens keep-merge' '
411 git reset --hard before-preserve-rebase &&
412 test_config pull.rebase preserve &&
413 git pull --rebase=true . copy &&
414 test "$(git rev-parse HEAD^^)" = "$(git rev-parse copy)" &&
415 test file3 = "$(git show HEAD:file3.t)"
416'
417
418test_expect_success '--rebase=preserve rebases and merges keep-merge' '
419 git reset --hard before-preserve-rebase &&
420 test_config pull.rebase true &&
421 git pull --rebase=preserve . copy &&
422 test "$(git rev-parse HEAD^^)" = "$(git rev-parse copy)" &&
423 test "$(git rev-parse HEAD^2)" = "$(git rev-parse keep-merge)"
424'
425
426test_expect_success '--rebase=invalid fails' '
427 git reset --hard before-preserve-rebase &&
428 ! git pull --rebase=invalid . copy
429'
430
431test_expect_success '--rebase overrides pull.rebase=preserve and flattens keep-merge' '
432 git reset --hard before-preserve-rebase &&
433 test_config pull.rebase preserve &&
434 git pull --rebase . copy &&
435 test "$(git rev-parse HEAD^^)" = "$(git rev-parse copy)" &&
436 test file3 = "$(git show HEAD:file3.t)"
437'
438
439test_expect_success '--rebase with rebased upstream' '
440
441 git remote add -f me . &&
442 git checkout copy &&
443 git tag copy-orig &&
444 git reset --hard HEAD^ &&
445 echo conflicting modification > file &&
446 git commit -m conflict file &&
447 git checkout to-rebase &&
448 echo file > file2 &&
449 git commit -m to-rebase file2 &&
450 git tag to-rebase-orig &&
451 git pull --rebase me copy &&
452 test "conflicting modification" = "$(cat file)" &&
453 test file = "$(cat file2)"
454
455'
456
457test_expect_success '--rebase -f with rebased upstream' '
458 test_when_finished "test_might_fail git rebase --abort" &&
459 git reset --hard to-rebase-orig &&
460 git pull --rebase -f me copy &&
461 test "conflicting modification" = "$(cat file)" &&
462 test file = "$(cat file2)"
463'
464
465test_expect_success '--rebase with rebased default upstream' '
466
467 git update-ref refs/remotes/me/copy copy-orig &&
468 git checkout --track -b to-rebase2 me/copy &&
469 git reset --hard to-rebase-orig &&
470 git pull --rebase &&
471 test "conflicting modification" = "$(cat file)" &&
472 test file = "$(cat file2)"
473
474'
475
476test_expect_success 'rebased upstream + fetch + pull --rebase' '
477
478 git update-ref refs/remotes/me/copy copy-orig &&
479 git reset --hard to-rebase-orig &&
480 git checkout --track -b to-rebase3 me/copy &&
481 git reset --hard to-rebase-orig &&
482 git fetch &&
483 git pull --rebase &&
484 test "conflicting modification" = "$(cat file)" &&
485 test file = "$(cat file2)"
486
487'
488
489test_expect_success 'pull --rebase dies early with dirty working directory' '
490
491 git checkout to-rebase &&
492 git update-ref refs/remotes/me/copy copy^ &&
493 COPY="$(git rev-parse --verify me/copy)" &&
494 git rebase --onto $COPY copy &&
495 test_config branch.to-rebase.remote me &&
496 test_config branch.to-rebase.merge refs/heads/copy &&
497 test_config branch.to-rebase.rebase true &&
498 echo dirty >> file &&
499 git add file &&
500 test_must_fail git pull &&
501 test "$COPY" = "$(git rev-parse --verify me/copy)" &&
502 git checkout HEAD -- file &&
503 git pull &&
504 test "$COPY" != "$(git rev-parse --verify me/copy)"
505
506'
507
508test_expect_success 'pull --rebase works on branch yet to be born' '
509 git rev-parse master >expect &&
510 mkdir empty_repo &&
511 (cd empty_repo &&
512 git init &&
513 git pull --rebase .. master &&
514 git rev-parse HEAD >../actual
515 ) &&
516 test_cmp expect actual
517'
518
519test_expect_success 'pull --rebase fails on unborn branch with staged changes' '
520 test_when_finished "rm -rf empty_repo2" &&
521 git init empty_repo2 &&
522 (
523 cd empty_repo2 &&
524 echo staged-file >staged-file &&
525 git add staged-file &&
526 test "$(git ls-files)" = staged-file &&
527 test_must_fail git pull --rebase .. master 2>err &&
528 test "$(git ls-files)" = staged-file &&
529 test "$(git show :staged-file)" = staged-file &&
530 test_i18ngrep "unborn branch with changes added to the index" err
531 )
532'
533
534test_expect_success 'setup for detecting upstreamed changes' '
535 mkdir src &&
536 (cd src &&
537 git init &&
538 printf "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n" > stuff &&
539 git add stuff &&
540 git commit -m "Initial revision"
541 ) &&
542 git clone src dst &&
543 (cd src &&
544 modify s/5/43/ stuff &&
545 git commit -a -m "5->43" &&
546 modify s/6/42/ stuff &&
547 git commit -a -m "Make it bigger"
548 ) &&
549 (cd dst &&
550 modify s/5/43/ stuff &&
551 git commit -a -m "Independent discovery of 5->43"
552 )
553'
554
555test_expect_success 'git pull --rebase detects upstreamed changes' '
556 (cd dst &&
557 git pull --rebase &&
558 test -z "$(git ls-files -u)"
559 )
560'
561
562test_expect_success 'setup for avoiding reapplying old patches' '
563 (cd dst &&
564 test_might_fail git rebase --abort &&
565 git reset --hard origin/master
566 ) &&
567 git clone --bare src src-replace.git &&
568 rm -rf src &&
569 mv src-replace.git src &&
570 (cd dst &&
571 modify s/2/22/ stuff &&
572 git commit -a -m "Change 2" &&
573 modify s/3/33/ stuff &&
574 git commit -a -m "Change 3" &&
575 modify s/4/44/ stuff &&
576 git commit -a -m "Change 4" &&
577 git push &&
578
579 modify s/44/55/ stuff &&
580 git commit --amend -a -m "Modified Change 4"
581 )
582'
583
584test_expect_success 'git pull --rebase does not reapply old patches' '
585 (cd dst &&
586 test_must_fail git pull --rebase &&
587 test 1 = $(find .git/rebase-apply -name "000*" | wc -l)
588 )
589'
590
591test_expect_success 'git pull --rebase against local branch' '
592 git checkout -b copy2 to-rebase-orig &&
593 git pull --rebase . to-rebase &&
594 test "conflicting modification" = "$(cat file)" &&
595 test file = "$(cat file2)"
596'
597
598test_done