git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v11] status: show comparison with push remote tracking branch

From
Harald Nordgren via GitGitGadget <gitgitgadget@gmail.com>
Date
Jan 2, 2026, 11:17 UTC
Message-ID
<pull.2138.v11.git.git.1767352663477.gitgitgadget@gmail.com>
In-Reply-To
<pull.2138.v10.git.git.1767110888.gitgitgadget@gmail.com>
From: Harald Nordgren <haraldnordgren@gmail.com>

"git status" on a branch that follows a remote branch compares commits on the current branch and the remote-tracking branch it builds upon, to show "ahead", "behind", or "diverged" status.

When working on a feature branch that tracks a remote feature branch, but you also want to track progress relative to the push remote's tracking branch (which may differ from the upstream branch), git status now shows an additional comparison.

When a push remote is configured (via branch.<name>.pushRemote or
remote.pushDefault), git status shows both the comparison with the
upstream tracking branch (as before) and an additional comparison with
the push remote's tracking branch, if it differs from the upstream
tracking branch. The push branch comparison appears on a separate
line after the upstream branch status, using the same format:
- "Ahead of 'origin/feature' by N commits" when purely ahead
- "Behind 'origin/feature' by N commits" when purely behind
- "Diverged from 'origin/feature' by N commits" when diverged
Example output when tracking upstream/main with pushRemote set to origin:
    On branch feature
    Your branch is ahead of 'upstream/main' by 2 commits.
      (use "git pull" if you want to integrate the remote branch with yours)
    Ahead of 'origin/feature' by 5 commits.

