Subject: [PATCH v17 0/2] status: show comparison with push remote tracking branch

From: "Harald Nordgren via GitGitGadget" <[email-masked]>
Date: Mon, 05 Jan 2026 10:17:47 +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]

Harald Nordgren (2):
  refactor format_branch_comparison in preparation
  status: show comparison with push remote tracking branch

 remote.c                 | 169 ++++++++++++++++++++-----
 t/t6040-tracking-info.sh | 262 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 397 insertions(+), 34 deletions(-)

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

Range-diff vs v16:

 1:  cf4e9779c5 ! 1:  b62a9feb4d refactor format_branch_comparison in preparation
     @@ remote.c: int stat_tracking_info(struct branch *branch, int *num_ours, int *num_
      -int format_tracking_info(struct branch *branch, struct strbuf *sb,
      -			 enum ahead_behind_flags abf,
      -			 int show_divergence_advice)
     -+static void format_branch_comparison(struct strbuf *sb,
     -+				     int ours, int theirs,
     -+				     const char *branch_name,
     -+				     enum ahead_behind_flags abf,
     -+				     int show_divergence_advice)
     - {
     +-{
      -	int ours, theirs, sti;
      -	const char *full_base;
      -	char *base;
     @@ remote.c: int stat_tracking_info(struct branch *branch, int *num_ours, int *num_
      -			strbuf_addstr(sb,
      -				_("  (use \"git branch --unset-upstream\" to fixup)\n"));
      -	} else if (!sti) {
     --		strbuf_addf(sb,
     --			_("Your branch is up to date with '%s'.\n"),
     ++static void format_branch_comparison(struct strbuf *sb,
     ++				     int sti,
     ++				     int ours, int theirs,
     ++				     const char *branch_name,
     ++				     enum ahead_behind_flags abf,
     ++				     int show_divergence_advice)
     ++{
     ++	if (!sti) {
     + 		strbuf_addf(sb,
     + 			_("Your branch is up to date with '%s'.\n"),
      -			base);
     --	} else if (abf == AHEAD_BEHIND_QUICK) {
     -+	if (abf == AHEAD_BEHIND_QUICK) {
     ++			branch_name);
     + 	} else if (abf == AHEAD_BEHIND_QUICK) {
       		strbuf_addf(sb,
       			    _("Your branch and '%s' refer to different commits.\n"),
      -			    base);
     @@ remote.c: int stat_tracking_info(struct branch *branch, int *num_ours, int *num_
       		if (advice_enabled(ADVICE_STATUS_HINTS))
       			strbuf_addf(sb, _("  (use \"%s\" for details)\n"),
       				    "git status --ahead-behind");
     -+	} else if (!ours && !theirs) {
     -+		strbuf_addf(sb,
     -+			_("Your branch is up to date with '%s'.\n"),
     -+			branch_name);
     - 	} else if (!theirs) {
     - 		strbuf_addf(sb,
     +@@ remote.c: int format_tracking_info(struct branch *branch, struct strbuf *sb,
       			Q_("Your branch is ahead of '%s' by %d commit.\n",
       			   "Your branch is ahead of '%s' by %d commits.\n",
       			   ours),
     @@ remote.c: int format_tracking_info(struct branch *branch, struct strbuf *sb,
      +			strbuf_addstr(sb,
      +				_("  (use \"git branch --unset-upstream\" to fixup)\n"));
      +	} else {
     -+		format_branch_comparison(sb, ours, theirs, base, abf, show_divergence_advice);
     ++		format_branch_comparison(sb, sti, ours, theirs, base, abf, show_divergence_advice);
      +	}
      +
       	free(base);
 2:  06cb483f61 ! 2:  1348542edc status: show comparison with push remote tracking branch
     @@ remote.c: int stat_tracking_info(struct branch *branch, int *num_ours, int *num_
      +}
      +
       static void format_branch_comparison(struct strbuf *sb,
     + 				     int sti,
       				     int ours, int theirs,
       				     const char *branch_name,
       				     enum ahead_behind_flags abf,
      +				     enum branch_mode_flags advice_flags,
       				     int show_divergence_advice)
       {
     - 	if (abf == AHEAD_BEHIND_QUICK) {
     + 	if (!sti) {
     +@@ remote.c: static void format_branch_comparison(struct strbuf *sb,
     + 		strbuf_addf(sb,
     + 			    _("Your branch and '%s' refer to different commits.\n"),
     + 			    branch_name);
     +-		if (advice_enabled(ADVICE_STATUS_HINTS))
     ++		if ((advice_flags & BRANCH_MODE_PUSH) &&
     ++		    advice_enabled(ADVICE_STATUS_HINTS))
     + 			strbuf_addf(sb, _("  (use \"%s\" for details)\n"),
     + 				    "git status --ahead-behind");
     + 	} else if (!theirs) {
      @@ remote.c: static void format_branch_comparison(struct strbuf *sb,
       			   "Your branch is ahead of '%s' by %d commits.\n",
       			   ours),
     @@ remote.c: int format_tracking_info(struct branch *branch, struct strbuf *sb,
       			strbuf_addstr(sb,
       				_("  (use \"git branch --unset-upstream\" to fixup)\n"));
       	} else {
     --		format_branch_comparison(sb, ours, theirs, base, abf, show_divergence_advice);
     -+		format_branch_comparison(sb, ours, theirs, base, abf,
     +-		format_branch_comparison(sb, sti, ours, theirs, base, abf, show_divergence_advice);
     ++		format_branch_comparison(sb, sti, ours, theirs, base, abf,
      +					 base_branch_modes, show_divergence_advice);
      +	}
      +
      +	if (push_branch_modes & BRANCH_MODE_PUSH) {
      +		strbuf_addstr(sb, "\n");
     -+		format_branch_comparison(sb, push_ours, push_theirs, push, abf,
     ++		format_branch_comparison(sb, push_sti, push_ours, push_theirs, push, abf,
      +					 push_branch_modes, 0);
       	}
       
     @@ t/t6040-tracking-info.sh: test_expect_success '--set-upstream-to @{-1}' '
      +	test_cmp expect actual
      +'
      +
     ++test_expect_success 'status --no-ahead-behind tracking origin/main shows only main' '
     ++	(
     ++		cd test &&
     ++		git checkout b4 &&
     ++		git status --no-ahead-behind >../actual
     ++	) &&
     ++	cat >expect <<-EOF &&
     ++	On branch b4
     ++	Your branch and ${SQ}origin/main${SQ} refer to different commits.
     ++	  (use "git status --ahead-behind" for details)
     ++
     ++	nothing to commit, working tree clean
     ++	EOF
     ++	test_cmp expect actual
     ++'
     ++
      +test_expect_success 'status shows ahead of both origin/main and feature branch' '
      +	(
      +		cd test &&
     @@ t/t6040-tracking-info.sh: test_expect_success '--set-upstream-to @{-1}' '
      +	test_cmp expect actual
      +'
      +
     ++test_expect_success 'status --no-ahead-behind shows diverged from origin/main and ahead of feature branch' '
     ++	(
     ++		cd test &&
     ++		git checkout feature4 &&
     ++		git status --no-ahead-behind >../actual
     ++	) &&
     ++	cat >expect <<-EOF &&
     ++	On branch feature4
     ++	Your branch and ${SQ}origin/main${SQ} refer to different commits.
     ++
     ++	Your branch and ${SQ}origin/feature4${SQ} refer to different commits.
     ++	  (use "git status --ahead-behind" for details)
     ++
     ++	nothing to commit, working tree clean
     ++	EOF
     ++	test_cmp expect actual
     ++'
     ++
      +test_expect_success 'setup upstream remote' '
      +	(
      +		cd test &&
     @@ t/t6040-tracking-info.sh: test_expect_success '--set-upstream-to @{-1}' '
      +	test_cmp expect actual
      +'
      +
     ++test_expect_success 'status --no-ahead-behind with upstream remote and push branch up to date' '
     ++	(
     ++		cd test &&
     ++		git checkout feature7 &&
     ++		git push origin &&
     ++		git status --no-ahead-behind >../actual
     ++	) &&
     ++	cat >expect <<-EOF &&
     ++	On branch feature7
     ++	Your branch is up to date with ${SQ}upstream/main${SQ}.
     ++
     ++	Your branch is up to date with ${SQ}origin/feature7${SQ}.
     ++
     ++	nothing to commit, working tree clean
     ++	EOF
     ++	test_cmp expect actual
     ++'
     ++
      +test_expect_success 'checkout shows push branch up to date' '
      +	(
      +		cd test &&

-- 
gitgitgadget