Git development
 help / color / mirror / Atom feed
From: "Harald Nordgren via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: Phillip Wood <phillip.wood123@gmail.com>,
	Kristoffer Haugsbakk <kristofferhaugsbakk@fastmail.com>,
	Harald Nordgren <haraldnordgren@gmail.com>,
	Harald Nordgren <haraldnordgren@gmail.com>
Subject: [PATCH v2] status: compare against both upstream and push branch by default
Date: Wed, 21 Oct 2026 12:27:42 +0000	[thread overview]
Message-ID: <pull.2458.v2.git.git.1792585662669.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.2458.git.git.1792437798463.gitgitgadget@gmail.com>

From: Harald Nordgren <haraldnordgren@gmail.com>

Commit 3ea95ac9c5 (status: add status.compareBranches config for
multiple branch comparisons, 2026-02-26) added status.compareBranches
so that "git status" can show comparison of the current branch with
its upstream in addition to where the branch is pushed to, which is
great to support the triangular workflow. It however did not make it
the default to show both.

Showing both without any configuration was the original proposal for
that commit. But some found the comparison with the push branch to be
noise. So the comparison was made opt in [1], with the idea of
flipping the default later if people like the option.

Make "@{upstream} @{push}" the default. With push.default left at
"simple", @{push} is either the same as @{upstream} or does not
resolve at all, so the output stays the same. It only changes for
those who set push.default to "current" or "matching", or configure a
push refspec, in two cases:

  - In a triangular workflow, a comparison with the push branch is
    shown after the one with the upstream.

  - A branch without an upstream is compared with the branch it is
    pushed to, where nothing was shown before.

Those who find the comparison with the push branch to be noise can
set status.compareBranches to "@{upstream}" to get the old output
back. Having configured push.default and a push remote to get there,
they are the users best placed to find that setting. Those who are
just starting to push somewhere other than where they pull from
benefit the most from seeing both comparisons without having to
discover the variable first.

No existing test relied on the old default, since none of them had a
push branch different from the upstream without also setting
status.compareBranches. Add tests for the new default on a branch
whose upstream and push branch are the same, on a branch in a
triangular workflow, and on a branch without an upstream. The existing
test that sets the variable to "@{upstream}" uses a branch where both
are the same, so it passes with either default. Add one on a
triangular branch to show that it restores the old output.

[1] https://lore.kernel.org/git/xmqq8qe0f2iq.fsf@gitster.g/

Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
---
    status: compare against both upstream and push branch by default
    
    Make @{upstream} @{push} the default for status.compareBranches. With
    the default push.default of simple the output does not change. With
    current or matching, a branch pushed somewhere other than its upstream
    now shows both comparisons.
    
    Changes in v2:
    
     * Kept the existing tests unchanged, including the explicit
       "@{upstream} @{push}" config and the "@{upstream}" test on main
     * Added tests for the new default with the same upstream and push
       branch, in a triangular workflow, and without an upstream
     * Added a test showing that "@{upstream}" restores the old output on a
       triangular branch
     * Reworded the commit message to point to 3ea95ac9c5 and explain which
       setups see a change

Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-2458%2FHaraldNordgren%2Fstatus-compare-branches-default-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-2458/HaraldNordgren/status-compare-branches-default-v2
Pull-Request: https://github.com/git/git/pull/2458

