aboutsummaryrefslogtreecommitdiffstats
path: root/builtin
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2022-11-23 11:22:25 +0900
committerJunio C Hamano <gitster@pobox.com>2022-11-23 11:22:25 +0900
commitf8828f91256b5bc9731c313d59f8cd2d26901541 (patch)
treeaee159d961fcd0af67d953e180bddac06e9cc2e4 /builtin
parentMerge branch 'jt/submodule-on-demand' (diff)
parentreceive-pack: only use visible refs for connectivity check (diff)
downloadgit-f8828f91256b5bc9731c313d59f8cd2d26901541.tar.gz
git-f8828f91256b5bc9731c313d59f8cd2d26901541.zip
Merge branch 'ps/receive-use-only-advertised'
"git receive-pack" used to use all the local refs as the boundary for checking connectivity of the data "git push" sent, but now it uses only the refs that it advertised to the pusher. In a repository with the .hideRefs configuration, this reduces the resources needed to perform the check. cf. <221028.86bkpw805n.gmgdl@evledraar.gmail.com> cf. <xmqqr0yrizqm.fsf@gitster.g> * ps/receive-use-only-advertised: receive-pack: only use visible refs for connectivity check rev-parse: add `--exclude-hidden=` option revision: add new parameter to exclude hidden refs revision: introduce struct to handle exclusions revision: move together exclusion-related functions refs: get rid of global list of hidden refs refs: fix memory leak when parsing hideRefs config
Diffstat (limited to 'builtin')
-rw-r--r--builtin/receive-pack.c10
-rw-r--r--builtin/rev-list.c1
-rw-r--r--builtin/rev-parse.c18
3 files changed, 22 insertions, 7 deletions
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index 44bcea3a5b..a90af30363 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -80,6 +80,7 @@ static struct object_id push_cert_oid;
static struct signature_check sigcheck;
static const char *push_cert_nonce;
static const char *cert_nonce_seed;
+static struct string_list hidden_refs = STRING_LIST_INIT_DUP;
static const char *NONCE_UNSOLICITED = "UNSOLICITED";
static const char *NONCE_BAD = "BAD";
@@ -130,7 +131,7 @@ static enum deny_action parse_deny_action(const char *var, const char *value)
static int receive_pack_config(const char *var, const char *value, void *cb)
{
- int status = parse_hide_refs_config(var, value, "receive");
+ int status = parse_hide_refs_config(var, value, "receive", &hidden_refs);
if (status)
return status;
@@ -296,7 +297,7 @@ static int show_ref_cb(const char *path_full, const struct object_id *oid,
struct oidset *seen = data;
const char *path = strip_namespace(path_full);
- if (ref_is_hidden(path, path_full))
+ if (ref_is_hidden(path, path_full, &hidden_refs))
return 0;
/*
@@ -1794,7 +1795,7 @@ static void reject_updates_to_hidden(struct command *commands)
strbuf_setlen(&refname_full, prefix_len);
strbuf_addstr(&refname_full, cmd->ref_name);
- if (!ref_is_hidden(cmd->ref_name, refname_full.buf))
+ if (!ref_is_hidden(cmd->ref_name, refname_full.buf, &hidden_refs))
continue;
if (is_null_oid(&cmd->new_oid))
cmd->error_string = "deny deleting a hidden ref";
@@ -1928,6 +1929,8 @@ static void execute_commands(struct command *commands,
opt.err_fd = err_fd;
opt.progress = err_fd && !quiet;
opt.env = tmp_objdir_env(tmp_objdir);
+ opt.exclude_hidden_refs_section = "receive";
+
if (check_connected(iterate_receive_command_list, &data, &opt))
set_connectivity_errors(commands, si);
@@ -2591,6 +2594,7 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
packet_flush(1);
oid_array_clear(&shallow);
oid_array_clear(&ref);
+ string_list_clear(&hidden_refs, 0);
free((void *)push_cert_nonce);
return 0;
}
diff --git a/builtin/rev-list.c b/builtin/rev-list.c
index 3acd93f71e..d42db0b0cc 100644
--- a/builtin/rev-list.c
+++ b/builtin/rev-list.c
@@ -38,6 +38,7 @@ static const char rev_list_usage[] =
" --tags\n"
" --remotes\n"
" --stdin\n"
+" --exclude-hidden=[receive|uploadpack]\n"
" --quiet\n"
" ordering output:\n"
" --topo-order\n"
diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index 8f61050bde..b5666a03bd 100644
--- a/builtin/rev-parse.c
+++ b/builtin/rev-parse.c
@@ -39,7 +39,7 @@ static int abbrev_ref_strict;
static int output_sq;
static int stuck_long;
-static struct string_list *ref_excludes;
+static struct ref_exclusions ref_excludes = REF_EXCLUSIONS_INIT;
/*
* Some arguments are relevant "revision" arguments,
@@ -198,7 +198,7 @@ static int show_default(void)
static int show_reference(const char *refname, const struct object_id *oid,
int flag UNUSED, void *cb_data UNUSED)
{
- if (ref_excluded(ref_excludes, refname))
+ if (ref_excluded(&ref_excludes, refname))
return 0;
show_rev(NORMAL, oid, refname);
return 0;
@@ -585,7 +585,7 @@ static void handle_ref_opt(const char *pattern, const char *prefix)
for_each_glob_ref_in(show_reference, pattern, prefix, NULL);
else
for_each_ref_in(prefix, show_reference, NULL);
- clear_ref_exclusion(&ref_excludes);
+ clear_ref_exclusions(&ref_excludes);
}
enum format_type {
@@ -863,7 +863,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
}
if (!strcmp(arg, "--all")) {
for_each_ref(show_reference, NULL);
- clear_ref_exclusion(&ref_excludes);
+ clear_ref_exclusions(&ref_excludes);
continue;
}
if (skip_prefix(arg, "--disambiguate=", &arg)) {
@@ -876,10 +876,14 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
continue;
}
if (opt_with_value(arg, "--branches", &arg)) {
+ if (ref_excludes.hidden_refs_configured)
+ return error(_("--exclude-hidden cannot be used together with --branches"));
handle_ref_opt(arg, "refs/heads/");
continue;
}
if (opt_with_value(arg, "--tags", &arg)) {
+ if (ref_excludes.hidden_refs_configured)
+ return error(_("--exclude-hidden cannot be used together with --tags"));
handle_ref_opt(arg, "refs/tags/");
continue;
}
@@ -888,6 +892,8 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
continue;
}
if (opt_with_value(arg, "--remotes", &arg)) {
+ if (ref_excludes.hidden_refs_configured)
+ return error(_("--exclude-hidden cannot be used together with --remotes"));
handle_ref_opt(arg, "refs/remotes/");
continue;
}
@@ -895,6 +901,10 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
add_ref_exclusion(&ref_excludes, arg);
continue;
}
+ if (skip_prefix(arg, "--exclude-hidden=", &arg)) {
+ exclude_hidden_refs(&ref_excludes, arg);
+ continue;
+ }
if (!strcmp(arg, "--show-toplevel")) {
const char *work_tree = get_git_work_tree();
if (work_tree)