[PATCH v29 0/2] status: add status.compareBranches config for multiple branch comparisons
From: Harald Nordgren via GitGitGadget <hidden>
Date: 2026-02-25 21:51:06
cc: Chris Torek chris.torek@gmail.com cc: Yee Cheng Chin
ychin.macvim@gmail.com cc: "brian m. carlson" sandals@crustytoothpaste.net
cc: Ben Knoble ben.knoble@gmail.com cc: "Kristoffer Haugsbakk"
kristofferhaugsbakk@fastmail.com cc: Phillip Wood phillip.wood123@gmail.com
cc: Nico Williams nico@cryptonector.com cc: Patrick Steinhardt ps@pks.im cc:
Jeff King peff@peff.net
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