git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Taylor Blau <me@ttaylorr.com>
To: git@vger.kernel.org
Cc: peff@peff.net, gitster@pobox.com, sunshine@sunshineco.com,
	sbeller@google.com
Subject: [PATCH v3 3/4] transport.c: introduce core.alternateRefsCommand
Date: Thu, 27 Sep 2018 21:25:42 -0700	[thread overview]
Message-ID: <2dbcd5419073f06def007be3746ce90fffaf6a6d.1538108385.git.me@ttaylorr.com> (raw)
In-Reply-To: <cover.1538108385.git.me@ttaylorr.com>

When in a repository containing one or more alternates, Git would
sometimes like to list references from those alternates. For example,
'git receive-pack' lists the "tips" pointed to by references in those
alternates as special ".have" references.

Listing ".have" references is designed to make pushing changes from
upstream to a fork a lightweight operation, by advertising to the pusher
that the fork already has the objects (via its alternate). Thus, the
client can avoid sending them.

However, when the alternate (upstream, in the previous example) has a
pathologically large number of references, the initial advertisement is
too expensive. In fact, it can dominate any such optimization where the
pusher avoids sending certain objects.

Introduce "core.alternateRefsCommand" in order to provide a facility to
limit or filter alternate references. This can be used, for example, to
filter out references the alternate does not wish to send (for space
concerns, or otherwise) during the initial advertisement.

Let the repository that has alternates configure this command to avoid
trusting the alternate to provide us a safe command to run in the shell.
To behave differently on each alternate (e.g., only list tags from
alternate A, only heads from B) provide the path of the alternate as the
first argument.

Signed-off-by: Taylor Blau <me@ttaylorr.com>
---
 Documentation/config.txt | 11 +++++++++
 t/t5410-receive-pack.sh  | 49 ++++++++++++++++++++++++++++++++++++++++
 transport.c              | 19 ++++++++++++----
 3 files changed, 75 insertions(+), 4 deletions(-)
 create mode 100755 t/t5410-receive-pack.sh

diff --git a/Documentation/config.txt b/Documentation/config.txt
index ad0f4510c3..afcb18331a 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -616,6 +616,17 @@ core.preferSymlinkRefs::
 	This is sometimes needed to work with old scripts that
 	expect HEAD to be a symbolic link.
 
+core.alternateRefsCommand::
+	When advertising tips of available history from an alternate, use the shell to
+	execute the specified command instead of linkgit:git-for-each-ref[1]. The
+	first argument is the absolute path of the alternate. Output must be of the
+	form: `%(objectname)`, where multiple tips are separated by newlines.
++
+This is useful when a repository only wishes to advertise some of its
+alternate's references as ".have"'s. For example, to only advertise branch
+heads, configure `core.alternateRefsCommand` to the path of a script which runs
+`git --git-dir="$1" for-each-ref --format='%(objectname)' refs/heads`.
+
 core.bare::
 	If true this repository is assumed to be 'bare' and has no
 	working directory associated with it.  If this is the case a
diff --git a/t/t5410-receive-pack.sh b/t/t5410-receive-pack.sh
new file mode 100755
index 0000000000..503dde35a4
--- /dev/null
+++ b/t/t5410-receive-pack.sh
@@ -0,0 +1,49 @@
+#!/bin/sh
+
+test_description='git receive-pack test'
+
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+	test_commit one &&
+	git update-ref refs/heads/a HEAD &&
+	test_commit two &&
+	git update-ref refs/heads/b HEAD &&
+	test_commit three &&
+	git update-ref refs/heads/c HEAD &&
+	git clone --bare . fork &&
+	git clone fork pusher &&
+	(
+		cd fork &&
+		git update-ref --stdin <<-\EOF &&
+		delete refs/heads/a
+		delete refs/heads/b
+		delete refs/heads/c
+		delete refs/heads/master
+		delete refs/tags/one
+		delete refs/tags/two
+		delete refs/tags/three
+		EOF
+		echo "../../.git/objects" >objects/info/alternates
+	)
+'
+
+extract_haves () {
+	depacketize | perl -lne '/^(\S+) \.have/ and print $1'
+}
+
+test_expect_success 'with core.alternateRefsCommand' '
+	write_script fork/alternate-refs <<-\EOF &&
+		git --git-dir="$1" for-each-ref \
+			--format="%(objectname)" \
+			refs/heads/a \
+			refs/heads/c
+	EOF
+	test_config -C fork core.alternateRefsCommand alternate-refs &&
+	git rev-parse a c >expect &&
+	printf "0000" | git receive-pack fork >actual &&
+	extract_haves <actual >actual.haves &&
+	test_cmp expect actual.haves
+'
+
+test_done
diff --git a/transport.c b/transport.c
index 2825debac5..e271b66603 100644
--- a/transport.c
+++ b/transport.c
@@ -1328,10 +1328,21 @@ char *transport_anonymize_url(const char *url)
 static void fill_alternate_refs_command(struct child_process *cmd,
 					const char *repo_path)
 {
-	cmd->git_cmd = 1;
-	argv_array_pushf(&cmd->args, "--git-dir=%s", repo_path);
-	argv_array_push(&cmd->args, "for-each-ref");
-	argv_array_push(&cmd->args, "--format=%(objectname)");
+	const char *value;
+
+	if (!git_config_get_value("core.alternateRefsCommand", &value)) {
+		cmd->use_shell = 1;
+
+		argv_array_push(&cmd->args, value);
+		argv_array_push(&cmd->args, repo_path);
+	} else {
+		cmd->git_cmd = 1;
+
+		argv_array_pushf(&cmd->args, "--git-dir=%s", repo_path);
+		argv_array_push(&cmd->args, "for-each-ref");
+		argv_array_push(&cmd->args, "--format=%(objectname)");
+	}
+
 	cmd->env = local_repo_env;
 	cmd->out = -1;
 }
-- 
2.19.0.221.g150f307af


  parent reply	other threads:[~2018-09-28  4:25 UTC|newest]