Range-diff vs v1:

 1:  2de975c175 ! 1:  39512b9ea1 status: compare against both upstream and push branch by default
     @@ Metadata
       ## Commit message ##
          status: compare against both upstream and push branch by default
      
     -    In a triangular workflow, where a branch is pulled from one place and
     -    pushed to another, "git status" only compares the branch to its
     -    upstream. It says nothing about the branch it is pushed to unless
     -    status.compareBranches is configured.
     +    Commit 3ea95ac9c5 (status: add status.compareBranches config for
     +    multiple branch comparisons, 2026-02-26) added status.compareBranches
     +    so that "git status" can show comparison of the current branch with
     +    its upstream in addition to where the branch is pushed to, which is
     +    great to support the triangular workflow. It however did not make it
     +    the default to show both.
      
     -    Show both comparisons by default. When the two resolve to the same
     -    branch, which is the common case, only one comparison is shown, so the
     -    output for most users does not change. Setting status.compareBranches
     -    to "@{upstream}" gives the previous output.
     +    Showing both without any configuration was the original proposal for
     +    that commit. But some found the comparison with the push branch to be
     +    noise. So the comparison was made opt in [1], with the idea of
     +    flipping the default later if people like the option.
     +
     +    Make "@{upstream} @{push}" the default. With push.default left at
     +    "simple", @{push} is either the same as @{upstream} or does not
     +    resolve at all, so the output stays the same. It only changes for
     +    those who set push.default to "current" or "matching", or configure a
     +    push refspec, in two cases:
     +
     +      - In a triangular workflow, a comparison with the push branch is
     +        shown after the one with the upstream.
     +
     +      - A branch without an upstream is compared with the branch it is
     +        pushed to, where nothing was shown before.
     +
     +    Those who find the comparison with the push branch to be noise can
     +    set status.compareBranches to "@{upstream}" to get the old output
     +    back. Having configured push.default and a push remote to get there,
     +    they are the users best placed to find that setting. Those who are
     +    just starting to push somewhere other than where they pull from
     +    benefit the most from seeing both comparisons without having to
     +    discover the variable first.
     +
     +    No existing test relied on the old default, since none of them had a
     +    push branch different from the upstream without also setting
     +    status.compareBranches. Add tests for the new default on a branch
     +    whose upstream and push branch are the same, on a branch in a
     +    triangular workflow, and on a branch without an upstream. The existing
     +    test that sets the variable to "@{upstream}" uses a branch where both
     +    are the same, so it passes with either default. Add one on a
     +    triangular branch to show that it restores the old output.
     +
     +    [1] https://lore.kernel.org/git/xmqq8qe0f2iq.fsf@gitster.g/
      
          Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
      
     @@ remote.c: int format_tracking_info(struct branch *branch, struct strbuf *sb,
       
       	upstream_ref = branch_get_upstream(branch, NULL);
      
     - ## t/t5505-remote.sh ##
     -@@ t/t5505-remote.sh: setup_url_pushremote () {
     - 		git checkout -b topic --track origin/main &&
     - 		git commit --allow-empty -m topic-change &&
     - 		git config push.default current &&
     --		git config status.compareBranches "@{upstream} @{push}" &&
     - 		git config branch.topic.pushRemote "$fork_url" &&
     - 		git push
     - 	)
     -
       ## t/t6040-tracking-info.sh ##
      @@ t/t6040-tracking-info.sh: test_expect_success 'status.compareBranches deduplicates when upstream and push
       	test_cmp expect actual
       '
       
     --test_expect_success 'status.compareBranches with only upstream shows only upstream' '
     --	test_config -C test status.compareBranches "@{upstream}" &&
     --	git -C test checkout main &&
     --	git -C test status >actual &&
     --	cat >expect <<-EOF &&
     --	On branch main
     --	Your branch is up to date with ${SQ}origin/main${SQ}.
     --
     --	nothing to commit, working tree clean
     --	EOF
     --	test_cmp expect actual
     --'
     --
     - test_expect_success 'status.compareBranches with only push shows only push' '
     - 	test_config -C test push.default current &&
     - 	test_config -C test status.compareBranches "@{push}" &&
     -@@ t/t6040-tracking-info.sh: test_expect_success 'status.compareBranches with only push shows only push' '
     - 	test_cmp expect actual
     - '
     - 
     --test_expect_success 'status.compareBranches shows ahead of both upstream and push branch' '
     -+test_expect_success 'status shows ahead of both upstream and push branch by default' '
     - 	test_config -C test push.default current &&
     --	test_config -C test status.compareBranches "@{upstream} @{push}" &&
     - 	git -C test checkout -b feature3 origin/main &&
     - 	git -C test push origin HEAD &&
     - 	(cd test && advance work) &&
     ++test_expect_success 'status shows one comparison by default when upstream and push are the same' '
     ++	git -C test checkout main &&
     ++	git -C test status >actual &&
     ++	cat >expect <<-EOF &&
     ++	On branch main
     ++	Your branch is up to date with ${SQ}origin/main${SQ}.
     ++
     ++	nothing to commit, working tree clean
     ++	EOF
     ++	test_cmp expect actual
     ++'
     ++
     + test_expect_success 'status.compareBranches with only upstream shows only upstream' '
     + 	test_config -C test status.compareBranches "@{upstream}" &&
     + 	git -C test checkout main &&
      @@ t/t6040-tracking-info.sh: test_expect_success 'status.compareBranches shows ahead of both upstream and pus
       	test_cmp expect actual
       '
       
     -+test_expect_success 'status.compareBranches with only upstream shows only upstream' '
     ++test_expect_success 'status shows ahead of both upstream and push branch by default' '
     ++	test_config -C test push.default current &&
     ++	git -C test checkout feature3 &&
     ++	git -C test status >actual &&
     ++	cat >expect <<-EOF &&
     ++	On branch feature3
     ++	Your branch is ahead of ${SQ}origin/main${SQ} by 1 commit.
     ++
     ++	Your branch is ahead of ${SQ}origin/feature3${SQ} by 1 commit.
     ++	  (use "git push" to publish your local commits)
     ++
     ++	nothing to commit, working tree clean
     ++	EOF
     ++	test_cmp expect actual
     ++'
     ++
     ++test_expect_success 'status.compareBranches with only upstream hides a different push branch' '
      +	test_config -C test push.default current &&
      +	test_config -C test status.compareBranches "@{upstream}" &&
      +	git -C test checkout feature3 &&
     @@ t/t6040-tracking-info.sh: test_expect_success 'status.compareBranches shows ahea
       test_expect_success 'checkout with status.compareBranches shows both branches' '
       	test_config -C test push.default current &&
       	test_config -C test status.compareBranches "@{upstream} @{push}" &&
     +@@ t/t6040-tracking-info.sh: test_expect_success 'status.compareBranches with behind push branch and no upstr
     + 	test_cmp expect actual
     + '
     + 
     ++test_expect_success 'status shows push branch by default without upstream' '
     ++	test_config -C test push.default current &&
     ++	test_config -C test remote.pushDefault origin &&
     ++	git -C test checkout feature15 &&
     ++	git -C test status >actual &&
     ++	cat >expect <<-EOF &&
     ++	On branch feature15
     ++	Your branch is behind ${SQ}origin/feature15${SQ} by 1 commit, and can be fast-forwarded.
     ++	  (use "git pull origin feature15" to update your local branch)
     ++
     ++	nothing to commit, working tree clean
     ++	EOF
     ++	test_cmp expect actual
     ++'
     ++
     + test_expect_success 'status.compareBranches behind upstream-equals-push suggests plain pull' '
     + 	test_config -C test status.compareBranches "@{upstream} @{push}" &&
     + 	git -C test checkout -b feature16 origin/main &&


 Documentation/config/status.adoc | 11 +++---
 remote.c                         |  1 +
 t/t6040-tracking-info.sh         | 57 ++++++++++++++++++++++++++++++++
 3 files changed, 64 insertions(+), 5 deletions(-)

diff --git a/Documentation/config/status.adoc b/Documentation/config/status.adoc
index b5dd85b761..1d847d3a8a 100644
--- a/Documentation/config/status.adoc
+++ b/Documentation/config/status.adoc
@@ -23,8 +23,9 @@ status.compareBranches::
 	are supported. They are interpreted as `branch@{upstream}` and
 	`branch@{push}` for the current branch.
 +
-If not set, the default behavior is equivalent to `@{upstream}`, which
-compares against the configured upstream tracking branch.
+If not set, the default behavior is equivalent to `@{upstream} @{push}`,
+which compares against both the configured upstream and push tracking
+branches.
 +
 The entries are shown in the order they appear in the configuration.
 Duplicate entries that resolve to the same ref are suppressed after
@@ -36,11 +37,11 @@ Example:
 +
 ----
 [status]
-	compareBranches = @{upstream} @{push}
+	compareBranches = @{upstream}
 ----
 +
-This would show comparisons against both the configured upstream and push
-tracking branches for the current branch.
+This would only show the comparison against the configured upstream
+tracking branch for the current branch.
 
 status.displayCommentPrefix::
 	If set to true, linkgit:git-status[1] will insert a comment
diff --git a/remote.c b/remote.c
index 49ee2ea318..0d97cb9100 100644
--- a/remote.c
+++ b/remote.c
@@ -2472,6 +2472,7 @@ int format_tracking_info(struct branch *branch, struct strbuf *sb,
 		string_list_remove_empty_items(&branches, 0);
 	} else {
 		string_list_append(&branches, "@{upstream}");
+		string_list_append(&branches, "@{push}");
 	}
 
 	upstream_ref = branch_get_upstream(branch, NULL);
diff --git a/t/t6040-tracking-info.sh b/t/t6040-tracking-info.sh
index e95d420972..3d61297c37 100755
--- a/t/t6040-tracking-info.sh
+++ b/t/t6040-tracking-info.sh
@@ -331,6 +331,18 @@ test_expect_success 'status.compareBranches deduplicates when upstream and push
 	test_cmp expect actual
 '
 
+test_expect_success 'status shows one comparison by default when upstream and push are the same' '
+	git -C test checkout main &&
+	git -C test status >actual &&
+	cat >expect <<-EOF &&
+	On branch main
+	Your branch is up to date with ${SQ}origin/main${SQ}.
+
+	nothing to commit, working tree clean
+	EOF
+	test_cmp expect actual
+'
+
 test_expect_success 'status.compareBranches with only upstream shows only upstream' '
 	test_config -C test status.compareBranches "@{upstream}" &&
 	git -C test checkout main &&
@@ -380,6 +392,36 @@ test_expect_success 'status.compareBranches shows ahead of both upstream and pus
 	test_cmp expect actual
 '
 
+test_expect_success 'status shows ahead of both upstream and push branch by default' '
+	test_config -C test push.default current &&
+	git -C test checkout feature3 &&
+	git -C test status >actual &&
+	cat >expect <<-EOF &&
+	On branch feature3
+	Your branch is ahead of ${SQ}origin/main${SQ} by 1 commit.
+
+	Your branch is ahead of ${SQ}origin/feature3${SQ} by 1 commit.
+	  (use "git push" to publish your local commits)
+
+	nothing to commit, working tree clean
+	EOF
+	test_cmp expect actual
+'
+
+test_expect_success 'status.compareBranches with only upstream hides a different push branch' '
+	test_config -C test push.default current &&
+	test_config -C test status.compareBranches "@{upstream}" &&
+	git -C test checkout feature3 &&
+	git -C test status >actual &&
+	cat >expect <<-EOF &&
+	On branch feature3
+	Your branch is ahead of ${SQ}origin/main${SQ} by 1 commit.
+
+	nothing to commit, working tree clean
+	EOF
+	test_cmp expect actual
+'
+
 test_expect_success 'checkout with status.compareBranches shows both branches' '
 	test_config -C test push.default current &&
 	test_config -C test status.compareBranches "@{upstream} @{push}" &&
@@ -707,6 +749,21 @@ test_expect_success 'status.compareBranches with behind push branch and no upstr
 	test_cmp expect actual
 '
 
+test_expect_success 'status shows push branch by default without upstream' '
+	test_config -C test push.default current &&
+	test_config -C test remote.pushDefault origin &&
+	git -C test checkout feature15 &&
+	git -C test status >actual &&
+	cat >expect <<-EOF &&
+	On branch feature15
+	Your branch is behind ${SQ}origin/feature15${SQ} by 1 commit, and can be fast-forwarded.
+	  (use "git pull origin feature15" to update your local branch)
+
+	nothing to commit, working tree clean
+	EOF
+	test_cmp expect actual
+'
+
 test_expect_success 'status.compareBranches behind upstream-equals-push suggests plain pull' '
 	test_config -C test status.compareBranches "@{upstream} @{push}" &&
 	git -C test checkout -b feature16 origin/main &&

base-commit: 47fdf2208c5b94c8cc01c106b8f7c85efb91c926
-- 
gitgitgadget

  parent reply	other threads:[~2026-10-21 12:27 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-19 19:23 [PATCH] status: compare against both upstream and push branch by default Harald Nordgren via GitGitGadget
2026-10-19 22:54 ` Junio C Hamano
2026-10-20  9:16   ` Harald Nordgren
2026-10-20  9:33 ` Phillip Wood
2026-10-20 10:19   ` Harald Nordgren
2026-10-20 10:56     ` Kristoffer Haugsbakk
2026-10-20 13:22     ` Phillip Wood
2026-10-21 12:27 ` Harald Nordgren via GitGitGadget [this message]
2026-10-23 17:43   ` [PATCH v2] " Junio C Hamano
2026-10-23 18:48     ` Harald Nordgren
2026-10-23 22:10       ` Junio C Hamano
2026-10-23 22:54         ` Harald Nordgren
2026-10-23 23:07           ` Junio C Hamano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=pull.2458.v2.git.git.1792585662669.gitgitgadget@gmail.com \
    --to=gitgitgadget@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=haraldnordgren@gmail.com \
    --cc=kristofferhaugsbakk@fastmail.com \
    --cc=phillip.wood123@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox