Subject: [PATCH v29 0/2] status: add status.compareBranches config for multiple branch comparisons

From: "Harald Nordgren via GitGitGadget" <[email-masked]>
Date: Wed, 25 Feb 2026 21:51:01 +0000

cc: Chris Torek [email-masked] cc: Yee Cheng Chin
[email-masked] cc: "brian m. carlson" [email-masked]
cc: Ben Knoble [email-masked] cc: "Kristoffer Haugsbakk"
[email-masked] cc: Phillip Wood [email-masked]
cc: Nico Williams [email-masked] cc: Patrick Steinhardt [email-masked] cc:
Jeff King [email-masked]

Harald Nordgren (2):
  refactor format_branch_comparison in preparation
  status: add status.compareBranches config for multiple branch
    comparisons

 Documentation/config/status.adoc |  19 ++
 remote.c                         | 180 +++++++++++++----
 t/t6040-tracking-info.sh         | 335 +++++++++++++++++++++++++++++++
 3 files changed, 497 insertions(+), 37 deletions(-)

base-commit: 7c02d39fc2ed2702223c7674f73150d9a7e61ba4
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-2138%2FHaraldNordgren%2Fahead_of_main_status-v29
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-2138/HaraldNordgren/ahead_of_main_status-v29
Pull-Request: https://github.com/git/git/pull/2138

Range-diff vs v28:

 1:  f3c8c782b0 = 1:  48db1f4847 refactor format_branch_comparison in preparation
 2:  067978dd09 ! 2:  6a88f41fa5 status: add status.compareBranches config for multiple branch comparisons
     @@ Metadata
       ## Commit message ##
          status: add status.compareBranches config for multiple branch comparisons
      
     -    Add a new configuration variable `status.compareBranches` that allows
     -    users to specify a space-separated list of branches to compare against
     -    the current branch in `git status` output.
     +    Add a new configuration variable status.compareBranches that allows
     +    users to specify a space-separated list of branch comparisons in
     +    git status output.
      
     -    Each branch in the list can be:
     -    - A remote-tracking branch name (e.g., `origin/main`)
     -    - The special reference `@{upstream}` for the tracking branch
     -    - The special reference `@{push}` for the push destination
     +    Supported values:
     +    - @{upstream} for the current branch's upstream tracking branch
     +    - @{push} for the current branch's push destination
     +
     +    Any other value is ignored and a warning is shown.
      
          When not configured, the default behavior is equivalent to setting
     -    `status.compareBranches = @{upstream}`, preserving backward compatibility.
     +    `status.compareBranches = @{upstream}`, preserving backward
     +    compatibility.
      
          The advice messages shown are context-aware:
          - "git pull" advice is shown only when comparing against @{upstream}
     @@ Documentation/config/status.adoc: status.aheadBehind::
       	non-porcelain status formats.  Defaults to true.
       
      +status.compareBranches::
     -+	A space-separated list of branches to compare the current branch
     -+	against in linkgit:git-status[1]. Each branch specification can be
     -+	a remote-tracking branch name (e.g. `origin/main`), or a special
     -+	reference like `@{upstream}` or `@{push}`. For each branch in the
     -+	list, git status shows whether the current branch is ahead, behind,
     -+	or has diverged from that branch.
     ++	A space-separated list of branch comparison specifiers to use in
     ++	linkgit:git-status[1]. Currently, only `@{upstream}` and `@{push}`
     ++	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.
     @@ Documentation/config/status.adoc: status.aheadBehind::
      ++
      +----
      +[status]
     -+	compareBranches = origin/main origin/develop
     ++	compareBranches = @{upstream} @{push}
      +----
      ++
     -+This would show comparisons against both `origin/main` and `origin/develop`.
     ++This would show comparisons against both the configured upstream and push
     ++tracking branches for the current branch.
      +
       status.displayCommentPrefix::
       	If set to true, linkgit:git-status[1] will insert a comment
     @@ remote.c: int stat_tracking_info(struct branch *branch, int *num_ours, int *num_
       
      +static char *resolve_compare_branch(struct branch *branch, const char *name)
      +{
     -+	struct strbuf buf = STRBUF_INIT;
      +	const char *resolved = NULL;
     -+	char *ret;
      +
      +	if (!branch || !name)
      +		return NULL;
      +
     -+	if (!strcasecmp(name, "@{upstream}") || !strcasecmp(name, "@{u}"))
     ++	if (!strcasecmp(name, "@{upstream}"))
      +		resolved = branch_get_upstream(branch, NULL);
      +	else if (!strcasecmp(name, "@{push}"))
      +		resolved = branch_get_push(branch, NULL);
     ++	else {
     ++		warning(_("ignoring value '%s' for status.compareBranches; only @{upstream} and @{push} are supported"),
     ++			name);
     ++		return NULL;
     ++	}
      +
      +	if (resolved)
      +		return xstrdup(resolved);
     -+
     -+	strbuf_addf(&buf, "refs/remotes/%s", name);
     -+	resolved = refs_resolve_ref_unsafe(
     -+		get_main_ref_store(the_repository),
     -+		buf.buf,
     -+		RESOLVE_REF_READING,
     -+		NULL, NULL);
     -+	if (resolved) {
     -+		ret = xstrdup(resolved);
     -+		strbuf_release(&buf);
     -+		return ret;
     -+	}
     -+
     -+	strbuf_release(&buf);
      +	return NULL;
      +}
      +
     @@ t/t6040-tracking-info.sh: test_expect_success '--set-upstream-to @{-1}' '
      +	test_cmp expect actual
      +'
      +
     -+test_expect_success 'status.compareBranches with upstream and origin remotes multiple compare branches' '
     ++test_expect_success 'status.compareBranches supports ordered upstream/push entries' '
      +	(
      +		cd test &&
      +		git checkout -b feature6 upstream/main &&
      +		git push origin &&
      +		advance work &&
     -+		git -c status.compareBranches="upstream/main origin/feature6 origin/feature5" status >../actual
     ++		git -c status.compareBranches="@{push} @{upstream}" status >../actual
      +	) &&
      +	cat >expect <<-EOF &&
      +	On branch feature6
     -+	Your branch is ahead of ${SQ}upstream/main${SQ} by 1 commit.
     -+
      +	Your branch is ahead of ${SQ}origin/feature6${SQ} by 1 commit.
      +	  (use "git push" to publish your local commits)
      +
     -+	Your branch is ahead of ${SQ}origin/feature5${SQ} by 1 commit.
     ++	Your branch is ahead of ${SQ}upstream/main${SQ} by 1 commit.
      +
      +	nothing to commit, working tree clean
      +	EOF

-- 
gitgitgadget