mirror of
https://github.com/git/git.git
synced 2024-11-01 06:47:52 +01:00
ls-remote: pass ref prefixes when requesting a remote's refs
Construct an argv_array of ref prefixes based on the patterns supplied via the command line and pass them to 'transport_get_remote_refs()' to be used when communicating protocol v2 so that the server can limit the ref advertisement based on those prefixes. Signed-off-by: Brandon Williams <bmwill@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
1af8ae1cfa
commit
b4be74105f
4 changed files with 60 additions and 2 deletions
|
@ -2,6 +2,7 @@
|
|||
#include "cache.h"
|
||||
#include "transport.h"
|
||||
#include "remote.h"
|
||||
#include "refs.h"
|
||||
|
||||
static const char * const ls_remote_usage[] = {
|
||||
N_("git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>]\n"
|
||||
|
@ -43,6 +44,7 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
|
|||
int show_symref_target = 0;
|
||||
const char *uploadpack = NULL;
|
||||
const char **pattern = NULL;
|
||||
struct argv_array ref_prefixes = ARGV_ARRAY_INIT;
|
||||
|
||||
struct remote *remote;
|
||||
struct transport *transport;
|
||||
|
@ -74,8 +76,17 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
|
|||
if (argc > 1) {
|
||||
int i;
|
||||
pattern = xcalloc(argc, sizeof(const char *));
|
||||
for (i = 1; i < argc; i++)
|
||||
for (i = 1; i < argc; i++) {
|
||||
const char *glob;
|
||||
pattern[i - 1] = xstrfmt("*/%s", argv[i]);
|
||||
|
||||
glob = strchr(argv[i], '*');
|
||||
if (glob)
|
||||
argv_array_pushf(&ref_prefixes, "%.*s",
|
||||
(int)(glob - argv[i]), argv[i]);
|
||||
else
|
||||
expand_ref_prefix(&ref_prefixes, argv[i]);
|
||||
}
|
||||
}
|
||||
|
||||
remote = remote_get(dest);
|
||||
|
@ -96,7 +107,7 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
|
|||
if (uploadpack != NULL)
|
||||
transport_set_option(transport, TRANS_OPT_UPLOADPACK, uploadpack);
|
||||
|
||||
ref = transport_get_remote_refs(transport, NULL);
|
||||
ref = transport_get_remote_refs(transport, &ref_prefixes);
|
||||
if (transport_disconnect(transport))
|
||||
return 1;
|
||||
|
||||
|
|
14
refs.c
14
refs.c
|
@ -13,6 +13,7 @@
|
|||
#include "tag.h"
|
||||
#include "submodule.h"
|
||||
#include "worktree.h"
|
||||
#include "argv-array.h"
|
||||
|
||||
/*
|
||||
* List of all available backends
|
||||
|
@ -501,6 +502,19 @@ int refname_match(const char *abbrev_name, const char *full_name)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a 'prefix' expand it by the rules in 'ref_rev_parse_rules' and add
|
||||
* the results to 'prefixes'
|
||||
*/
|
||||
void expand_ref_prefix(struct argv_array *prefixes, const char *prefix)
|
||||
{
|
||||
const char **p;
|
||||
int len = strlen(prefix);
|
||||
|
||||
for (p = ref_rev_parse_rules; *p; p++)
|
||||
argv_array_pushf(prefixes, *p, len, prefix);
|
||||
}
|
||||
|
||||
/*
|
||||
* *string and *len will only be substituted, and *string returned (for
|
||||
* later free()ing) if the string passed in is a magic short-hand form
|
||||
|
|
7
refs.h
7
refs.h
|
@ -139,6 +139,13 @@ int resolve_gitlink_ref(const char *submodule, const char *refname,
|
|||
*/
|
||||
int refname_match(const char *abbrev_name, const char *full_name);
|
||||
|
||||
/*
|
||||
* Given a 'prefix' expand it by the rules in 'ref_rev_parse_rules' and add
|
||||
* the results to 'prefixes'
|
||||
*/
|
||||
struct argv_array;
|
||||
void expand_ref_prefix(struct argv_array *prefixes, const char *prefix);
|
||||
|
||||
int expand_ref(const char *str, int len, struct object_id *oid, char **ref);
|
||||
int dwim_ref(const char *str, int len, struct object_id *oid, char **ref);
|
||||
int dwim_log(const char *str, int len, struct object_id *oid, char **ref);
|
||||
|
|
|
@ -32,6 +32,19 @@ test_expect_success 'list refs with git:// using protocol v2' '
|
|||
test_cmp actual expect
|
||||
'
|
||||
|
||||
test_expect_success 'ref advertisment is filtered with ls-remote using protocol v2' '
|
||||
test_when_finished "rm -f log" &&
|
||||
|
||||
GIT_TRACE_PACKET="$(pwd)/log" git -c protocol.version=2 \
|
||||
ls-remote "$GIT_DAEMON_URL/parent" master >actual &&
|
||||
|
||||
cat >expect <<-EOF &&
|
||||
$(git -C "$daemon_parent" rev-parse refs/heads/master)$(printf "\t")refs/heads/master
|
||||
EOF
|
||||
|
||||
test_cmp actual expect
|
||||
'
|
||||
|
||||
stop_git_daemon
|
||||
|
||||
# Test protocol v2 with 'file://' transport
|
||||
|
@ -54,4 +67,17 @@ test_expect_success 'list refs with file:// using protocol v2' '
|
|||
test_cmp actual expect
|
||||
'
|
||||
|
||||
test_expect_success 'ref advertisment is filtered with ls-remote using protocol v2' '
|
||||
test_when_finished "rm -f log" &&
|
||||
|
||||
GIT_TRACE_PACKET="$(pwd)/log" git -c protocol.version=2 \
|
||||
ls-remote "file://$(pwd)/file_parent" master >actual &&
|
||||
|
||||
cat >expect <<-EOF &&
|
||||
$(git -C file_parent rev-parse refs/heads/master)$(printf "\t")refs/heads/master
|
||||
EOF
|
||||
|
||||
test_cmp actual expect
|
||||
'
|
||||
|
||||
test_done
|
||||
|
|
Loading…
Reference in a new issue