Raw
1 #!/bin/sh
2
3 test_description='remote tracking stats'
4
5 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
6 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
7
8 . ./test-lib.sh
9
10 advance () {
11 echo "$1" >"$1" &&
12 git add "$1" &&
13 test_tick &&
14 git commit -m "$1"
15 }
16
17 test_expect_success setup '
18 advance a &&
19 advance b &&
20 advance c &&
21 git clone . test &&
22 (
23 cd test &&
24 git checkout -b b1 origin &&
25 git reset --hard HEAD^ &&
26 advance d &&
27 git checkout -b b2 origin &&
28 git reset --hard b1 &&
29 git checkout -b b3 origin &&
30 git reset --hard HEAD^ &&
31 git checkout -b b4 origin &&
32 advance e &&
33 advance f &&
34 git checkout -b brokenbase origin &&
35 git checkout -b b5 --track brokenbase &&
36 advance g &&
37 git branch -d brokenbase &&
38 git checkout -b b6 origin
39 ) &&
40 git checkout -b follower --track main &&
41 advance h
42 '
43
44 t6040_script='s/^..\(b.\) *[0-9a-f]* \(.*\)$/\1 \2/p'
45 cat >expect <<\EOF
46 b1 [ahead 1, behind 1] d
47 b2 [ahead 1, behind 1] d
48 b3 [behind 1] b
49 b4 [ahead 2] f
50 b5 [gone] g
51 b6 c
52 EOF
53
54 test_expect_success 'branch -v' '
55 (
56 cd test &&
57 git branch -v
58 ) |
59 sed -n -e "$t6040_script" >actual &&
60 test_cmp expect actual
61 '
62
63 cat >expect <<\EOF
64 b1 [origin/main: ahead 1, behind 1] d
65 b2 [origin/main: ahead 1, behind 1] d
66 b3 [origin/main: behind 1] b
67 b4 [origin/main: ahead 2] f
68 b5 [brokenbase: gone] g
69 b6 [origin/main] c
70 EOF
71
72 test_expect_success 'branch -vv' '
73 (
74 cd test &&
75 git branch -vv
76 ) |
77 sed -n -e "$t6040_script" >actual &&
78 test_cmp expect actual
79 '
80
81 test_expect_success 'checkout (diverged from upstream)' '
82 (
83 cd test && git checkout b1
84 ) >actual &&
85 test_grep "have 1 and 1 different" actual
86 '
87
88 test_expect_success 'checkout with local tracked branch' '
89 git checkout main &&
90 git checkout follower >actual &&
91 test_grep "is ahead of" actual
92 '
93
94 test_expect_success 'checkout (upstream is gone)' '
95 (
96 cd test &&
97 git checkout b5
98 ) >actual &&
99 test_grep "is based on .*, but the upstream is gone." actual
100 '
101
102 test_expect_success 'checkout (up-to-date with upstream)' '
103 (
104 cd test && git checkout b6
105 ) >actual &&
106 test_grep "Your branch is up to date with .origin/main" actual
107 '
108
109 test_expect_success 'status (diverged from upstream)' '
110 (
111 cd test &&
112 git checkout b1 >/dev/null &&
113 # reports nothing to commit
114 test_must_fail git commit --dry-run
115 ) >actual &&
116 test_grep "have 1 and 1 different" actual
117 '
118
119 test_expect_success 'status (upstream is gone)' '
120 (
121 cd test &&
122 git checkout b5 >/dev/null &&
123 # reports nothing to commit
124 test_must_fail git commit --dry-run
125 ) >actual &&
126 test_grep "is based on .*, but the upstream is gone." actual
127 '
128
129 test_expect_success 'status (up-to-date with upstream)' '
130 (
131 cd test &&
132 git checkout b6 >/dev/null &&
133 # reports nothing to commit
134 test_must_fail git commit --dry-run
135 ) >actual &&
136 test_grep "Your branch is up to date with .origin/main" actual
137 '
138
139 cat >expect <<\EOF
140 ## b1...origin/main [ahead 1, behind 1]
141 EOF
142
143 test_expect_success 'status -s -b (diverged from upstream)' '
144 (
145 cd test &&
146 git checkout b1 >/dev/null &&
147 git status -s -b | head -1
148 ) >actual &&
149 test_cmp expect actual
150 '
151
152 cat >expect <<\EOF
153 ## b1...origin/main [different]
154 EOF
155
156 test_expect_success 'status -s -b --no-ahead-behind (diverged from upstream)' '
157 (
158 cd test &&
159 git checkout b1 >/dev/null &&
160 git status -s -b --no-ahead-behind | head -1
161 ) >actual &&
162 test_cmp expect actual
163 '
164
165 cat >expect <<\EOF
166 ## b1...origin/main [different]
167 EOF
168
169 test_expect_success 'status.aheadbehind=false status -s -b (diverged from upstream)' '
170 (
171 cd test &&
172 git checkout b1 >/dev/null &&
173 git -c status.aheadbehind=false status -s -b | head -1
174 ) >actual &&
175 test_cmp expect actual
176 '
177
178 cat >expect <<\EOF
179 On branch b1
180 Your branch and 'origin/main' have diverged,
181 and have 1 and 1 different commits each, respectively.
182 EOF
183
184 test_expect_success 'status --long --branch' '
185 (
186 cd test &&
187 git checkout b1 >/dev/null &&
188 git status --long -b | head -3
189 ) >actual &&
190 test_cmp expect actual
191 '
192
193 test_expect_success 'status --long --branch' '
194 (
195 cd test &&
196 git checkout b1 >/dev/null &&
197 git -c status.aheadbehind=true status --long -b | head -3
198 ) >actual &&
199 test_cmp expect actual
200 '
201
202 cat >expect <<\EOF
203 On branch b1
204 Your branch and 'origin/main' refer to different commits.
205 EOF
206
207 test_expect_success 'status --long --branch --no-ahead-behind' '
208 (
209 cd test &&
210 git checkout b1 >/dev/null &&
211 git status --long -b --no-ahead-behind | head -2
212 ) >actual &&
213 test_cmp expect actual
214 '
215
216 test_expect_success 'status.aheadbehind=false status --long --branch' '
217 (
218 cd test &&
219 git checkout b1 >/dev/null &&
220 git -c status.aheadbehind=false status --long -b | head -2
221 ) >actual &&
222 test_cmp expect actual
223 '
224
225 cat >expect <<\EOF
226 ## b5...brokenbase [gone]
227 EOF
228
229 test_expect_success 'status -s -b (upstream is gone)' '
230 (
231 cd test &&
232 git checkout b5 >/dev/null &&
233 git status -s -b | head -1
234 ) >actual &&
235 test_cmp expect actual
236 '
237
238 cat >expect <<\EOF
239 ## b6...origin/main
240 EOF
241
242 test_expect_success 'status -s -b (up-to-date with upstream)' '
243 (
244 cd test &&
245 git checkout b6 >/dev/null &&
246 git status -s -b | head -1
247 ) >actual &&
248 test_cmp expect actual
249 '
250
251 test_expect_success 'fail to track lightweight tags' '
252 git checkout main &&
253 git tag light &&
254 test_must_fail git branch --track lighttrack light >actual &&
255 test_grep ! "set up to track" actual &&
256 test_must_fail git checkout lighttrack
257 '
258
259 test_expect_success 'fail to track annotated tags' '
260 git checkout main &&
261 git tag -m heavy heavy &&
262 test_must_fail git branch --track heavytrack heavy >actual &&
263 test_grep ! "set up to track" actual &&
264 test_must_fail git checkout heavytrack
265 '
266
267 test_expect_success '--set-upstream-to does not change branch' '
268 git branch from-main main &&
269 git branch --set-upstream-to main from-main &&
270 git branch from-topic_2 main &&
271 test_must_fail git config branch.from-topic_2.merge > actual &&
272 git rev-list from-topic_2 &&
273 git update-ref refs/heads/from-topic_2 from-topic_2^ &&
274 git rev-parse from-topic_2 >expect2 &&
275 git branch --set-upstream-to main from-topic_2 &&
276 git config branch.from-main.merge > actual &&
277 git rev-parse from-topic_2 >actual2 &&
278 grep -q "^refs/heads/main$" actual &&
279 cmp expect2 actual2
280 '
281
282 test_expect_success '--set-upstream-to @{-1}' '
283 git checkout follower &&
284 git checkout from-topic_2 &&
285 git config branch.from-topic_2.merge > expect2 &&
286 git branch --set-upstream-to @{-1} from-main &&
287 git config branch.from-main.merge > actual &&
288 git config branch.from-topic_2.merge > actual2 &&
289 git branch --set-upstream-to follower from-main &&
290 git config branch.from-main.merge > expect &&
291 test_cmp expect2 actual2 &&
292 test_cmp expect actual
293 '
294
295 test_expect_success 'status tracking origin/main shows only main' '
296 git -C test checkout b4 &&
297 git -C test status >actual &&
298 cat >expect <<-EOF &&
299 On branch b4
300 Your branch is ahead of ${SQ}origin/main${SQ} by 2 commits.
301 (use "git push" to publish your local commits)
302
303 nothing to commit, working tree clean
304 EOF
305 test_cmp expect actual
306 '
307
308 test_expect_success 'status --no-ahead-behind tracking origin/main shows only main' '
309 git -C test checkout b4 &&
310 git -C test status --no-ahead-behind >actual &&
311 cat >expect <<-EOF &&
312 On branch b4
313 Your branch and ${SQ}origin/main${SQ} refer to different commits.
314 (use "git status --ahead-behind" for details)
315
316 nothing to commit, working tree clean
317 EOF
318 test_cmp expect actual
319 '
320
321 test_expect_success 'status.compareBranches deduplicates when upstream and push are the same' '
322 test_config -C test status.compareBranches "@{upstream} @{push}" &&
323 git -C test checkout main &&
324 git -C test status >actual &&
325 cat >expect <<-EOF &&
326 On branch main
327 Your branch is up to date with ${SQ}origin/main${SQ}.
328
329 nothing to commit, working tree clean
330 EOF
331 test_cmp expect actual
332 '
333
334 test_expect_success 'status.compareBranches with only upstream shows only upstream' '
335 test_config -C test status.compareBranches "@{upstream}" &&
336 git -C test checkout main &&
337 git -C test status >actual &&
338 cat >expect <<-EOF &&
339 On branch main
340 Your branch is up to date with ${SQ}origin/main${SQ}.
341
342 nothing to commit, working tree clean
343 EOF
344 test_cmp expect actual
345 '
346
347 test_expect_success 'status.compareBranches with only push shows only push' '
348 test_config -C test push.default current &&
349 test_config -C test status.compareBranches "@{push}" &&
350 git -C test checkout -b feature2 origin/main &&
351 git -C test push origin HEAD &&
352 (cd test && advance work) &&
353 git -C test status >actual &&
354 cat >expect <<-EOF &&
355 On branch feature2
356 Your branch is ahead of ${SQ}origin/feature2${SQ} by 1 commit.
357 (use "git push" to publish your local commits)
358
359 nothing to commit, working tree clean
360 EOF
361 test_cmp expect actual
362 '
363
364 test_expect_success 'status.compareBranches shows ahead of both upstream and push branch' '
365 test_config -C test push.default current &&
366 test_config -C test status.compareBranches "@{upstream} @{push}" &&
367 git -C test checkout -b feature3 origin/main &&
368 git -C test push origin HEAD &&
369 (cd test && advance work) &&
370 git -C test status >actual &&
371 cat >expect <<-EOF &&
372 On branch feature3
373 Your branch is ahead of ${SQ}origin/main${SQ} by 1 commit.
374
375 Your branch is ahead of ${SQ}origin/feature3${SQ} by 1 commit.
376 (use "git push" to publish your local commits)
377
378 nothing to commit, working tree clean
379 EOF
380 test_cmp expect actual
381 '
382
383 test_expect_success 'checkout with status.compareBranches shows both branches' '
384 test_config -C test push.default current &&
385 test_config -C test status.compareBranches "@{upstream} @{push}" &&
386 git -C test checkout feature3 >actual &&
387 cat >expect <<-EOF &&
388 Your branch is ahead of ${SQ}origin/main${SQ} by 1 commit.
389
390 Your branch is ahead of ${SQ}origin/feature3${SQ} by 1 commit.
391 (use "git push" to publish your local commits)
392 EOF
393 test_cmp expect actual
394 '
395
396 test_expect_success 'setup for ahead of tracked but diverged from main' '
397 (
398 cd test &&
399 git checkout -b feature4 origin/main &&
400 advance work1 &&
401 git checkout origin/main &&
402 advance work2 &&
403 git push origin HEAD:main &&
404 git checkout feature4 &&
405 advance work3
406 )
407 '
408
409 test_expect_success 'status.compareBranches shows diverged and ahead' '
410 test_config -C test push.default current &&
411 test_config -C test status.compareBranches "@{upstream} @{push}" &&
412 git -C test checkout feature4 &&
413 git -C test branch --set-upstream-to origin/main &&
414 git -C test push origin HEAD &&
415 (cd test && advance work) &&
416 git -C test status >actual &&
417 cat >expect <<-EOF &&
418 On branch feature4
419 Your branch and ${SQ}origin/main${SQ} have diverged,
420 and have 3 and 1 different commits each, respectively.
421 (use "git pull" if you want to integrate the remote branch with yours)
422
423 Your branch is ahead of ${SQ}origin/feature4${SQ} by 1 commit.
424 (use "git push" to publish your local commits)
425
426 nothing to commit, working tree clean
427 EOF
428 test_cmp expect actual
429 '
430
431 test_expect_success 'status --no-ahead-behind with status.compareBranches' '
432 test_config -C test push.default current &&
433 test_config -C test status.compareBranches "@{upstream} @{push}" &&
434 git -C test checkout feature4 &&
435 git -C test status --no-ahead-behind >actual &&
436 cat >expect <<-EOF &&
437 On branch feature4
438 Your branch and ${SQ}origin/main${SQ} refer to different commits.
439
440 Your branch and ${SQ}origin/feature4${SQ} refer to different commits.
441 (use "git status --ahead-behind" for details)
442
443 nothing to commit, working tree clean
444 EOF
445 test_cmp expect actual
446 '
447
448 test_expect_success 'setup upstream remote' '
449 (
450 cd test &&
451 git remote add upstream ../. &&
452 git fetch upstream
453 )
454 '
455
456 test_expect_success 'status.compareBranches with upstream and origin remotes' '
457 test_config -C test push.default current &&
458 test_config -C test remote.pushDefault origin &&
459 test_config -C test status.compareBranches "@{upstream} @{push}" &&
460 git -C test checkout -b feature5 upstream/main &&
461 git -C test push origin &&
462 (cd test && advance work) &&
463 git -C test status >actual &&
464 cat >expect <<-EOF &&
465 On branch feature5
466 Your branch is ahead of ${SQ}upstream/main${SQ} by 1 commit.
467
468 Your branch is ahead of ${SQ}origin/feature5${SQ} by 1 commit.
469 (use "git push" to publish your local commits)
470
471 nothing to commit, working tree clean
472 EOF
473 test_cmp expect actual
474 '
475
476 test_expect_success 'status.compareBranches supports ordered upstream/push entries' '
477 test_config -C test push.default current &&
478 test_config -C test remote.pushDefault origin &&
479 test_config -C test status.compareBranches "@{push} @{upstream}" &&
480 git -C test checkout -b feature6 upstream/main &&
481 git -C test push origin &&
482 (cd test && advance work) &&
483 git -C test status >actual &&
484 cat >expect <<-EOF &&
485 On branch feature6
486 Your branch is ahead of ${SQ}origin/feature6${SQ} by 1 commit.
487 (use "git push" to publish your local commits)
488
489 Your branch is ahead of ${SQ}upstream/main${SQ} by 1 commit.
490
491 nothing to commit, working tree clean
492 EOF
493 test_cmp expect actual
494 '
495
496 test_expect_success 'status.compareBranches deduplicates repeated specifiers' '
497 test_config -C test push.default current &&
498 test_config -C test remote.pushDefault origin &&
499 test_config -C test status.compareBranches "@{push} @{upstream} @{push}" &&
500 git -C test checkout -b feature7 upstream/main &&
501 git -C test push origin &&
502 (cd test && advance work) &&
503 git -C test status >actual &&
504 cat >expect <<-EOF &&
505 On branch feature7
506 Your branch is ahead of ${SQ}origin/feature7${SQ} by 1 commit.
507 (use "git push" to publish your local commits)
508
509 Your branch is ahead of ${SQ}upstream/main${SQ} by 1 commit.
510
511 nothing to commit, working tree clean
512 EOF
513 test_cmp expect actual
514 '
515
516 test_expect_success 'status.compareBranches with diverged push branch' '
517 test_config -C test push.default current &&
518 test_config -C test remote.pushDefault origin &&
519 test_config -C test status.compareBranches "@{upstream} @{push}" &&
520 git -C test checkout -b feature8 upstream/main &&
521 (cd test && advance work81) &&
522 git -C test push origin &&
523 git -C test reset --hard upstream/main &&
524 (cd test && advance work82) &&
525 git -C test status >actual &&
526 cat >expect <<-EOF &&
527 On branch feature8
528 Your branch is ahead of ${SQ}upstream/main${SQ} by 1 commit.
529
530 Your branch and ${SQ}origin/feature8${SQ} have diverged,
531 and have 1 and 1 different commits each, respectively.
532
533 nothing to commit, working tree clean
534 EOF
535 test_cmp expect actual
536 '
537
538 test_expect_success 'status.compareBranches shows up to date branches' '
539 test_config -C test push.default current &&
540 test_config -C test remote.pushDefault origin &&
541 test_config -C test status.compareBranches "@{upstream} @{push}" &&
542 git -C test checkout -b feature9 upstream/main &&
543 git -C test push origin &&
544 git -C test status >actual &&
545 cat >expect <<-EOF &&
546 On branch feature9
547 Your branch is up to date with ${SQ}upstream/main${SQ}.
548
549 Your branch is up to date with ${SQ}origin/feature9${SQ}.
550
551 nothing to commit, working tree clean
552 EOF
553 test_cmp expect actual
554 '
555
556 test_expect_success 'status --no-ahead-behind with status.compareBranches up to date' '
557 test_config -C test push.default current &&
558 test_config -C test remote.pushDefault origin &&
559 test_config -C test status.compareBranches "@{upstream} @{push}" &&
560 git -C test checkout feature9 >actual &&
561 git -C test push origin &&
562 git -C test status --no-ahead-behind >actual &&
563 cat >expect <<-EOF &&
564 On branch feature9
565 Your branch is up to date with ${SQ}upstream/main${SQ}.
566
567 Your branch is up to date with ${SQ}origin/feature9${SQ}.
568
569 nothing to commit, working tree clean
570 EOF
571 test_cmp expect actual
572 '
573
574 test_expect_success 'checkout with status.compareBranches shows up to date' '
575 test_config -C test push.default current &&
576 test_config -C test remote.pushDefault origin &&
577 test_config -C test status.compareBranches "@{upstream} @{push}" &&
578 git -C test checkout feature9 >actual &&
579 cat >expect <<-EOF &&
580 Your branch is up to date with ${SQ}upstream/main${SQ}.
581
582 Your branch is up to date with ${SQ}origin/feature9${SQ}.
583 EOF
584 test_cmp expect actual
585 '
586
587 test_expect_success 'status.compareBranches with upstream behind and push up to date' '
588 test_config -C test push.default current &&
589 test_config -C test remote.pushDefault origin &&
590 test_config -C test status.compareBranches "@{upstream} @{push}" &&
591 git -C test checkout -b ahead upstream/main &&
592 (cd test && advance work) &&
593 git -C test push upstream HEAD &&
594 git -C test checkout -b feature10 upstream/main &&
595 git -C test push origin &&
596 git -C test branch --set-upstream-to upstream/ahead &&
597 git -C test status >actual &&
598 cat >expect <<-EOF &&
599 On branch feature10
600 Your branch is behind ${SQ}upstream/ahead${SQ} by 1 commit, and can be fast-forwarded.
601 (use "git pull" to update your local branch)
602
603 Your branch is up to date with ${SQ}origin/feature10${SQ}.
604
605 nothing to commit, working tree clean
606 EOF
607 test_cmp expect actual
608 '
609
610 test_expect_success 'status.compareBranches with remapped push refspec' '
611 test_config -C test remote.origin.push refs/heads/feature11:refs/heads/remapped &&
612 test_config -C test status.compareBranches "@{upstream} @{push}" &&
613 git -C test checkout -b feature11 origin/main &&
614 git -C test push &&
615 (cd test && advance work) &&
616 git -C test status >actual &&
617 cat >expect <<-EOF &&
618 On branch feature11
619 Your branch is ahead of ${SQ}origin/main${SQ} by 1 commit.
620
621 Your branch is ahead of ${SQ}origin/remapped${SQ} by 1 commit.
622 (use "git push" to publish your local commits)
623
624 nothing to commit, working tree clean
625 EOF
626 test_cmp expect actual
627 '
628
629 test_expect_success 'status.compareBranches with remapped push and upstream remote' '
630 test_config -C test remote.pushDefault origin &&
631 test_config -C test remote.origin.push refs/heads/feature12:refs/heads/remapped &&
632 test_config -C test status.compareBranches "@{upstream} @{push}" &&
633 git -C test checkout -b feature12 upstream/main &&
634 git -C test push origin &&
635 (cd test && advance work) &&
636 git -C test status >actual &&
637 cat >expect <<-EOF &&
638 On branch feature12
639 Your branch is ahead of ${SQ}upstream/main${SQ} by 1 commit.
640
641 Your branch is ahead of ${SQ}origin/remapped${SQ} by 1 commit.
642 (use "git push" to publish your local commits)
643
644 nothing to commit, working tree clean
645 EOF
646 test_cmp expect actual
647 '
648
649 test_done