All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Harald Nordgren via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: "D. Ben Knoble" <ben.knoble@gmail.com>,
	Harald Nordgren <haraldnordgren@gmail.com>,
	Harald Nordgren <haraldnordgren@gmail.com>
Subject: [PATCH v2 2/2] remote: resolve "simple" @{push} when pushing to another remote
Date: Sat, 31 Oct 2026 08:04:01 +0000	[thread overview]
Message-ID: <c58afcc4b166d33489feee41d57e65738581a0da.1793433841.git.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.2466.v2.git.git.1793433841.gitgitgadget@gmail.com>

From: Harald Nordgren <haraldnordgren@gmail.com>

With push.default left at "simple", a branch whose upstream is on one
remote and whose push remote is another gets pushed by "git push" to a
branch of the same name on the push remote. But @{push} for that
branch fails with "cannot resolve 'simple' push to a single
destination". As a result "git status" shows the "git push" hint under
the comparison with the upstream, even though "git push" goes
elsewhere, and leaves out the comparison with the push branch when
status.compareBranches asks for it.

"git push" learned to handle "simple" this way in ed2b18292b (push:
change `simple` to accommodate triangular workflows, 2013-06-19). When
@{push} was added in e291c75a95 (remote.c: add branch_get_push,
2015-05-21), its "simple" case only covered pushing back to the remote
the branch is fetched from, where the upstream must have the same name.

Make @{push} follow "git push". When the push remote is not the remote
of the branch, resolve to the branch of the same name on the push
remote, as "current" does.

The test added in 9bf9eed093 (remote: fix leak in branch_get_push_1()
with invalid "simple" config, 2026-01-19) relied on a different push
remote being invalid for "simple". Use an upstream with a different
name on the same remote instead, so that it still exercises the error
path.

Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
---
 remote.c                  | 13 ++++++++-----
 t/for-each-ref-tests.sh   |  4 +++-
 t/t1514-rev-parse-push.sh | 13 ++++++++++++-
 3 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/remote.c b/remote.c
index d15d34aad7..98665a3085 100644
--- a/remote.c
+++ b/remote.c
@@ -1972,16 +1972,19 @@ static char *branch_get_push_simple(struct repository *repo,
 				    struct branch *branch,
 				    struct strbuf *err)
 {
-	const char *up;
+	const char *up = NULL;
 	char *cur;
 
-	up = branch_get_upstream(branch, err);
-	if (!up)
-		return NULL;
+	if (!strcmp(remote->name,
+		    remotes_remote_for_branch(repo->remote_state, branch, NULL))) {
+		up = branch_get_upstream(branch, err);
+		if (!up)
+			return NULL;
+	}
 	cur = tracking_for_push_dest(repo, remote, branch->refname, err);
 	if (!cur)
 		return NULL;
-	if (strcmp(cur, up)) {
+	if (up && strcmp(cur, up)) {
 		free(cur);
 		return error_buf(err,
 				 _("cannot resolve 'simple' push to a single destination"));
diff --git a/t/for-each-ref-tests.sh b/t/for-each-ref-tests.sh
index b1a10dd933..4991a82b91 100644
--- a/t/for-each-ref-tests.sh
+++ b/t/for-each-ref-tests.sh
@@ -1745,9 +1745,11 @@ test_expect_success ':remotename and :remoteref' '
 '
 
 test_expect_success '%(push) with an invalid push-simple config' '
+	test_when_finished "git config branch.main.merge refs/heads/main" &&
+	git config branch.main.merge refs/heads/not-main &&
 	echo "refs/heads/main " >expect &&
 	git -c push.default=simple \
-	    -c remote.pushdefault=myfork \
+	    -c remote.pushdefault=origin \
 	    for-each-ref \
 	    --format="%(refname) %(push)" refs/heads/main >actual &&
 	test_cmp expect actual
diff --git a/t/t1514-rev-parse-push.sh b/t/t1514-rev-parse-push.sh
index 5a4f16867a..dc2df7eb80 100755
--- a/t/t1514-rev-parse-push.sh
+++ b/t/t1514-rev-parse-push.sh
@@ -39,7 +39,7 @@ test_expect_success '@{push} with default=simple' '
 	resolve main@{pUSh} refs/remotes/origin/main
 '
 
-test_expect_success 'triangular @{push} fails with default=simple' '
+test_expect_success '@{push} with default=simple fails when upstream has a different name' '
 	test_config push.default simple &&
 	test_must_fail git rev-parse topic@{push}
 '
@@ -60,6 +60,17 @@ test_expect_success '@{push} with pushremote defined' '
 	resolve topic@{push} refs/remotes/other/topic
 '
 
+test_expect_success 'triangular @{push} with default=simple and remote.pushdefault' '
+	test_config push.default simple &&
+	test_config remote.pushdefault other &&
+	test_when_finished "git checkout main" &&
+	git checkout topic &&
+	test_commit simple-triangular &&
+	git push &&
+	resolve topic@{push} refs/remotes/other/topic &&
+	test_cmp_rev topic topic@{push}
+'
+
 test_expect_success '@{p} is short for @{push}' '
 	test_config push.default current &&
 	test_config branch.topic.pushremote other &&
-- 
gitgitgadget

      parent reply	other threads:[~2026-10-31  8:04 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-27 12:43 [PATCH] remote: resolve "simple" @{push} when pushing to another remote Harald Nordgren via GitGitGadget
2026-10-28 22:24 ` D. Ben Knoble
2026-10-29 10:34   ` Harald Nordgren
2026-10-29 17:48   ` Junio C Hamano
2026-10-29 22:15     ` Harald Nordgren
2026-10-31  8:03 ` [PATCH v2 0/2] " Harald Nordgren via GitGitGadget
2026-10-31  8:04   ` [PATCH v2 1/2] remote: move "simple" @{push} resolution into a helper Harald Nordgren via GitGitGadget
2026-10-31  8:04   ` Harald Nordgren via GitGitGadget [this message]

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=c58afcc4b166d33489feee41d57e65738581a0da.1793433841.git.gitgitgadget@gmail.com \
    --to=gitgitgadget@gmail.com \
    --cc=ben.knoble@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=haraldnordgren@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.