The comparison is only shown when a push remote is configured and the push remote's tracking branch differs from the upstream tracking branch.

Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
---
    status: show comparison with push remote tracking branch
    
    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
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-2138%2FHaraldNordgren%2Fahead_of_main_status-v11
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-2138/HaraldNordgren/ahead_of_main_status-v11
Pull-Request: https://github.com/git/git/pull/2138
Range-diff vs v10:
 1:  43a75944fb ! 1:  53bb1cb6bb status: show comparison with configured goal branch
     @@ Metadata
      Author: Harald Nordgren <haraldnordgren@gmail.com>
      
       ## Commit message ##
     -    status: show comparison with configured goal branch
     +    status: show comparison with push remote tracking branch
      
          "git status" on a branch that follows a remote branch compares
          commits on the current branch and the remote-tracking branch it
          builds upon, to show "ahead", "behind", or "diverged" status.
      
          When working on a feature branch that tracks a remote feature branch,
     -    but you also want to track progress relative to a goal branch (e.g.,
     -    upstream/main), you can configure status.goalBranch to show an
     -    additional comparison.
     +    but you also want to track progress relative to the push remote's
     +    tracking branch (which may differ from the upstream branch), git status
     +    now shows an additional comparison.
      
     -    Add support for status.goalBranch configuration option that specifies
     -    a remote/branch to compare against. When set, git status shows both
     -    the comparison with the tracking branch (as before) and an additional
     -    comparison with the configured goal branch, if it differs from the
     -    tracking branch. The goal branch comparison appears on a separate
     -    line after the tracking branch status, using the same format:
     -    - "Ahead of 'upstream/main' by N commits" when purely ahead
     -    - "Behind 'upstream/main' by N commits" when purely behind
     -    - "Diverged from 'upstream/main' by N commits" when diverged
     +    When a push remote is configured (via branch.<name>.pushRemote or
     +    remote.pushDefault), git status shows both the comparison with the
     +    upstream tracking branch (as before) and an additional comparison with
     +    the push remote's tracking branch, if it differs from the upstream
     +    tracking branch. The push branch comparison appears on a separate
     +    line after the upstream branch status, using the same format:
     +    - "Ahead of 'origin/feature' by N commits" when purely ahead
     +    - "Behind 'origin/feature' by N commits" when purely behind
     +    - "Diverged from 'origin/feature' by N commits" when diverged
      
     -    Example output when tracking a feature branch with status.goalBranch
     -    set to upstream/main:
     +    Example output when tracking upstream/main with pushRemote set to origin:
              On branch feature
     -        Your branch is ahead of 'origin/feature' by 2 commits.
     -          (use "git push" to publish your local commits)
     +        Your branch is ahead of 'upstream/main' by 2 commits.
     +          (use "git pull" if you want to integrate the remote branch with yours)
      
     -        Ahead of 'upstream/main' by 5 commits.
     +        Ahead of 'origin/feature' by 5 commits.
      
     -    The comparison is only shown when status.goalBranch is configured
     -    and the goal branch differs from the tracking branch.
     +    The comparison is only shown when a push remote is configured and the
     +    push remote's tracking branch differs from the upstream tracking branch.
      
          Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
      
     @@ remote.c: int stat_tracking_info(struct branch *branch, int *num_ours, int *num_
       	return stat_branch_pair(branch->refname, base, num_ours, num_theirs, abf);
       }
       
     -+static char *get_goal_branch_ref(char **full_ref_out)
     ++static char *get_remote_push_branch(struct branch *branch, char **full_ref_out)
      +{
     -+	const char *config_value;
     ++	const char *push_remote;
      +	const char *resolved;
      +	int flag;
      +	struct strbuf ref_buf = STRBUF_INIT;
     -+	char *slash_pos;
      +	char *ret = NULL;
      +
     -+	if (repo_config_get_value(the_repository, "status.goalBranch", &config_value))
     ++	if (!branch)
      +		return NULL;
      +
     -+	if (!config_value || !*config_value)
     ++	push_remote = pushremote_for_branch(branch, NULL);
     ++	if (!push_remote)
      +		return NULL;
      +
     -+	slash_pos = strchr(config_value, '/');
     -+	if (!slash_pos || slash_pos == config_value || !slash_pos[1]) {
     -+		warning(_("invalid value for status.goalBranch: '%s' (expected format: remote/branch)"),
     -+			config_value);
     -+		return NULL;
     -+	}
     -+
     -+	strbuf_addf(&ref_buf, "refs/remotes/%.*s/%s",
     -+		    (int)(slash_pos - config_value), config_value,
     -+		    slash_pos + 1);
     ++	strbuf_addf(&ref_buf, "refs/remotes/%s/%s", push_remote, branch->name);
      +
      +	resolved = refs_resolve_ref_unsafe(
      +		get_main_ref_store(the_repository),
     @@ remote.c: int stat_tracking_info(struct branch *branch, int *num_ours, int *num_
      +	return ret;
      +}
      +
     -+static void format_goal_branch_comparison(struct strbuf *sb,
     ++static void format_push_branch_comparison(struct strbuf *sb,
      +					     const char *branch_refname,
     -+					     const char *goal_full,
     -+					     const char *goal_short,
     ++					     const char *push_full,
     ++					     const char *push_short,
      +					     enum ahead_behind_flags abf)
      +{
     -+	int goal_ahead = 0, goal_behind = 0;
     ++	int push_ahead = 0, push_behind = 0;
     ++	int stat_result;
      +
     -+	if (stat_branch_pair(branch_refname, goal_full,
     -+			     &goal_ahead, &goal_behind, abf) <= 0)
     ++	stat_result = stat_branch_pair(branch_refname, push_full,
     ++				       &push_ahead, &push_behind, abf);
     ++	if (stat_result < 0)
      +		return;
      +
      +	strbuf_addstr(sb, "\n");
      +
     -+	if (goal_ahead > 0 && goal_behind == 0) {
     ++	if (stat_result == 0 || (push_ahead == 0 && push_behind == 0)) {
     ++		strbuf_addf(sb,
     ++			_("Your branch is up to date with '%s'.\n"),
     ++			push_short);
     ++	} else if (push_ahead > 0 && push_behind == 0) {
      +		strbuf_addf(sb,
      +			Q_("Ahead of '%s' by %d commit.\n",
      +			   "Ahead of '%s' by %d commits.\n",
     -+			   goal_ahead),
     -+			goal_short, goal_ahead);
     -+	} else if (goal_behind > 0 && goal_ahead == 0) {
     ++			   push_ahead),
     ++			push_short, push_ahead);
     ++	} else if (push_behind > 0 && push_ahead == 0) {
      +		strbuf_addf(sb,
      +			Q_("Behind '%s' by %d commit.\n",
      +			   "Behind '%s' by %d commits.\n",
     -+			   goal_behind),
     -+			goal_short, goal_behind);
     -+	} else if (goal_ahead > 0 && goal_behind > 0) {
     ++			   push_behind),
     ++			push_short, push_behind);
     ++	} else if (push_ahead > 0 && push_behind > 0) {
      +		strbuf_addf(sb,
      +			Q_("Diverged from '%s' by %d commit.\n",
      +			   "Diverged from '%s' by %d commits.\n",
     -+			   goal_ahead + goal_behind),
     -+			goal_short, goal_ahead + goal_behind);
     ++			   push_ahead + push_behind),
     ++			push_short, push_ahead + push_behind);
      +	}
      +}
      +
     @@ remote.c: int format_tracking_info(struct branch *branch, struct strbuf *sb,
       	}
      +
      +	if (!upstream_is_gone && sti >= 0 && abf != AHEAD_BEHIND_QUICK) {
     -+		char *goal_full = NULL;
     -+		char *goal_short = get_goal_branch_ref(&goal_full);
     ++		char *push_full = NULL;
     ++		char *push_short = get_remote_push_branch(branch, &push_full);
      +
     -+		if (goal_short && strcmp(base, goal_short))
     -+			format_goal_branch_comparison(sb, branch->refname, goal_full,
     -+						     goal_short, abf);
     ++		if (push_short && strcmp(base, push_short))
     ++			format_push_branch_comparison(sb, branch->refname, push_full,
     ++						     push_short, abf);
      +
     -+		free(goal_short);
     -+		free(goal_full);
     ++		free(push_short);
     ++		free(push_full);
      +	}
      +
       	free(base);
     @@ remote.c: int format_tracking_info(struct branch *branch, struct strbuf *sb,
       }
      
       ## t/t6040-tracking-info.sh ##
     -@@ t/t6040-tracking-info.sh: test_expect_success setup '
     - 	git clone . test &&
     - 	(
     - 		cd test &&
     -+		git symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/main &&
     - 		git checkout -b b1 origin &&
     - 		git reset --hard HEAD^ &&
     - 		advance d &&
      @@ t/t6040-tracking-info.sh: test_expect_success '--set-upstream-to @{-1}' '
       	test_cmp expect actual
       '
       
     -+test_expect_success 'setup for ahead of non-main tracking branch' '
     -+	(
     -+		cd test &&
     -+		git checkout -b feature origin/main &&
     -+		advance feature1 &&
     -+		git push origin feature &&
     -+		git checkout -b work --track origin/feature &&
     -+		advance work1 &&
     -+		advance work2
     -+	)
     -+'
     -+
     -+test_expect_success 'status shows ahead of both tracked branch and origin/main' '
     ++test_expect_success 'status tracking origin/main shows only main' '
      +	(
      +		cd test &&
     -+		git checkout work >/dev/null &&
     -+		git config status.goalBranch origin/main &&
     -+		git status --long -b
     -+	) >actual &&
     -+	cat >expect <<-\EOF &&
     -+On branch work
     -+Your branch is ahead of '\''origin/feature'\'' by 2 commits.
     -+  (use "git push" to publish your local commits)
     -+
     -+Ahead of '\''origin/main'\'' by 3 commits.
     -+
     -+nothing to commit, working tree clean
     -+EOF
     ++		git checkout b4 &&
     ++		git status >../actual
     ++	) &&
     ++	cat >expect <<-EOF &&
     ++	On branch b4
     ++	Your branch is ahead of ${SQ}origin/main${SQ} by 2 commits.
     ++	  (use "git push" to publish your local commits)
     ++
     ++	nothing to commit, working tree clean
     ++	EOF
      +	test_cmp expect actual
      +'
      +
     -+test_expect_success 'checkout shows ahead of both tracked branch and origin/main' '
     ++test_expect_success 'status shows ahead of both origin/main and feature branch' '
      +	(
      +		cd test &&
     -+		git checkout main >/dev/null &&
     -+		git config status.goalBranch origin/main &&
     -+		git checkout work 2>&1
     -+	) >actual &&
     -+	cat >expect <<-\EOF &&
     -+Switched to branch '\''work'\''
     -+Your branch is ahead of '\''origin/feature'\'' by 2 commits.
     -+  (use "git push" to publish your local commits)
     -+
     -+Ahead of '\''origin/main'\'' by 3 commits.
     -+EOF
     ++		git checkout -b feature2 origin/main &&
     ++		git push origin HEAD &&
     ++		advance work &&
     ++		git status >../actual
     ++	) &&
     ++	cat >expect <<-EOF &&
     ++	On branch feature2
     ++	Your branch is ahead of ${SQ}origin/main${SQ} by 1 commit.
     ++	  (use "git push" to publish your local commits)
     ++
     ++	Ahead of ${SQ}origin/feature2${SQ} by 1 commit.
     ++
     ++	nothing to commit, working tree clean
     ++	EOF
      +	test_cmp expect actual
      +'
      +
     -+test_expect_success 'status tracking origin/main shows only main' '
     ++test_expect_success 'checkout shows ahead of both origin/main and feature branch' '
      +	(
      +		cd test &&
     -+		git checkout b4 >/dev/null &&
     -+		git status --long -b
     -+	) >actual &&
     -+	test_grep "ahead of .origin/main. by 2 commits" actual &&
     -+	test_grep ! "Ahead of" actual
     ++		git checkout feature2 >../actual
     ++	) &&
     ++	cat >expect <<-EOF &&
     ++	Your branch is ahead of ${SQ}origin/main${SQ} by 1 commit.
     ++	  (use "git push" to publish your local commits)
     ++
     ++	Ahead of ${SQ}origin/feature2${SQ} by 1 commit.
     ++	EOF
     ++	test_cmp expect actual
      +'
      +
      +test_expect_success 'setup for ahead of tracked but diverged from main' '
      +	(
      +		cd test &&
     ++		git checkout -b feature4 origin/main &&
     ++		advance work1 &&
      +		git checkout origin/main &&
     -+		git checkout -b oldfeature &&
     -+		advance oldfeature1 &&
     -+		git push origin oldfeature &&
     -+		git checkout origin/main &&
     -+		advance main_newer &&
     ++		advance work2 &&
      +		git push origin HEAD:main &&
     -+		git checkout -b work2 --track origin/oldfeature &&
     -+		advance work2_commit
     -+	)
     -+'
     -+
     -+test_expect_success 'status shows ahead of tracked and diverged from origin/main' '
     -+	(
     -+		cd test &&
     -+		git checkout work2 >/dev/null &&
     -+		git config status.goalBranch origin/main &&
     -+		git status --long -b
     -+	) >actual &&
     -+	cat >expect <<-\EOF &&
     -+On branch work2
     -+Your branch is ahead of '\''origin/oldfeature'\'' by 1 commit.
     -+  (use "git push" to publish your local commits)
     -+
     -+Diverged from '\''origin/main'\'' by 3 commits.
     -+
     -+nothing to commit, working tree clean
     -+EOF
     -+	test_cmp expect actual
     -+'
     -+
     -+test_expect_success 'setup for diverged from tracked but behind main' '
     -+	(
     -+		cd test &&
     -+		git fetch origin &&
     -+		git checkout origin/main &&
     -+		git checkout -b work2b &&
     -+		git branch --set-upstream-to=origin/oldfeature &&
     -+		git checkout origin/main &&
     -+		advance main_extra &&
     -+		git push origin HEAD:main
     -+	)
     -+'
     -+
     -+test_expect_success 'status shows diverged from tracked and behind origin/main' '
     -+	(
     -+		cd test &&
     -+		git checkout work2b >/dev/null &&
     -+		git config status.goalBranch origin/main &&
     -+		git status --long -b
     -+	) >actual &&
     -+	cat >expect <<-\EOF &&
     -+On branch work2b
     -+Your branch and '\''origin/oldfeature'\'' have diverged,
     -+and have 1 and 1 different commits each, respectively.
     -+  (use "git pull" if you want to integrate the remote branch with yours)
     -+
     -+Behind '\''origin/main'\'' by 1 commit.
     -+
     -+nothing to commit, working tree clean
     -+EOF
     -+	test_cmp expect actual
     -+'
     -+
     -+test_expect_success 'setup for behind tracked but ahead of main' '
     -+	(
     -+		cd test &&
     -+		git fetch origin &&
     -+		git checkout origin/main &&
     -+		git checkout -b feature3 &&
     -+		advance feature3_1 &&
     -+		advance feature3_2 &&
     -+		advance feature3_3 &&
     -+		git push origin feature3 &&
     -+		git checkout -b work3 --track origin/feature3 &&
     -+		git reset --hard HEAD~2
     ++		git checkout feature4 &&
     ++		advance work3
      +	)
      +'
      +
     -+test_expect_success 'status shows behind tracked and ahead of origin/main' '
     ++test_expect_success 'status shows diverged from origin/main and ahead of feature branch' '
      +	(
      +		cd test &&
     -+		git checkout work3 >/dev/null &&
     -+		git config status.goalBranch origin/main &&
     -+		git status --long -b
     -+	) >actual &&
     -+	cat >expect <<-\EOF &&
     -+On branch work3
     -+Your branch is behind '\''origin/feature3'\'' by 2 commits, and can be fast-forwarded.
     -+  (use "git pull" to update your local branch)
     -+
     -+Ahead of '\''origin/main'\'' by 1 commit.
     -+
     -+nothing to commit, working tree clean
     -+EOF
     ++		git checkout feature4 &&
     ++		git branch --set-upstream-to origin/main &&
     ++		git push origin HEAD &&
     ++		advance work &&
     ++		git status >../actual
     ++	) &&
     ++	cat >expect <<-EOF &&
     ++	On branch feature4
     ++	Your branch and ${SQ}origin/main${SQ} have diverged,
     ++	and have 3 and 1 different commits each, respectively.
     ++	  (use "git pull" if you want to integrate the remote branch with yours)
     ++
     ++	Ahead of ${SQ}origin/feature4${SQ} by 1 commit.
     ++
     ++	nothing to commit, working tree clean
     ++	EOF
      +	test_cmp expect actual
      +'
      +
     -+test_expect_success 'setup upstream remote preference' '
     ++test_expect_success 'setup upstream remote' '
      +	(
      +		cd test &&
      +		git remote add upstream ../. &&
      +		git fetch upstream &&
     -+		git symbolic-ref refs/remotes/upstream/HEAD refs/remotes/upstream/main
     ++		git config remote.pushDefault origin
      +	)
      +'
      +
     -+test_expect_success 'status prefers upstream remote over origin for comparison' '
     ++test_expect_success 'status with upstream remote and push.default set to origin' '
      +	(
      +		cd test &&
     -+		git checkout work >/dev/null &&
     -+		git config status.goalBranch upstream/main &&
     -+		git status --long -b
     -+	) >actual &&
     -+	cat >expect <<-\EOF &&
     -+On branch work
     -+Your branch is ahead of '\''origin/feature'\'' by 2 commits.
     -+  (use "git push" to publish your local commits)
     -+
     -+Diverged from '\''upstream/main'\'' by 5 commits.
     -+
     -+nothing to commit, working tree clean
     -+EOF
     ++		git checkout -b feature5 upstream/main &&
     ++		git push origin &&
     ++		advance work &&
     ++		git status >../actual
     ++	) &&
     ++	cat >expect <<-EOF &&
     ++	On branch feature5
     ++	Your branch is ahead of ${SQ}upstream/main${SQ} by 1 commit.
     ++	  (use "git push" to publish your local commits)
     ++
     ++	Ahead of ${SQ}origin/feature5${SQ} by 1 commit.
     ++
     ++	nothing to commit, working tree clean
     ++	EOF
      +	test_cmp expect actual
      +'
      +
     -+test_expect_success 'setup for up to date with tracked but ahead of default' '
     -+	(
     -+		cd test &&
     -+		git checkout origin/feature &&
     -+		git checkout -b synced_feature --track origin/feature &&
     -+		git checkout origin/main &&
     -+		advance main_ahead &&
     -+		git push origin HEAD:main
     -+	)
     -+'
     -+
     -+test_expect_success 'status shows up to date with tracked but diverged from default' '
     ++test_expect_success 'status with upstream remote and push.default set to origin and diverged' '
      +	(
      +		cd test &&
     -+		git checkout synced_feature >/dev/null &&
     -+		git config status.goalBranch upstream/main &&
     -+		git status --long -b
     -+	) >actual &&
     -+	cat >expect <<-\EOF &&
     -+On branch synced_feature
     -+Your branch is up to date with '\''origin/feature'\''.
     -+
     -+Diverged from '\''upstream/main'\'' by 3 commits.
     -+
     -+nothing to commit, working tree clean
     -+EOF
     ++		git checkout -b feature6 upstream/main &&
     ++		advance work &&
     ++		git push origin &&
     ++		git reset --hard upstream/main &&
     ++		advance work &&
     ++		git status >../actual
     ++	) &&
     ++	cat >expect <<-EOF &&
     ++	On branch feature6
     ++	Your branch is ahead of ${SQ}upstream/main${SQ} by 1 commit.
     ++	  (use "git push" to publish your local commits)
     ++
     ++	Diverged from ${SQ}origin/feature6${SQ} by 2 commits.
     ++
     ++	nothing to commit, working tree clean
     ++	EOF
      +	test_cmp expect actual
      +'
      +
     -+test_expect_success 'setup for up to date with tracked but ahead of origin/main' '
     ++test_expect_success 'status with upstream remote and push branch up to date' '
      +	(
      +		cd test &&
     -+		git remote remove upstream &&
     -+		git checkout origin/feature &&
     -+		git checkout -b synced_feature2 --track origin/feature &&
     -+		git checkout origin/main &&
     -+		advance main_ahead2 &&
     -+		git push origin HEAD:main
     -+	)
     -+'
     -+
     -+test_expect_success 'status shows up to date with tracked but diverged from origin/main' '
     -+	(
     -+		cd test &&
     -+		git checkout synced_feature2 >/dev/null &&
     -+		git config status.goalBranch origin/main &&
     -+		git status --long -b
     -+	) >actual &&
     -+	cat >expect <<-\EOF &&
     -+On branch synced_feature2
     -+Your branch is up to date with '\''origin/feature'\''.
     -+
     -+Diverged from '\''origin/main'\'' by 5 commits.
     -+
     -+nothing to commit, working tree clean
     -+EOF
     ++		git checkout -b feature7 upstream/main &&
     ++		git push origin &&
     ++		git status >../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 'setup for up to date with tracked but purely ahead of origin/main' '
     ++test_expect_success 'checkout shows push branch up to date' '
      +	(
      +		cd test &&
     -+		git checkout origin/feature &&
     -+		git checkout -b synced_feature3 --track origin/feature
     -+	)
     -+'
     ++		git checkout feature7 >../actual
     ++	) &&
     ++	cat >expect <<-EOF &&
     ++	Your branch is up to date with ${SQ}upstream/main${SQ}.
      +
     -+test_expect_success 'status shows up to date with tracked but shows default branch comparison' '
     -+	(
     -+		cd test &&
     -+		git checkout synced_feature3 >/dev/null &&
     -+		git config status.goalBranch origin/main &&
     -+		git status --long -b
     -+	) >actual &&
     -+	cat >expect <<-\EOF &&
     -+On branch synced_feature3
     -+Your branch is up to date with '\''origin/feature'\''.
     -+
     -+Diverged from '\''origin/main'\'' by 5 commits.
     -+
     -+nothing to commit, working tree clean
     -+EOF
     -+	test_cmp expect actual
     -+'
     -+
     -+test_expect_success 'status with status.goalBranch unset shows no default comparison' '
     -+	(
     -+		cd test &&
     -+		git checkout synced_feature3 >/dev/null &&
     -+		git config --unset status.goalBranch 2>/dev/null || true &&
     -+		git status --long -b
     -+	) >actual &&
     -+	cat >expect <<-\EOF &&
     -+On branch synced_feature3
     -+Your branch is up to date with '\''origin/feature'\''.
     -+
     -+nothing to commit, working tree clean
     -+EOF
     -+	test_cmp expect actual
     -+'
     -+
     -+test_expect_success 'status with status.goalBranch set uses configured branch' '
     -+	(
     -+		cd test &&
     -+		git checkout synced_feature3 >/dev/null &&
     -+		git config status.goalBranch origin/main &&
     -+		git status --long -b
     -+	) >actual &&
     -+	cat >expect <<-\EOF &&
     -+On branch synced_feature3
     -+Your branch is up to date with '\''origin/feature'\''.
     -+
     -+Diverged from '\''origin/main'\'' by 5 commits.
     -+
     -+nothing to commit, working tree clean
     -+EOF
     -+	test_cmp expect actual
     -+'
     -+
     -+test_expect_success 'status with status.goalBranch set to different remote/branch' '
     -+	(
     -+		cd test &&
     -+		git checkout work >/dev/null &&
     -+		git config status.goalBranch origin/feature &&
     -+		git status --long -b
     -+	) >actual &&
     -+	cat >expect <<-\EOF &&
     -+On branch work
     -+Your branch is ahead of '\''origin/feature'\'' by 2 commits.
     -+  (use "git push" to publish your local commits)
     -+
     -+nothing to commit, working tree clean
     -+EOF
     -+	test_cmp expect actual
     -+'
     -+
     -+test_expect_success 'status with status.goalBranch set to non-existent branch' '
     -+	(
     -+		cd test &&
     -+		git checkout synced_feature3 >/dev/null &&
     -+		git config status.goalBranch origin/nonexistent &&
     -+		git status --long -b
     -+	) >actual &&
     -+	cat >expect <<-\EOF &&
     -+On branch synced_feature3
     -+Your branch is up to date with '\''origin/feature'\''.
     -+
     -+nothing to commit, working tree clean
     -+EOF
     ++	Your branch is up to date with ${SQ}origin/feature7${SQ}.
     ++	EOF
      +	test_cmp expect actual
      +'
      +
 2:  e6d24b8b6a < -:  ---------- improve tests
 3:  13c2a03b0a < -:  ---------- use pushRemote and tracking branch
 remote.c                 |  89 +++++++++++++++++++++
 t/t6040-tracking-info.sh | 167 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 256 insertions(+)
