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.