git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jeff King <peff@peff.net>
To: Lana Deere <lana.deere@gmail.com>
Cc: "Johannes Schindelin" <Johannes.Schindelin@gmx.de>,
	"Đoàn Trần Công Danh" <congdanhqx@gmail.com>,
	git@vger.kernel.org
Subject: [PATCH 2/2] fetch: add branch.*.merge to default ref-prefix extension
Date: Thu, 8 Sep 2022 15:26:09 -0400	[thread overview]
Message-ID: <YxpB0dbFTKp5L94k@coredump.intra.peff.net> (raw)
In-Reply-To: <YxpBMaIckimFJYEi@coredump.intra.peff.net>

When running "git pull" with no arguments, we'll do a default "git
fetch" and then try to merge the branch specified by the branch.*.merge
config. There's code in get_ref_map() to treat that "merge" branch as
something we want to fetch, even if it is not otherwise covered by the
default refspec.

This works fine with the v0 protocol, as the server tells us about all
of the refs, and get_ref_map() is the ultimate decider of what we fetch.

But in the v2 protocol, we send the ref-prefix extension to the server,
asking it to limit the ref advertisement. And we only tell it about the
default refspec for the remote; we don't mention the branch.*.merge
config at all.

This usually doesn't matter, because the default refspec matches
"refs/heads/*", which covers all branches. But if you explicitly use a
narrow refspec, then "git pull" on some branches may fail. The server
doesn't advertise the branch, so we don't fetch it, and "git pull"
thinks that it went away upstream.

We can fix this by including any branch.*.merge entries for the current
branch in the list of ref-prefixes we pass to the server. This only
needs to happen when using the default configured refspec (since
command-line refspecs are already added, and take precedence in deciding
what we fetch). We don't otherwise need to replicate any of the "what to
fetch" logic in get_ref_map(). These ref-prefixes are an optimization,
so it's OK if we tell the server to advertise the branch.*.merge ref,
even if we're not going to pull it. We'll just choose not to fetch it.

The test here is based on one constructed by Johannes. I modified the
branch names to trigger the ref-prefix issue (and be more descriptive),
and to confirm that "git pull" actually updated the local ref, which
should be more robust than just checking stderr.

Reported-by: Lana Deere <lana.deere@gmail.com>
Helped-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Jeff King <peff@peff.net>
---
 builtin/fetch.c | 18 +++++++++++++++---
 t/t5520-pull.sh | 17 +++++++++++++++++
 2 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/builtin/fetch.c b/builtin/fetch.c
index f78146ca81..d4bbef6695 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -1616,9 +1616,21 @@ static int do_fetch(struct transport *transport,
 				break;
 			}
 		}
-	} else if (transport->remote->fetch.nr)
-		refspec_ref_prefixes(&transport->remote->fetch,
-				     &transport_ls_refs_options.ref_prefixes);
+	} else {
+		struct branch *branch = branch_get(NULL);
+
+		if (transport->remote->fetch.nr)
+			refspec_ref_prefixes(&transport->remote->fetch,
+					     &transport_ls_refs_options.ref_prefixes);
+		if (branch_has_merge_config(branch) &&
+		    !strcmp(branch->remote_name, transport->remote->name)) {
+			int i;
+			for (i = 0; i < branch->merge_nr; i++) {
+				strvec_push(&transport_ls_refs_options.ref_prefixes,
+					    branch->merge[i]->src);
+			}
+		}
+	}
 
 	if (tags == TAGS_SET || tags == TAGS_DEFAULT) {
 		must_list_refs = 1;
diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh
index 081808009b..0b72112fb1 100755
--- a/t/t5520-pull.sh
+++ b/t/t5520-pull.sh
@@ -218,6 +218,23 @@ test_expect_success 'fail if upstream branch does not exist' '
 	test_cmp expect file
 '
 
+test_expect_success 'fetch upstream branch even if refspec excludes it' '
+	# the branch names are not important here except that
+	# the first one must not be a prefix of the second,
+	# since otherwise the ref-prefix protocol extension
+	# would match both
+	git branch in-refspec HEAD^ &&
+	git branch not-in-refspec HEAD &&
+	git init -b in-refspec downstream &&
+	git -C downstream remote add -t in-refspec origin "file://$(pwd)/.git" &&
+	git -C downstream config branch.in-refspec.remote origin &&
+	git -C downstream config branch.in-refspec.merge refs/heads/not-in-refspec &&
+	git -C downstream pull &&
+	git rev-parse --verify not-in-refspec >expect &&
+	git -C downstream rev-parse --verify HEAD >actual &&
+	test_cmp expect actual
+'
+
 test_expect_success 'fail if the index has unresolved entries' '
 	git checkout -b third second^ &&
 	test_when_finished "git checkout -f copy && git branch -D third" &&
-- 
2.37.3.1164.gb600acaa9f

  parent reply	other threads:[~2022-09-08 19:26 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-09-02 19:27 2.37.2 can't "git pull" but 2.18.0 can Lana Deere
2022-09-02 20:16 ` brian m. carlson
2022-09-06 18:26   ` Lana Deere
2022-09-07 12:59     ` Johannes Schindelin
2022-09-07 15:59       ` Lana Deere
2022-09-08 18:20       ` Jeff King
2022-09-03  1:07 ` Jeff King
2022-09-06 19:37   ` Lana Deere
2022-09-07  2:11     ` Đoàn Trần Công Danh
2022-09-07 15:56       ` Lana Deere
2022-09-07 18:21         ` Jeff King
2022-09-07 18:53           ` Lana Deere
2022-09-07 21:10             ` Jeff King
2022-09-08 16:46               ` Lana Deere
2022-09-08 18:14                 ` Jeff King
2022-09-08 19:23                   ` [PATCH 0/2] v2 protocol can't "git pull" with restricted refspec Jeff King
2022-09-08 19:24                     ` [PATCH 1/2] fetch: stop checking for NULL transport->remote in do_fetch() Jeff King
2022-09-08 19:26                     ` Jeff King [this message]
2022-09-08 20:36                       ` [PATCH 2/2] fetch: add branch.*.merge to default ref-prefix extension Junio C Hamano
2022-09-08 20:48                         ` Junio C Hamano
2022-09-09  2:17                           ` Jeff King
2022-09-09  5:23                             ` Junio C Hamano
2022-09-11  5:08                               ` Jeff King
2022-09-09 17:32                   ` 2.37.2 can't "git pull" but 2.18.0 can Lana Deere
2022-09-09 18:27                     ` Junio C Hamano
2022-09-12 14:58                       ` Lana Deere
2022-09-13  0:28                         ` Jeff King
2022-09-05 10:25 ` Johannes Schindelin
2022-09-06 18:38   ` Lana Deere
2022-09-07 10:20     ` Johannes Schindelin
2022-09-07 16:01       ` Lana Deere

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=YxpB0dbFTKp5L94k@coredump.intra.peff.net \
    --to=peff@peff.net \
    --cc=Johannes.Schindelin@gmx.de \
    --cc=congdanhqx@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=lana.deere@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).