diff --git a/remote.c b/remote.c
index 59b3715120..2317725f7d 100644
--- a/remote.c
+++ b/remote.c
@@ -2237,6 +2237,81 @@ int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs,
 	return stat_branch_pair(branch->refname, base, num_ours, num_theirs, abf);
 }
 
+static char *get_remote_push_branch(struct branch *branch, char **full_ref_out)
+{
+	const char *push_remote;
+	const char *resolved;
+	int flag;
+	struct strbuf ref_buf = STRBUF_INIT;
+	char *ret = NULL;
+
+	if (!branch)
+		return NULL;
+
+	push_remote = pushremote_for_branch(branch, NULL);
+	if (!push_remote)
+		return NULL;
+
+	strbuf_addf(&ref_buf, "refs/remotes/%s/%s", push_remote, branch->name);
+
+	resolved = refs_resolve_ref_unsafe(
+		get_main_ref_store(the_repository),
+		ref_buf.buf,
+		RESOLVE_REF_READING,
+		NULL, &flag);
+
+	if (resolved) {
+		if (full_ref_out)
+			*full_ref_out = xstrdup(resolved);
+		ret = refs_shorten_unambiguous_ref(
+			get_main_ref_store(the_repository), resolved, 0);
+	}
+
+	strbuf_release(&ref_buf);
+	return ret;
+}
+
+static void format_push_branch_comparison(struct strbuf *sb,
+					     const char *branch_refname,
+					     const char *push_full,
+					     const char *push_short,
+					     enum ahead_behind_flags abf)
+{
+	int push_ahead = 0, push_behind = 0;
+	int stat_result;
+
+	stat_result = stat_branch_pair(branch_refname, push_full,
+				       &push_ahead, &push_behind, abf);
+	if (stat_result < 0)
+		return;
+
+	strbuf_addstr(sb, "\n");
+
+	if (stat_result == 0 || (push_ahead == 0 && push_behind == 0)) {
+		strbuf_addf(sb,
+			_("Your branch is up to date with '%s'.\n"),
+			push_short);
+	} else if (push_ahead > 0 && push_behind == 0) {
+		strbuf_addf(sb,
+			Q_("Ahead of '%s' by %d commit.\n",
+			   "Ahead of '%s' by %d commits.\n",
+			   push_ahead),
+			push_short, push_ahead);
+	} else if (push_behind > 0 && push_ahead == 0) {
+		strbuf_addf(sb,
+			Q_("Behind '%s' by %d commit.\n",
+			   "Behind '%s' by %d commits.\n",
+			   push_behind),
+			push_short, push_behind);
+	} else if (push_ahead > 0 && push_behind > 0) {
+		strbuf_addf(sb,
+			Q_("Diverged from '%s' by %d commit.\n",
+			   "Diverged from '%s' by %d commits.\n",
+			   push_ahead + push_behind),
+			push_short, push_ahead + push_behind);
+	}
+}
+
 /*
  * Return true when there is anything to report, otherwise false.
  */