Thread overview: 94+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-09-20 18:04 [PATCH 0/3] Filter alternate references Taylor Blau
2018-09-20 18:04 ` [PATCH 1/3] transport.c: extract 'fill_alternate_refs_command' Taylor Blau
2018-09-20 18:04 ` [PATCH 2/3] transport.c: introduce core.alternateRefsCommand Taylor Blau
2018-09-20 19:37   ` Jeff King
2018-09-20 20:00     ` Taylor Blau
2018-09-20 20:06       ` Jeff King
2018-09-21 16:39   ` Junio C Hamano
2018-09-21 17:48     ` Taylor Blau
2018-09-21 17:57       ` Taylor Blau
2018-09-21 19:59         ` Junio C Hamano
2018-09-26  0:56           ` Taylor Blau
2018-09-20 18:04 ` [PATCH 3/3] transport.c: introduce core.alternateRefsPrefixes Taylor Blau
2018-09-20 19:47   ` Jeff King
2018-09-20 20:12     ` Taylor Blau
2018-09-21  7:19   ` Eric Sunshine
2018-09-21 14:07     ` Taylor Blau
2018-09-21 16:45       ` Junio C Hamano
2018-09-21 17:49         ` Taylor Blau
2018-09-21 16:40     ` Junio C Hamano
2018-09-20 18:35 ` [PATCH 0/3] Filter alternate references Stefan Beller
2018-09-20 18:56   ` Taylor Blau
2018-09-20 19:27   ` Jeff King
2018-09-20 19:21 ` Jeff King
2018-09-21 18:47 ` [PATCH v2 " Taylor Blau
2018-09-21 18:47   ` [PATCH v2 1/3] transport.c: extract 'fill_alternate_refs_command' Taylor Blau
2018-09-21 18:47   ` [PATCH v2 2/3] transport.c: introduce core.alternateRefsCommand Taylor Blau
2018-09-21 20:18     ` Eric Sunshine
2018-09-26  0:59       ` Taylor Blau
2018-09-21 21:09     ` Junio C Hamano
2018-09-21 22:13       ` Jeff King
2018-09-21 22:23         ` Junio C Hamano
2018-09-21 22:27           ` Jeff King
2018-09-26  1:06       ` Taylor Blau
2018-09-26  3:21         ` Jeff King
2018-09-21 21:10     ` Eric Sunshine
2018-09-22 18:02     ` brian m. carlson
2018-09-22 19:52       ` Jeff King
2018-09-23 14:53         ` brian m. carlson
2018-09-26  1:09         ` Taylor Blau
2018-09-26  3:33           ` Jeff King
2018-09-26 13:39             ` Taylor Blau
2018-09-26 18:38               ` Jeff King
2018-09-28  2:39                 ` Taylor Blau
2018-09-21 18:47   ` [PATCH v2 3/3] transport.c: introduce core.alternateRefsPrefixes Taylor Blau
2018-09-21 21:14     ` Junio C Hamano
2018-09-21 21:37       ` Jeff King
2018-09-21 22:06         ` Junio C Hamano
2018-09-21 22:18           ` Jeff King
2018-09-21 22:23             ` Stefan Beller
2018-09-24 15:17             ` Junio C Hamano
2018-09-24 18:10               ` Jeff King
2018-09-24 20:32                 ` Junio C Hamano
2018-09-24 20:50                   ` Jeff King
2018-09-24 21:01                     ` Jeff King
2018-09-24 21:55                     ` Junio C Hamano
2018-09-24 23:14                       ` Jeff King
2018-09-25 17:41                         ` Junio C Hamano
2018-09-25 22:46                           ` Taylor Blau
2018-09-25 23:56                             ` Junio C Hamano
2018-09-26  1:18                               ` Taylor Blau
2018-09-26  3:16                               ` Jeff King
2018-09-28  4:25 ` [PATCH v3 0/4] Filter alternate references Taylor Blau
2018-09-28  4:25   ` [PATCH v3 1/4] transport: drop refnames from for_each_alternate_ref Jeff King
2018-09-28  4:58     ` Jeff King
2018-09-28 14:21       ` Taylor Blau
2018-09-28  4:25   ` [PATCH v3 2/4] transport.c: extract 'fill_alternate_refs_command' Taylor Blau
2018-09-28  4:59     ` Jeff King
2018-09-28  4:25   ` Taylor Blau [this message]
2018-09-28  5:26     ` [PATCH v3 3/4] transport.c: introduce core.alternateRefsCommand Jeff King
2018-09-28 22:04       ` Taylor Blau
2018-09-29  7:31         ` Jeff King
2018-10-02  1:56           ` Taylor Blau
2018-09-28  4:25   ` [PATCH v3 4/4] transport.c: introduce core.alternateRefsPrefixes Taylor Blau
2018-09-28  5:30     ` Jeff King
2018-09-28 22:05       ` Taylor Blau
2018-09-29  7:34         ` Jeff King
2018-10-02  1:57           ` Taylor Blau
2018-10-02  2:00             ` Taylor Blau
2018-10-02  2:23 ` [PATCH v4 0/4] Filter alternate references Taylor Blau
2018-10-02  2:23   ` [PATCH v4 1/4] transport: drop refnames from for_each_alternate_ref Taylor Blau
2018-10-02  2:23   ` [PATCH v4 2/4] transport.c: extract 'fill_alternate_refs_command' Taylor Blau
2018-10-02  2:23   ` [PATCH v4 3/4] transport.c: introduce core.alternateRefsCommand Taylor Blau
2018-10-02 23:40     ` Jeff King
2018-10-04  2:17       ` Taylor Blau
2018-10-02  2:24   ` [PATCH v4 4/4] transport.c: introduce core.alternateRefsPrefixes Taylor Blau
2018-10-02 15:13     ` Ramsay Jones
2018-10-02 23:28       ` Taylor Blau
2018-10-08 18:09 ` [PATCH v5 0/4] Filter alternate references Taylor Blau
2018-10-08 18:09   ` [PATCH v5 1/4] transport: drop refnames from for_each_alternate_ref Taylor Blau
2018-10-08 18:09   ` [PATCH v5 2/4] transport.c: extract 'fill_alternate_refs_command' Taylor Blau
2018-10-08 18:09   ` [PATCH v5 3/4] transport.c: introduce core.alternateRefsCommand Taylor Blau
2018-10-08 18:09   ` [PATCH v5 4/4] transport.c: introduce core.alternateRefsPrefixes Taylor Blau
2018-10-09  3:09   ` [PATCH v5 0/4] Filter alternate references Jeff King
2018-10-09 14:49     ` Taylor Blau

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

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2dbcd5419073f06def007be3746ce90fffaf6a6d.1538108385.git.me@ttaylorr.com \
    --to=me@ttaylorr.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=peff@peff.net \
    --cc=sbeller@google.com \
    --cc=sunshine@sunshineco.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.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

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 read-only IMAP folder(s) and NNTP newsgroup(s).