status: clarify how status.compareBranches deduplicates

The order of output when multiple branches are specified on the configuration variable was not clearly spelled out in the documentation. Add a paragraph to describe the order and also how the branches are deduplicated. Update t6040 with additional tests to illustrate how multiple branches are shown and deduplicated. Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com> [jc: made a whole replacement into incremental; wrote log message.] Signed-off-by: Junio C Hamano <gitster@pobox.com>

Harald Nordgren committed Mar 4, 2026 at 12:25 UTC 68791d7506aa39da7c98de4143cac09cc93fc404
2 files changed +88 -38
Documentation/config/status.adoc
+6
@@ -26,6 +26,12 @@ status.compareBranches::
26 If not set, the default behavior is equivalent to `@{upstream}`, which
27 compares against the configured upstream tracking branch.
28 +
29 +The entries are shown in the order they appear in the configuration.
30 +Duplicate entries that resolve to the same ref are suppressed after
31 +their first occurrence, so `@{push} @{upstream} @{push}` shows at
32 +most two comparisons. When `@{upstream}` and `@{push}` resolve to
33 +the same remote-tracking branch, only one comparison is shown.
34 ++
35 Example:
36 +
37 ----
t/t6040-tracking-info.sh
+82 -38
@@ -293,11 +293,8 @@ test_expect_success '--set-upstream-to @{-1}' '
293 '
294
295 test_expect_success 'status tracking origin/main shows only main' '
296 - (
297 - cd test &&
298 - git checkout b4 &&
299 - git status >../actual
300 - ) &&
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.
@@ -309,11 +306,8 @@ test_expect_success 'status tracking origin/main shows only main' '
306 '
307
308 test_expect_success 'status --no-ahead-behind tracking origin/main shows only main' '
312 - (
313 - cd test &&
314 - git checkout b4 &&
315 - git status --no-ahead-behind >../actual
316 - ) &&
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.
@@ -324,7 +318,7 @@ test_expect_success 'status --no-ahead-behind tracking origin/main shows only ma
318 test_cmp expect actual
319 '
320
327 -test_expect_success 'status.compareBranches from upstream has no duplicates' '
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 &&
@@ -337,18 +331,48 @@ test_expect_success 'status.compareBranches from upstream has no duplicates' '
331 test_cmp expect actual
332 '
333
340 -test_expect_success 'status.compareBranches shows ahead of both upstream and push branch' '
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 &&
342 - test_config -C test status.compareBranches "@{upstream} @{push}" &&
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
351 - Your branch is ahead of ${SQ}origin/feature2${SQ} by 1 commit.
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
@@ -359,11 +383,11 @@ test_expect_success 'status.compareBranches shows ahead of both upstream and pus
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}" &&
362 - git -C test checkout feature2 >actual &&
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
366 - Your branch is ahead of ${SQ}origin/feature2${SQ} by 1 commit.
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
@@ -469,21 +493,41 @@ test_expect_success 'status.compareBranches supports ordered upstream/push entri
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}" &&
476 - git -C test checkout -b feature7 upstream/main &&
477 - (cd test && advance work71) &&
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 &&
480 - (cd test && advance work72) &&
524 + (cd test && advance work82) &&
525 git -C test status >actual &&
526 cat >expect <<-EOF &&
483 - On branch feature7
527 + On branch feature8
528 Your branch is ahead of ${SQ}upstream/main${SQ} by 1 commit.
529
486 - Your branch and ${SQ}origin/feature7${SQ} have diverged,
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
@@ -495,14 +539,14 @@ 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}" &&
498 - git -C test checkout -b feature8 upstream/main &&
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 &&
502 - On branch feature8
546 + On branch feature9
547 Your branch is up to date with ${SQ}upstream/main${SQ}.
548
505 - Your branch is up to date with ${SQ}origin/feature8${SQ}.
549 + Your branch is up to date with ${SQ}origin/feature9${SQ}.
550
551 nothing to commit, working tree clean
552 EOF
@@ -513,14 +557,14 @@ test_expect_success 'status --no-ahead-behind with status.compareBranches up to
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}" &&
516 - git -C test checkout feature8 >actual &&
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 &&
520 - On branch feature8
564 + On branch feature9
565 Your branch is up to date with ${SQ}upstream/main${SQ}.
566
523 - Your branch is up to date with ${SQ}origin/feature8${SQ}.
567 + Your branch is up to date with ${SQ}origin/feature9${SQ}.
568
569 nothing to commit, working tree clean
570 EOF
@@ -531,11 +575,11 @@ 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}" &&
534 - git -C test checkout feature8 >actual &&
578 + git -C test checkout feature9 >actual &&
579 cat >expect <<-EOF &&
580 Your branch is up to date with ${SQ}upstream/main${SQ}.
581
538 - Your branch is up to date with ${SQ}origin/feature8${SQ}.
582 + Your branch is up to date with ${SQ}origin/feature9${SQ}.
583 EOF
584 test_cmp expect actual
585 '
@@ -547,16 +591,16 @@ test_expect_success 'status.compareBranches with upstream behind and push up to
591 git -C test checkout -b ahead upstream/main &&
592 (cd test && advance work) &&
593 git -C test push upstream HEAD &&
550 - git -C test checkout -b feature9 upstream/main &&
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 &&
555 - On branch feature9
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
559 - Your branch is up to date with ${SQ}origin/feature9${SQ}.
603 + Your branch is up to date with ${SQ}origin/feature10${SQ}.
604
605 nothing to commit, working tree clean
606 EOF
@@ -564,14 +608,14 @@ test_expect_success 'status.compareBranches with upstream behind and push up to
608 '
609
610 test_expect_success 'status.compareBranches with remapped push refspec' '
567 - test_config -C test remote.origin.push refs/heads/feature10:refs/heads/remapped &&
611 + test_config -C test remote.origin.push refs/heads/feature11:refs/heads/remapped &&
612 test_config -C test status.compareBranches "@{upstream} @{push}" &&
569 - git -C test checkout -b feature10 origin/main &&
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 &&
574 - On branch feature10
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.
@@ -584,14 +628,14 @@ test_expect_success 'status.compareBranches with remapped push refspec' '
628
629 test_expect_success 'status.compareBranches with remapped push and upstream remote' '
630 test_config -C test remote.pushDefault origin &&
587 - test_config -C test remote.origin.push refs/heads/feature11:refs/heads/remapped &&
631 + test_config -C test remote.origin.push refs/heads/feature12:refs/heads/remapped &&
632 test_config -C test status.compareBranches "@{upstream} @{push}" &&
589 - git -C test checkout -b feature11 upstream/main &&
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 &&
594 - On branch feature11
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.