The recently-introduced "core.alternateRefsCommand" allows callers to
specify with high flexibility the tips that they wish to advertise from
alternates. This flexibility comes at the cost of some inconvenience
when the caller only wishes to limit the advertisement to one or more
prefixes.

For example, to advertise only tags, a caller using
'core.alternateRefsCommand' would have to do:

  $ git config core.alternateRefsCommand ' \
      git -C "$1" for-each-ref refs/tags \
      --format="%(objectname) %(refname)" \
    '

The above is cumbersome to write, so let's introduce a
"core.alternateRefsPrefixes" to address this common case. Instead, the
caller can run:

  $ git config core.alternateRefsPrefixes 'refs/tags'

Which will behave identically to the longer example using
"core.alternateRefsCommand".

Since the value of "core.alternateRefsPrefixes" is appended to 'git
for-each-ref' and then executed, include a "--" before taking the
configured value to avoid misinterpreting arguments as flags to 'git
for-each-ref'.

In the case that the caller wishes to specify multiple prefixes, they
may separate them by whitespace. If "core.alternateRefsCommand" is set,
it will take precedence over "core.alternateRefsPrefixes".

Signed-off-by: Taylor Blau <m...@ttaylorr.com>
---
 Documentation/config.txt | 7 +++++++
 t/t5410-receive-pack.sh  | 8 ++++++++
 transport.c              | 5 +++++
 3 files changed, 20 insertions(+)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index 526557e494..7df6c22925 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -627,6 +627,13 @@ 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 refs/heads`.
 
+core.alternateRefsPrefixes::
+       When listing references from an alternate, list only references that 
begin
+       with the given prefix. Prefixes match as if they were given as 
arguments to
+       linkgit:git-for-each-ref[1]. To list multiple prefixes, separate them 
with
+       whitespace. If `core.alternateRefsCommand` is set, setting
+       `core.alternateRefsPrefixes` has no effect.
+
 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
index 2f21f1cb8f..b656c9b30c 100755
--- a/t/t5410-receive-pack.sh
+++ b/t/t5410-receive-pack.sh
@@ -51,4 +51,12 @@ test_expect_success 'with core.alternateRefsCommand' '
        test_cmp expect actual.haves
 '
 
+test_expect_success 'with core.alternateRefsPrefixes' '
+       test_config -C fork core.alternateRefsPrefixes "refs/tags" &&
+       expect_haves one three two >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 e7d2cdf00b..9323e5c3cd 100644
--- a/transport.c
+++ b/transport.c
@@ -1341,6 +1341,11 @@ static void fill_alternate_refs_command(struct 
child_process *cmd,
                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) 
%(refname)");
+
+               if (!git_config_get_value("core.alternateRefsPrefixes", 
&value)) {
+                       argv_array_push(&cmd->args, "--");
+                       argv_array_split(&cmd->args, value);
+               }
        }
 
        cmd->env = local_repo_env;
-- 
2.19.0.221.g150f307af

Reply via email to