@@ -2258,6 +2333,7 @@ int format_tracking_info(struct branch *branch, struct strbuf *sb,
 
 	base = refs_shorten_unambiguous_ref(get_main_ref_store(the_repository),
 					    full_base, 0);
+
 	if (upstream_is_gone) {
 		strbuf_addf(sb,
 			_("Your branch is based on '%s', but the upstream is gone.\n"),
@@ -2311,6 +2387,19 @@ int format_tracking_info(struct branch *branch, struct strbuf *sb,
 			strbuf_addstr(sb,
 				_("  (use \"git pull\" if you want to integrate the remote branch with yours)\n"));
 	}
+
+	if (!upstream_is_gone && sti >= 0 && abf != AHEAD_BEHIND_QUICK) {
+		char *push_full = NULL;
+		char *push_short = get_remote_push_branch(branch, &push_full);
+
+		if (push_short && strcmp(base, push_short))
+			format_push_branch_comparison(sb, branch->refname, push_full,
+						     push_short, abf);
+
+		free(push_short);
+		free(push_full);
+	}
+
 	free(base);
 	return 1;
 }
diff --git a/t/t6040-tracking-info.sh b/t/t6040-tracking-info.sh
index 0b719bbae6..f27ae719ad 100755
--- a/t/t6040-tracking-info.sh
+++ b/t/t6040-tracking-info.sh
@@ -292,4 +292,171 @@ test_expect_success '--set-upstream-to @{-1}' '
 	test_cmp expect actual
 '
 
+test_expect_success 'status tracking origin/main shows only main' '
+	(
+		cd test &&
+		git checkout b4 &&
+		git status >../actual
+	) &&
+	cat >expect <<-EOF &&
+	On branch b4
+	Your branch is ahead of ${SQ}origin/main${SQ} by 2 commits.
+	  (use "git push" to publish your local commits)
+
+	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 &&
+		git checkout -b feature2 origin/main &&
+		git push origin HEAD &&
+		advance work &&
+		git status >../actual
+	) &&
+	cat >expect <<-EOF &&
+	On branch feature2
+	Your branch is ahead of ${SQ}origin/main${SQ} by 1 commit.
+	  (use "git push" to publish your local commits)
+
+	Ahead of ${SQ}origin/feature2${SQ} by 1 commit.
+
+	nothing to commit, working tree clean
+	EOF
+	test_cmp expect actual
+'
+
+test_expect_success 'checkout shows ahead of both origin/main and feature branch' '
+	(
+		cd test &&
+		git checkout feature2 >../actual
+	) &&
+	cat >expect <<-EOF &&
+	Your branch is ahead of ${SQ}origin/main${SQ} by 1 commit.
+	  (use "git push" to publish your local commits)
+
+	Ahead of ${SQ}origin/feature2${SQ} by 1 commit.
+	EOF
+	test_cmp expect actual
+'
+
+test_expect_success 'setup for ahead of tracked but diverged from main' '
+	(
+		cd test &&
+		git checkout -b feature4 origin/main &&
+		advance work1 &&
+		git checkout origin/main &&
+		advance work2 &&
+		git push origin HEAD:main &&
+		git checkout feature4 &&
+		advance work3
+	)
+'
+
+test_expect_success 'status shows diverged from origin/main and ahead of feature branch' '
+	(
+		cd test &&
+		git checkout feature4 &&
+		git branch --set-upstream-to origin/main &&
+		git push origin HEAD &&
+		advance work &&
+		git status >../actual
+	) &&
+	cat >expect <<-EOF &&
+	On branch feature4
+	Your branch and ${SQ}origin/main${SQ} have diverged,
+	and have 3 and 1 different commits each, respectively.
+	  (use "git pull" if you want to integrate the remote branch with yours)
+
+	Ahead of ${SQ}origin/feature4${SQ} by 1 commit.
+
+	nothing to commit, working tree clean
+	EOF
+	test_cmp expect actual
+'
+
+test_expect_success 'setup upstream remote' '
+	(
+		cd test &&
+		git remote add upstream ../. &&
+		git fetch upstream &&
+		git config remote.pushDefault origin
+	)
+'
+
+test_expect_success 'status with upstream remote and push.default set to origin' '
+	(
+		cd test &&
+		git checkout -b feature5 upstream/main &&
+		git push origin &&
+		advance work &&
+		git status >../actual
+	) &&
+	cat >expect <<-EOF &&
+	On branch feature5
+	Your branch is ahead of ${SQ}upstream/main${SQ} by 1 commit.
+	  (use "git push" to publish your local commits)
+
+	Ahead of ${SQ}origin/feature5${SQ} by 1 commit.
+
+	nothing to commit, working tree clean
+	EOF
+	test_cmp expect actual
+'
+
+test_expect_success 'status with upstream remote and push.default set to origin and diverged' '
+	(
+		cd test &&
+		git checkout -b feature6 upstream/main &&
+		advance work &&
+		git push origin &&
+		git reset --hard upstream/main &&
+		advance work &&
+		git status >../actual
+	) &&
+	cat >expect <<-EOF &&
+	On branch feature6
+	Your branch is ahead of ${SQ}upstream/main${SQ} by 1 commit.
+	  (use "git push" to publish your local commits)
+
+	Diverged from ${SQ}origin/feature6${SQ} by 2 commits.
+
+	nothing to commit, working tree clean
+	EOF
+	test_cmp expect actual
+'
+
+test_expect_success 'status with upstream remote and push branch up to date' '
+	(
+		cd test &&
+		git checkout -b feature7 upstream/main &&
+		git push origin &&
+		git status >../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 &&
+		git checkout feature7 >../actual
+	) &&
+	cat >expect <<-EOF &&
+	Your branch is up to date with ${SQ}upstream/main${SQ}.
+
+	Your branch is up to date with ${SQ}origin/feature7${SQ}.
+	EOF
+	test_cmp expect actual
+'
+
 test_done

base-commit: 68cb7f9e92a5d8e9824f5b52ac3d0a9d8f653dbe
-- 
gitgitgadget
Previous: D. Ben KnobleNext: Phillip Wood
Message 71 of 259 in “status: show default branch comparison when tracking non-default branch”
  1. status: show default branch comparison when tracking non-default branchHarald Nordgren via GitGitGadget, Dec 23, 2025
  2. Junio C HamanoDec 23, 2025
  3. Harald NordgrenDec 23, 2025
  4. Harald NordgrenDec 23, 2025
  5. Chris TorekDec 23, 2025
  6. Harald NordgrenDec 23, 2025
  7. Chris TorekDec 23, 2025
  8. Another look?Harald Nordgren, Jan 1, 2026
  9. Junio C HamanoDec 23, 2025
  10. Harald NordgrenDec 23, 2025
  11. 0/2 status: show default branch comparison when tracking non-default branchHarald Nordgren via GitGitGadget, Dec 23, 2025
  12. 1/2 status: show comparison with upstream default branchHarald Nordgren via GitGitGadget, Dec 23, 2025
  13. brian m. carlsonDec 24, 2025
  14. Junio C HamanoDec 24, 2025
  15. Another look?Harald Nordgren, Jan 1, 2026
  16. 2/2 Simplify default branch comparison logicHarald Nordgren via GitGitGadget, Dec 23, 2025
  17. Harald NordgrenDec 24, 2025
  18. 0/3 status: show default branch comparison when tracking non-default branchHarald Nordgren via GitGitGadget, Dec 24, 2025
  19. 1/3 status: show comparison with upstream default branchHarald Nordgren via GitGitGadget, Dec 24, 2025
  20. 2/3 Simplify default branch comparison logicHarald Nordgren via GitGitGadget, Dec 24, 2025
  21. 3/3 Use repo.settings.statusGoalBranch config for status comparisonHarald Nordgren via GitGitGadget, Dec 24, 2025
  22. 0/4 status: show default branch comparison when tracking non-default branchHarald Nordgren via GitGitGadget, Dec 24, 2025
  23. 1/4 status: show comparison with upstream default branchHarald Nordgren via GitGitGadget, Dec 24, 2025
  24. 2/4 Simplify default branch comparison logicHarald Nordgren via GitGitGadget, Dec 24, 2025
  25. 3/4 Use repo.settings.statusGoalBranch config for status comparisonHarald Nordgren via GitGitGadget, Dec 24, 2025
  26. 4/4 Rename default_remote to goal_branchHarald Nordgren via GitGitGadget, Dec 24, 2025
  27. 0/5 status: show default branch comparison when tracking non-default branchHarald Nordgren via GitGitGadget, Dec 24, 2025
  28. 1/5 status: show comparison with upstream default branchHarald Nordgren via GitGitGadget, Dec 24, 2025
  29. 2/5 Simplify default branch comparison logicHarald Nordgren via GitGitGadget, Dec 24, 2025
  30. 3/5 Use repo.settings.statusGoalBranch config for status comparisonHarald Nordgren via GitGitGadget, Dec 24, 2025
  31. 4/5 Rename default_remote to goal_branchHarald Nordgren via GitGitGadget, Dec 24, 2025
  32. 5/5 Add warning for malformed statusGoalBranch configHarald Nordgren via GitGitGadget, Dec 24, 2025
  33. 0/6 status: show default branch comparison when tracking non-default branchHarald Nordgren via GitGitGadget, Dec 24, 2025
  34. 1/6 status: show comparison with upstream default branchHarald Nordgren via GitGitGadget, Dec 24, 2025
  35. 2/6 Simplify default branch comparison logicHarald Nordgren via GitGitGadget, Dec 24, 2025
  36. 3/6 Use repo.settings.statusGoalBranch config for status comparisonHarald Nordgren via GitGitGadget, Dec 24, 2025
  37. 4/6 Rename default_remote to goal_branchHarald Nordgren via GitGitGadget, Dec 24, 2025
  38. 5/6 Add warning for malformed statusGoalBranch configHarald Nordgren via GitGitGadget, Dec 24, 2025
  39. 6/6 Change config key to status.compareBranchHarald Nordgren via GitGitGadget, Dec 24, 2025
  40. Junio C HamanoDec 25, 2025
  41. Harald NordgrenDec 25, 2025
  42. Junio C HamanoDec 26, 2025
  43. Harald NordgrenDec 26, 2025
  44. status: additional comparison with goal branchHarald Nordgren via GitGitGadget, Dec 25, 2025
  45. status: show comparison with configured goal branchHarald Nordgren via GitGitGadget, Dec 25, 2025
  46. Code review?Harald Nordgren, Dec 28, 2025
  47. Junio C HamanoDec 28, 2025
  48. Code review?Harald Nordgren, Dec 28, 2025
  49. Ben KnobleDec 28, 2025
  50. Triangular workflowsHarald Nordgren, Dec 29, 2025
  51. Harald NordgrenJan 1, 2026
  52. Harald NordgrenDec 30, 2025
  53. Junio C HamanoDec 28, 2025
  54. Code review?Harald Nordgren, Dec 28, 2025
  55. 0/2 status: show comparison with configured goal branchHarald Nordgren via GitGitGadget, Dec 28, 2025
  56. 1/2 status: show comparison with configured goal branchHarald Nordgren via GitGitGadget, Dec 28, 2025
  57. 2/2 improve testsHarald Nordgren via GitGitGadget, Dec 28, 2025
  58. 0/3 status: show additional comparison with push branch when different from tracking branchHarald Nordgren via GitGitGadget, Dec 30, 2025
  59. 1/3 status: show comparison with configured goal branchHarald Nordgren via GitGitGadget, Dec 30, 2025
  60. 2/3 improve testsHarald Nordgren via GitGitGadget, Dec 30, 2025
  61. 3/3 use pushRemote and tracking branchHarald Nordgren via GitGitGadget, Dec 30, 2025
  62. Junio C HamanoJan 1, 2026
  63. Another look?Harald Nordgren, Jan 1, 2026
  64. Kristoffer HaugsbakkJan 2, 2026
  65. Another look?Harald Nordgren, Jan 2, 2026
  66. Kristoffer HaugsbakkJan 12, 2026
  67. Junio C HamanoJan 4, 2026
  68. Nico WilliamsJan 4, 2026
  69. Junio C HamanoJan 4, 2026
  70. D. Ben KnobleJan 5, 2026
  71. status: show comparison with push remote tracking branchHarald Nordgren via GitGitGadget, Jan 2, 2026
  72. Phillip WoodJan 2, 2026
  73. Another look?Harald Nordgren, Jan 2, 2026
  74. Phillip WoodJan 3, 2026
  75. Another look?Harald Nordgren, Jan 3, 2026
  76. 0/2 status: show comparison with push remote tracking branchHarald Nordgren via GitGitGadget, Jan 2, 2026
  77. 1/2 refactor: format_branch_comparison in preparationHarald Nordgren via GitGitGadget, Jan 2, 2026
  78. 2/2 status: show comparison with push remote tracking branchHarald Nordgren via GitGitGadget, Jan 2, 2026
  79. 0/2 status: show comparison with push remote tracking branchHarald Nordgren via GitGitGadget, Jan 3, 2026
  80. 1/2 refactor: format_branch_comparison in preparationHarald Nordgren via GitGitGadget, Jan 3, 2026
  81. 2/2 status: show comparison with push remote tracking branchHarald Nordgren via GitGitGadget, Jan 3, 2026
  82. 0/2 status: show comparison with push remote tracking branchHarald Nordgren via GitGitGadget, Jan 3, 2026
  83. 1/2 refactor: format_branch_comparison in preparationHarald Nordgren via GitGitGadget, Jan 3, 2026
  84. Junio C HamanoJan 4, 2026
  85. Another look?Harald Nordgren, Jan 4, 2026
  86. Another look?Harald Nordgren, Jan 4, 2026
  87. Junio C HamanoJan 5, 2026
  88. 2/2 status: show comparison with push remote tracking branchHarald Nordgren via GitGitGadget, Jan 3, 2026
  89. 0/2 status: show comparison with push remote tracking branchHarald Nordgren via GitGitGadget, Jan 4, 2026
  90. 1/2 refactor format_branch_comparison in preparationHarald Nordgren via GitGitGadget, Jan 4, 2026
  91. 2/2 status: show comparison with push remote tracking branchHarald Nordgren via GitGitGadget, Jan 4, 2026
  92. 0/2 status: show comparison with push remote tracking branchHarald Nordgren via GitGitGadget, Jan 4, 2026
  93. 1/2 refactor format_branch_comparison in preparationHarald Nordgren via GitGitGadget, Jan 4, 2026
  94. Junio C HamanoJan 5, 2026
  95. Another look?Harald Nordgren, Jan 5, 2026
  96. Another look?Harald Nordgren, Jan 5, 2026
  97. Junio C HamanoJan 5, 2026
  98. Another look?Harald Nordgren, Jan 5, 2026
  99. Junio C HamanoJan 5, 2026
  100. ABQHarald Nordgren, Jan 6, 2026
  101. ABQHarald Nordgren, Jan 8, 2026
  102. 2/2 status: show comparison with push remote tracking branchHarald Nordgren via GitGitGadget, Jan 4, 2026
  103. 0/2 status: show comparison with push remote tracking branchHarald Nordgren via GitGitGadget, Jan 5, 2026
  104. 1/2 refactor format_branch_comparison in preparationHarald Nordgren via GitGitGadget, Jan 5, 2026
  105. Phillip WoodJan 9, 2026
  106. Harald NordgrenJan 9, 2026
  107. 2/2 status: show comparison with push remote tracking branchHarald Nordgren via GitGitGadget, Jan 5, 2026
  108. Phillip WoodJan 9, 2026
  109. Harald NordgrenJan 9, 2026
  110. Ben KnobleJan 9, 2026
  111. Patrick SteinhardtJan 9, 2026
  112. Harald NordgrenJan 9, 2026
  113. Phillip WoodJan 12, 2026
  114. Harald NordgrenJan 12, 2026
  115. Phillip WoodJan 13, 2026
  116. Harald NordgrenJan 13, 2026
  117. 0/2 status: show comparison with push remote tracking branchHarald Nordgren via GitGitGadget, Jan 9, 2026
  118. 1/2 refactor format_branch_comparison in preparationHarald Nordgren via GitGitGadget, Jan 9, 2026
  119. 2/2 status: show comparison with push remote tracking branchHarald Nordgren via GitGitGadget, Jan 9, 2026
  120. 0/2 status: show comparison with push remote tracking branchHarald Nordgren via GitGitGadget, Jan 9, 2026
  121. 1/2 refactor format_branch_comparison in preparationHarald Nordgren via GitGitGadget, Jan 9, 2026
  122. Junio C HamanoJan 10, 2026
  123. 2/2 status: show comparison with push remote tracking branchHarald Nordgren via GitGitGadget, Jan 9, 2026
  124. Junio C HamanoJan 10, 2026
  125. Harald NordgrenJan 10, 2026
  126. Junio C HamanoJan 10, 2026
  127. Junio C HamanoJan 10, 2026
  128. Harald NordgrenJan 10, 2026
  129. Harald NordgrenJan 10, 2026
  130. Junio C HamanoJan 10, 2026
  131. Harald NordgrenJan 10, 2026
  132. Junio C HamanoJan 11, 2026
  133. 0/2 status: show comparison with push remote tracking branchHarald Nordgren via GitGitGadget, Jan 10, 2026
  134. 1/2 refactor format_branch_comparison in preparationHarald Nordgren via GitGitGadget, Jan 10, 2026
  135. 2/2 status: show comparison with push remote tracking branchHarald Nordgren via GitGitGadget, Jan 10, 2026
  136. 0/2 status: show comparison with push remote tracking branchHarald Nordgren via GitGitGadget, Jan 10, 2026
  137. 1/2 refactor format_branch_comparison in preparationHarald Nordgren via GitGitGadget, Jan 10, 2026
  138. 2/2 status: show comparison with push remote tracking branchHarald Nordgren via GitGitGadget, Jan 10, 2026
  139. 0/2 status: show comparison with push remote tracking branchHarald Nordgren via GitGitGadget, Jan 10, 2026
  140. 1/2 refactor format_branch_comparison in preparationHarald Nordgren via GitGitGadget, Jan 10, 2026
  141. 2/2 status: show comparison with push remote tracking branchHarald Nordgren via GitGitGadget, Jan 10, 2026
  142. 0/2 status: show comparison with push remote tracking branchHarald Nordgren via GitGitGadget, Jan 12, 2026
  143. 1/2 refactor format_branch_comparison in preparationHarald Nordgren via GitGitGadget, Jan 12, 2026
  144. 2/2 status: show comparison with push remote tracking branchHarald Nordgren via GitGitGadget, Jan 12, 2026
  145. Junio C HamanoJan 12, 2026
  146. Harald NordgrenJan 13, 2026
  147. 0/2 status: show comparison with push remote tracking branchHarald Nordgren via GitGitGadget, Jan 13, 2026
  148. 1/2 refactor format_branch_comparison in preparationHarald Nordgren via GitGitGadget, Jan 13, 2026
  149. 2/2 status: show comparison with push remote tracking branchHarald Nordgren via GitGitGadget, Jan 13, 2026
  150. 0/2 status: show comparison with push remote tracking branchHarald Nordgren via GitGitGadget, Jan 13, 2026
  151. 1/2 refactor format_branch_comparison in preparationHarald Nordgren via GitGitGadget, Jan 13, 2026
  152. 2/2 status: show comparison with push remote tracking branchHarald Nordgren via GitGitGadget, Jan 13, 2026
  153. Jeff KingJan 13, 2026
  154. Triangular workflowHarald Nordgren, Jan 13, 2026
  155. Jeff KingJan 13, 2026
  156. Triangular workflowHarald Nordgren, Jan 13, 2026
  157. D. Ben KnobleJan 14, 2026
  158. Triangular workflowHarald Nordgren, Jan 14, 2026
  159. Ben KnobleJan 14, 2026
  160. Jeff KingJan 14, 2026
  161. Triangular workflowHarald Nordgren, Jan 14, 2026
  162. Jeff KingJan 14, 2026
  163. Triangular workflowHarald Nordgren, Jan 14, 2026
  164. Jeff KingJan 14, 2026
  165. Ben KnobleJan 14, 2026
  166. Jeff KingJan 14, 2026
  167. D. Ben KnobleJan 15, 2026
  168. Junio C HamanoJan 14, 2026
  169. Junio C HamanoJan 14, 2026
  170. Jeff KingJan 14, 2026
  171. Ben KnobleJan 14, 2026
  172. Triangular workflowHarald Nordgren, Jan 14, 2026
  173. Chris TorekJan 19, 2026
  174. Triangular workflowHarald Nordgren, Jan 20, 2026
  175. Triangular workflowHarald Nordgren, Jan 14, 2026
  176. Junio C HamanoJan 14, 2026
  177. Triangular workflowHarald Nordgren, Jan 18, 2026
  178. Phillip WoodJan 15, 2026
  179. Junio C HamanoJan 15, 2026
  180. Jeff KingJan 15, 2026
  181. 0/2 status: add status.compareBranches config for multiple branch comparisonsHarald Nordgren via GitGitGadget, Jan 18, 2026
  182. 1/2 refactor format_branch_comparison in preparationHarald Nordgren via GitGitGadget, Jan 18, 2026
  183. 2/2 status: add status.compareBranches config for multiple branch comparisonsHarald Nordgren via GitGitGadget, Jan 18, 2026
  184. Jeff KingJan 19, 2026
  185. Memory leakHarald Nordgren, Jan 20, 2026
  186. Memory leakHarald Nordgren, Jan 20, 2026
  187. Junio C HamanoJan 20, 2026
  188. Junio C HamanoJan 21, 2026
  189. Jeff KingJan 21, 2026
  190. Memory leakHarald Nordgren, Jan 22, 2026
  191. Junio C HamanoJan 22, 2026
  192. 0/2 status: add status.compareBranches config for multiple branch comparisonsHarald Nordgren via GitGitGadget, Jan 22, 2026
  193. 1/2 refactor format_branch_comparison in preparationHarald Nordgren via GitGitGadget, Jan 22, 2026
  194. 2/2 status: add status.compareBranches config for multiple branch comparisonsHarald Nordgren via GitGitGadget, Jan 22, 2026
  195. Jeff KingJan 22, 2026
  196. Harald NordgrenJan 22, 2026
  197. Junio C HamanoJan 22, 2026
  198. Junio C HamanoJan 22, 2026
  199. Harald NordgrenJan 22, 2026
  200. Junio C HamanoJan 22, 2026
  201. Junio C HamanoJan 22, 2026
  202. Jeff KingJan 22, 2026
  203. Jeff KingJan 22, 2026
  204. Jeff KingJan 22, 2026
  205. Harald NordgrenJan 24, 2026
  206. Junio C HamanoJan 25, 2026
  207. Harald NordgrenFeb 8, 2026
  208. Junio C HamanoJan 22, 2026
  209. Junio C HamanoJan 22, 2026
  210. Harald NordgrenJan 22, 2026
  211. Junio C HamanoJan 22, 2026
  212. Harald NordgrenJan 22, 2026
  213. 0/2 status: add status.compareBranches config for multiple branch comparisonsHarald Nordgren via GitGitGadget, Jan 22, 2026
  214. 1/2 refactor format_branch_comparison in preparationHarald Nordgren via GitGitGadget, Jan 22, 2026
  215. 2/2 status: add status.compareBranches config for multiple branch comparisonsHarald Nordgren via GitGitGadget, Jan 22, 2026
  216. Harald NordgrenFeb 21, 2026
  217. Junio C HamanoFeb 21, 2026
  218. D. Ben KnobleFeb 22, 2026
  219. Jeff KingFeb 23, 2026
  220. Harald NordgrenFeb 24, 2026
  221. Junio C HamanoFeb 24, 2026
  222. Harald NordgrenFeb 25, 2026
  223. Junio C HamanoFeb 25, 2026
  224. Jeff KingFeb 25, 2026
  225. Junio C HamanoFeb 25, 2026
  226. Harald NordgrenFeb 26, 2026
  227. D. Ben KnobleFeb 25, 2026
  228. 0/2 status: add status.compareBranches config for multiple branch comparisonsHarald Nordgren via GitGitGadget, Feb 25, 2026
  229. 1/2 refactor format_branch_comparison in preparationHarald Nordgren via GitGitGadget, Feb 25, 2026
  230. 2/2 status: add status.compareBranches config for multiple branch comparisonsHarald Nordgren via GitGitGadget, Feb 25, 2026
  231. Junio C HamanoFeb 25, 2026
  232. Harald NordgrenFeb 26, 2026
  233. 0/2 status: add status.compareBranches config for multiple branch comparisonsHarald Nordgren via GitGitGadget, Feb 26, 2026
  234. 1/2 refactor format_branch_comparison in preparationHarald Nordgren via GitGitGadget, Feb 26, 2026
  235. 2/2 status: add status.compareBranches config for multiple branch comparisonsHarald Nordgren via GitGitGadget, Feb 26, 2026
  236. Junio C HamanoMar 2, 2026
  237. Harald NordgrenMar 4, 2026
  238. Junio C HamanoFeb 26, 2026
  239. Harald NordgrenMar 1, 2026
  240. Kristoffer HaugsbakkMar 1, 2026
  241. Junio C HamanoMar 2, 2026
  242. 0/2 status: add status.compareBranches config for multiple branch comparisonsHarald Nordgren via GitGitGadget, Mar 4, 2026
  243. 1/2 refactor format_branch_comparison in preparationHarald Nordgren via GitGitGadget, Mar 4, 2026
  244. 2/2 status: add status.compareBranches config for multiple branch comparisonsHarald Nordgren via GitGitGadget, Mar 4, 2026
  245. Junio C HamanoMar 4, 2026
  246. Harald NordgrenMar 9, 2026
  247. Junio C HamanoMar 9, 2026
  248. Junio C HamanoJan 10, 2026
  249. Harald NordgrenJan 10, 2026
  250. Kristoffer HaugsbakkJan 12, 2026
  251. Yee Cheng ChinDec 23, 2025
  252. Harald NordgrenDec 23, 2025
  253. Yee Cheng ChinDec 24, 2025
  254. Junio C HamanoDec 24, 2025
  255. Yee Cheng ChinDec 24, 2025
  256. Junio C HamanoDec 24, 2025
  257. Harald NordgrenDec 24, 2025
  258. Another look?Harald Nordgren, Jan 1, 2026
  259. Harald NordgrenDec 24, 2025

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.