From: "Sun Chao via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: Sun Chao <16657101987@163.com>
Subject: [PATCH v2 0/3] hide-refs: add hook to force hide refs
Date: Mon, 15 Aug 2022 00:54:22 +0000 [thread overview]
Message-ID: <pull.1301.v2.git.git.1660524865.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.1301.git.git.1659543457.gitgitgadget@gmail.com>
Gerrit is implemented by JGit and is known as a centralized workflow system
which supports reference-level access control for repository. If we choose
to work in centralized workflow like what Gerrit provided, reference-level
access control is needed and we might add a reference filter hook hide-refs
to hide the private data.
This hook would be invoked by 'git-receive-pack' and 'git-upload-pack'
during the reference discovery phase, each reference and will be filtered
with this hook. The hook executes once with no arguments for each
'git-upload-pack' and 'git-receive-pack' process. Once the hook is invoked,
a version number and server process name ('uploadpack' or 'receive') will
send to it in pkt-line format, followed by a flush-pkt. The hook should
response with its version number.
During reference discovery phase, each reference will be filtered by this
hook. In the following example, the letter 'G' stands for 'git-receive-pack'
or 'git-upload-pack' and the letter 'H' stands for this hook. The hook
decides if the reference will be hidden or not, it sends result back in
pkt-line format protocol, a response "hide" the references will hide to the
client and can not fetch its private data even in protocol V2.
# Version negotiation
G: PKT-LINE(version=1\0uploadpack)
G: flush-pkt
H: PKT-LINE(version=1)
H: flush-pkt
# Send reference filter request to hook
G: PKT-LINE(ref <refname>:<refname_full>)
G: flush-pkt
# Receive result from the hook.
# Case 1: this reference is hidden
H: PKT-LINE(hide)
H: flush-pkt
# Case 2: this reference can be advertised
H: flush-pkt
To enable the hide-refs hook, we should config hiderefs with force: option,
eg:
git config --add transfer.hiderefs force:refs/prefix1/
git config --add uploadpack.hiderefs force:!refs/prefix2/
the hide-refs will be called during reference discovery phase and check each
matched reference, a 'hide' response means the reference will be hidden for
its private data and even the allowTipSHA1InWant or allowReachableSHA1InWant
is set to true.
Sun Chao (3):
hide-refs: add hook to force hide refs
t1419: add test cases for hide-refs hook
doc: add documentation for the hide-refs hook
Documentation/githooks.txt | 48 ++++
Makefile | 1 +
builtin/receive-pack.c | 5 +-
ls-refs.c | 2 +-
refs.c | 221 +++++++++++++++++-
refs.h | 6 +
serve.c | 2 +
t/helper/test-hide-refs.c | 152 ++++++++++++
t/helper/test-tool.c | 1 +
t/helper/test-tool.h | 1 +
t/t1419-hide-refs-hook.sh | 142 +++++++++++
t/t1419/common-functions.sh | 80 +++++++
t/t1419/once-0000-abnormal-hide-refs-hook.sh | 161 +++++++++++++
...test-0001-ls-remote-with-hide-refs-hook.sh | 77 ++++++
...st-0002-upload-pack-with-hide-refs-hook.sh | 122 ++++++++++
...t-0003-receive-pack-with-hide-refs-hook.sh | 87 +++++++
upload-pack.c | 32 +--
upload-pack.h | 1 +
18 files changed, 1111 insertions(+), 30 deletions(-)
create mode 100644 t/helper/test-hide-refs.c
create mode 100755 t/t1419-hide-refs-hook.sh
create mode 100644 t/t1419/common-functions.sh
create mode 100644 t/t1419/once-0000-abnormal-hide-refs-hook.sh
create mode 100644 t/t1419/test-0001-ls-remote-with-hide-refs-hook.sh
create mode 100644 t/t1419/test-0002-upload-pack-with-hide-refs-hook.sh
create mode 100644 t/t1419/test-0003-receive-pack-with-hide-refs-hook.sh
base-commit: afa70145a25e81faa685dc0b465e52b45d2444bd
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-1301%2Fsunchao9%2Frefs_advertise-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-1301/sunchao9/refs_advertise-v2
Pull-Request: https://github.com/git/git/pull/1301
Range-diff vs v1:
1: b4b5ce5a361 ! 1: 3b8fb63cc78 refs-advertise: add hook to filter advertised refs
@@ Metadata
Author: Sun Chao <sunchao9@huawei.com>
## Commit message ##
- refs-advertise: add hook to filter advertised refs
+ hide-refs: add hook to force hide refs
Gerrit is implemented by JGit and is known as a centralized workflow system
which supports reference-level access control for repository. If we choose
to work in centralized workflow like what Gerrit provided, reference-level
- access control is needed and is possible if we add a reference advertise
- filter hook just like what Gerrit did.
+ access control is needed and we might add a reference filter hook
+ `hide-refs` to hide the private data.
This hook would be invoked by 'git-receive-pack' and 'git-upload-pack'
- during the reference discovery phase and the commit fetching phase,
- each reference and will be filtered by this hook. The hook executes once
- with no arguments for each 'git-upload-pack' and 'git-receive-pack' process
- and if the exit status is non-zero, `git push` and `git fetch` will abort.
-
- Once the hook is invoked, a version number and server process name
- ('git-upload-pack' or 'git-receive-pack' or 'ls-refs') should send to it in
- packet-line format, followed by a flush-pkt. The hook should response with
- its version number and process name list it support. If the list does not
- contains the server process name, the server will close the connection with
- the hook and keep going without the hook child process.
+ during the reference discovery phase, each reference and will be filtered
+ with this hook. The hook executes once with no arguments for each
+ 'git-upload-pack' and 'git-receive-pack' process. Once the hook is invoked,
+ a version number and server process name ('uploadpack' or 'receive') will
+ send to it in pkt-line format, followed by a flush-pkt. The hook should
+ response with its version number.
During reference discovery phase, each reference will be filtered by this
hook. In the following example, the letter 'G' stands for 'git-receive-pack'
or 'git-upload-pack' and the letter 'H' stands for this hook. The hook
- decides if the reference will be advertised or not, it sends result back in
- pkt-line format protocol, a response in "ok ref <ref>" format followed by a
- flush-pkt means the references "<ref>" can be advertised, and "ng ref <ref>"
- means not.
-
- # Version negotiation
- G: PKT-LINE(version=1\0git-upload-pack)
- G: flush-pkt
- H: PKT-LINE(version=1\0git-upload-pack git-receive-pack ls-refs)
- H: flush-pkt
+ decides if the reference will be hidden or not, it sends result back in
+ pkt-line format protocol, a response "hide" the references will hide
+ to the client and can not fetch its private data even in protocol V2.
- # Send reference filter request to hook
- G: PKT-LINE(ref <ref> <oid>)
- G: flush-pkt
+ # Version negotiation
+ G: PKT-LINE(version=1\0uploadpack)
+ G: flush-pkt
+ H: PKT-LINE(version=1)
+ H: flush-pkt
- # Receive result from the hook.
- # Case 1: this reference is valid
- H: PKT-LINE(ok ref <ref>)
- H: flush-pkt
- # Case 2: this reference is filtered out
- H: PKT-LINE(ng ref <ref>)
- H: flush-pkt
+ # Send reference filter request to hook
+ G: PKT-LINE(ref <refname>:<refname_full>)
+ G: flush-pkt
- During commit fetch phase of 'git-upload-pack' process, git client may send
- `want <oid>` requests and 'git-upload-pack' will send object filter requests
- to the hook to check if the object "<oid>" will be sent to the client or
- not. In the following example, the letter 'G' stands for 'git-upload-pack'
- and the letter 'H' stands for this hook.
+ # Receive result from the hook.
+ # Case 1: this reference is hidden
+ H: PKT-LINE(hide)
+ H: flush-pkt
- The hook will decides if a commit will be sent to the client or not, it
- sends result in pkt-line format protocol to `git-upload-pack`, a response
- with "ok obj <oid>" format followed by a flush-pkt means the object "<oid>"
- can be sent to client, and "ng obj <oid>" means not.
+ # Case 2: this reference can be advertised
+ H: flush-pkt
- # Version negotiation
- G: PKT-LINE(version=1\0ls-refs)
- G: flush-pkt
- H: PKT-LINE(version=1\0git-upload-pack git-receive-pack ls-refs)
- H: flush-pkt
+ To enable the `hide-refs` hook, we should config hiderefs with `force:`
+ option, eg:
- # Send commit filter request to hook
- G: PKT-LINE(obj <oid>)
- G: flush-pkt
+ git config --add transfer.hiderefs force:refs/prefix1/
+ git config --add uploadpack.hiderefs force:!refs/prefix2/
- # Receive result from the hook.
- # Case 1: this object is valid
- H: PKT-LINE(ok obj <oid>)
- H: flush-pkt
- # Case 2: this object is filtered out
- H: PKT-LINE(ng obj <oid>)
- H: flush-pkt
+ the `hide-refs` will be called during reference discovery phase and
+ check each matched reference, a 'hide' response means the reference will
+ be hidden for its private data and even the `allowTipSHA1InWant` or
+ `allowReachableSHA1InWant` is set to true.
Signed-off-by: Sun Chao <sunchao9@huawei.com>
@@ Makefile: TEST_BUILTINS_OBJS += test-wildmatch.o
TEST_BUILTINS_OBJS += test-windows-named-pipe.o
TEST_BUILTINS_OBJS += test-write-cache.o
TEST_BUILTINS_OBJS += test-xml-encode.o
-+TEST_BUILTINS_OBJS += test-refs-advertise.o
++TEST_BUILTINS_OBJS += test-hide-refs.o
# Do not add more tests here unless they have extra dependencies. Add
# them in TEST_BUILTINS_OBJS above.
-@@ Makefile: LIB_OBJS += refs/files-backend.o
- LIB_OBJS += refs/iterator.o
- LIB_OBJS += refs/packed-backend.o
- LIB_OBJS += refs/ref-cache.o
-+LIB_OBJS += refs/refs-advertise.o
- LIB_OBJS += refspec.o
- LIB_OBJS += remote.o
- LIB_OBJS += replace-object.o
## builtin/receive-pack.c ##
-@@
- #include "commit-reach.h"
- #include "worktree.h"
- #include "shallow.h"
-+#include "refs/refs-advertise.h"
-
- static const char * const receive_pack_usage[] = {
- N_("git receive-pack <git-dir>"),
@@ builtin/receive-pack.c: static int show_ref_cb(const char *path_full, const struct object_id *oid,
- if (ref_is_hidden(path, path_full))
+ 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) || ref_is_force_hidden(path, path_full))
return 0;
-+ if (filter_advertise_ref(path, oid)) {
-+ return 0;
-+ }
-+
/*
- * Advertise refs outside our current namespace as ".have"
- * refs, so that the client can use them to minimize data
-@@ builtin/receive-pack.c: static int delete_only(struct command *commands)
- return 1;
- }
-
-+static void clean_refs_advertise_filter(void) {
-+ clean_advertise_refs_filter();
-+}
-+
- int cmd_receive_pack(int argc, const char **argv, const char *prefix)
- {
- int advertise_refs = 0;
-@@ builtin/receive-pack.c: int cmd_receive_pack(int argc, const char **argv, const char *prefix)
- if (!enter_repo(service_dir, 0))
- die("'%s' does not appear to be a git repository", service_dir);
+@@ builtin/receive-pack.c: static void reject_updates_to_hidden(struct command *commands)
+ strbuf_setlen(&refname_full, prefix_len);
+ strbuf_addstr(&refname_full, cmd->ref_name);
-+ create_advertise_refs_filter("git-receive-pack");
-+ atexit(clean_refs_advertise_filter);
-+
- git_config(receive_pack_config, NULL);
- if (cert_nonce_seed)
- push_cert_nonce = prepare_push_cert_nonce(service_dir, time(NULL));
+- if (!ref_is_hidden(cmd->ref_name, refname_full.buf))
++ if (!ref_is_hidden(cmd->ref_name, refname_full.buf) &&
++ !ref_is_force_hidden(cmd->ref_name, refname_full.buf))
+ continue;
+ if (is_null_oid(&cmd->new_oid))
+ cmd->error_string = "deny deleting a hidden ref";
## ls-refs.c ##
-@@
- #include "ls-refs.h"
- #include "pkt-line.h"
- #include "config.h"
-+#include "run-command.h"
-+#include "refs/refs-advertise.h"
-
- static int config_read;
- static int advertise_unborn;
- static int allow_unborn;
-+static struct string_list symref = STRING_LIST_INIT_DUP;
-
- static void ensure_config_read(void)
- {
@@ ls-refs.c: static int send_ref(const char *refname, const struct object_id *oid,
- {
- struct ls_refs_data *data = cb_data;
- const char *refname_nons = strip_namespace(refname);
-+ const char *refname_to_filter = refname_nons;
strbuf_reset(&data->buf);
-@@ ls-refs.c: static int send_ref(const char *refname, const struct object_id *oid,
- if (!ref_match(&data->prefixes, refname_nons))
+- if (ref_is_hidden(refname_nons, refname))
++ if (mark_our_ref(refname_nons, refname, oid))
return 0;
-+ if (!strcmp(refname_nons, "HEAD")) {
-+ struct string_list_item *item = string_list_lookup(&symref, "HEAD");
-+ if (item) {
-+ refname_to_filter = (const char *)item->util;
-+ }
-+ }
-+
-+ if (filter_advertise_ref(refname_to_filter, oid))
-+ return 0;
-+
- if (oid)
- strbuf_addf(&data->buf, "%s %s", oid_to_hex(oid), refname_nons);
- else
-@@ ls-refs.c: static int send_ref(const char *refname, const struct object_id *oid,
-
- static void send_possibly_unborn_head(struct ls_refs_data *data)
- {
-+ const char *symref_target;
-+ struct string_list_item *item;
- struct strbuf namespaced = STRBUF_INIT;
- struct object_id oid;
- int flag;
- int oid_is_null;
-
- strbuf_addf(&namespaced, "%sHEAD", get_git_namespace());
-- if (!resolve_ref_unsafe(namespaced.buf, 0, &oid, &flag))
-+ symref_target = resolve_ref_unsafe(namespaced.buf, 0, &oid, &flag);
-+ if (!symref_target)
- return; /* bad ref */
- oid_is_null = is_null_oid(&oid);
- if (!oid_is_null ||
-- (data->unborn && data->symrefs && (flag & REF_ISSYMREF)))
-+ (data->unborn && data->symrefs && (flag & REF_ISSYMREF))) {
-+ item = string_list_append(&symref, "HEAD");
-+ item->util = xstrdup(strip_namespace(symref_target));
- send_ref(namespaced.buf, oid_is_null ? NULL : &oid, flag, data);
-+ }
- strbuf_release(&namespaced);
- }
-
-@@ ls-refs.c: static int ls_refs_config(const char *var, const char *value, void *data)
- return parse_hide_refs_config(var, value, "uploadpack");
+ if (!ref_match(&data->prefixes, refname_nons))
+
+ ## refs.c ##
+@@
+ #include "lockfile.h"
+ #include "iterator.h"
+ #include "refs.h"
++#include "pkt-line.h"
+ #include "refs/refs-internal.h"
+ #include "run-command.h"
+ #include "hook.h"
+@@ refs.c: char *shorten_unambiguous_ref(const char *refname, int strict)
}
-+static void clean_refs_advertise_filter(void) {
-+ clean_advertise_refs_filter();
-+}
-+
- int ls_refs(struct repository *r, struct packet_reader *request)
+ static struct string_list *hide_refs;
+-
++static struct string_list *force_hide_refs;
++static struct strbuf hide_refs_section = STRBUF_INIT;
+ int parse_hide_refs_config(const char *var, const char *value, const char *section)
{
- struct ls_refs_data data;
-@@ ls-refs.c: int ls_refs(struct repository *r, struct packet_reader *request)
+ const char *key;
++ int force = 0;
++
+ if (!strcmp("transfer.hiderefs", var) ||
+ (!parse_config_key(var, section, NULL, NULL, &key) &&
+ !strcmp(key, "hiderefs"))) {
+ char *ref;
+ int len;
++ int forcelen;
- ensure_config_read();
- git_config(ls_refs_config, NULL);
-+ create_advertise_refs_filter("ls-refs");
-+ atexit(clean_refs_advertise_filter);
-
- while (packet_reader_read(request) == PACKET_READ_NORMAL) {
- const char *arg = request->line;
-
- ## refs/refs-advertise.c (new) ##
-@@
-+#include "../cache.h"
-+#include "../config.h"
-+#include "../strbuf.h"
-+#include "../hook.h"
-+#include "../sigchain.h"
-+#include "../pkt-line.h"
-+#include "../refs.h"
-+#include "../run-command.h"
-+#include "connect.h"
-+#include "ref-cache.h"
-+#include "refs-advertise.h"
+ if (!value)
+ return config_error_nonbool(var);
+
-+struct advertise_refs_filter {
-+ struct child_process proc;
-+ struct packet_reader reader;
-+};
++ forcelen = strlen("force:");
++ len = strlen(value);
++ if ((len >= forcelen) && !strncmp(value, "force:", forcelen)) {
++ if (len == forcelen)
++ return error(_("missing value for '%s' with force option"), var);
++
++ force = 1;
++ value += forcelen;
++ }
++
+ ref = xstrdup(value);
+ len = strlen(ref);
+ while (len && ref[len - 1] == '/')
+ ref[--len] = '\0';
+- if (!hide_refs) {
+- CALLOC_ARRAY(hide_refs, 1);
+- hide_refs->strdup_strings = 1;
++
++ if (force) {
++ if (!force_hide_refs) {
++ CALLOC_ARRAY(force_hide_refs, 1);
++ force_hide_refs->strdup_strings = 1;
++ }
++ string_list_append(force_hide_refs, ref);
++ } else {
++ if (!hide_refs) {
++ CALLOC_ARRAY(hide_refs, 1);
++ hide_refs->strdup_strings = 1;
++ }
++ string_list_append(hide_refs, ref);
+ }
+- string_list_append(hide_refs, ref);
+ }
+
-+static struct advertise_refs_filter *hook_filter = NULL;
++ if (hide_refs_section.len == 0) {
++ strbuf_addstr(&hide_refs_section, section);
++ }
+
-+void create_advertise_refs_filter(const char *command) {
-+ struct advertise_refs_filter *filter;
+ return 0;
+ }
+
+-int ref_is_hidden(const char *refname, const char *refname_full)
++static struct child_process *hide_refs_proc;
++static struct packet_reader *hide_refs_reader;
++static void create_hide_refs_process(void) {
+ struct child_process *proc;
+ struct packet_reader *reader;
+ const char *hook_path;
-+ int command_support = 0;
+ int version = 0;
+ int code;
+
-+ if (hook_filter != NULL)
-+ return;
-+
-+ hook_path = find_hook("refs-advertise");
++ hook_path = find_hook("hide-refs");
+ if (!hook_path) {
-+ return;
++ die("can not find hide-refs hook");
+ }
+
-+ filter = (struct advertise_refs_filter *) xcalloc (1, sizeof (struct advertise_refs_filter));
-+ proc = &filter->proc;
-+ reader = &filter->reader;
++ proc = (struct child_process *) xcalloc (1, sizeof (struct child_process));
++ reader = (struct packet_reader *) xcalloc (1, sizeof(struct packet_reader));
+
+ child_process_init(proc);
+ strvec_push(&proc->args, hook_path);
+ proc->in = -1;
+ proc->out = -1;
-+ proc->trace2_hook_name = "refs-advertise";
++ proc->trace2_hook_name = "hide-refs";
+ proc->err = 0;
+
+ code = start_command(proc);
+ if (code)
-+ die("can not run hook refs-advertise");
++ die("can not run hook hide-refs");
+
+ sigchain_push(SIGPIPE, SIG_IGN);
+
@@ refs/refs-advertise.c (new)
+ packet_reader_init(reader, proc->out, NULL, 0,
+ PACKET_READ_CHOMP_NEWLINE |
+ PACKET_READ_GENTLE_ON_EOF);
-+ code = packet_write_fmt_gently(proc->in, "version=1%c%s", '\0', command);
++ code = packet_write_fmt_gently(proc->in, "version=1%c%s", '\0', hide_refs_section.buf);
+ if (!code)
+ code = packet_flush_gently(proc->in);
+
+ if (!code)
+ for (;;) {
-+ int linelen;
+ enum packet_read_status status;
+
+ status = packet_reader_read(reader);
+ if (status != PACKET_READ_NORMAL) {
-+ /* Check whether refs-advertise exited abnormally */
++ /* Check whether hide-refs exited abnormally */
+ if (status == PACKET_READ_EOF)
-+ die("can not read version message from hook refs-advertise");
++ die("can not read version message from hook hide-refs");
+ break;
+ }
+
+ if (reader->pktlen > 8 && starts_with(reader->line, "version=")) {
+ version = atoi(reader->line + 8);
-+ linelen = strlen(reader->line);
-+ if (linelen < reader->pktlen) {
-+ const char *command_list = reader->line + linelen + 1;
-+ if (parse_feature_request(command_list, command)) {
-+ command_support = 1;
-+ }
-+ }
+ }
+ }
+
+ if (code)
-+ die("can not read version message from hook refs-advertise");
++ die("can not read version message from hook hide-refs");
+
+ switch (version) {
+ case 0:
@@ refs/refs-advertise.c (new)
+ case 1:
+ break;
+ default:
-+ die(_("hook refs-advertise version '%d' is not supported"), version);
++ die(_("hook hide-refs version '%d' is not supported"), version);
+ }
+
+ sigchain_pop(SIGPIPE);
+
-+ if (!command_support) {
-+ close(proc->in);
-+ close(proc->out);
-+ kill(proc->pid, SIGTERM);
-+ finish_command_in_signal(proc);
-+ free(filter);
-+
-+ return;
-+ }
-+
-+ hook_filter = filter;
++ hide_refs_proc = proc;
++ hide_refs_reader = reader;
+ return;
+}
+
-+void clean_advertise_refs_filter(void) {
-+ struct child_process *proc;
-+
-+ if (!hook_filter) {
-+ return;
-+ }
-+
-+ proc = &hook_filter->proc;
-+
-+ close(proc->in);
-+ close(proc->out);
-+ kill(proc->pid, SIGTERM);
-+ finish_command_in_signal(proc);
-+ FREE_AND_NULL(hook_filter);
-+}
-+
-+static int do_filter_advertise_ref(const char *refname, const struct object_id *oid) {
-+ struct child_process *proc;
-+ struct packet_reader *reader;
++static int ref_force_hidden_check(const char *refname, const char *refname_full)
++{
+ struct strbuf buf = STRBUF_INIT;
-+ char *oid_hex;
+ int code;
++ int ret = 0;
++
++ if (!force_hide_refs) {
++ return 0;
++ }
+
-+ proc = &hook_filter->proc;
-+ reader = &hook_filter->reader;
-+ if (oid)
-+ oid_hex = oid_to_hex(oid);
-+ else
-+ oid_hex = oid_to_hex(null_oid());
++ if (!hide_refs_proc) {
++ create_hide_refs_process();
++ }
+
-+ code = packet_write_fmt_gently(proc->in, "ref %s %s", refname, oid_hex);
++ sigchain_push(SIGPIPE, SIG_IGN);
++ code = packet_write_fmt_gently(hide_refs_proc->in, "ref %s:%s", refname, refname_full);
+ if (code)
-+ die("hook refs-advertise died abnormally");
++ die("hook hide-refs died abnormally");
+
-+ code = packet_flush_gently(proc->in);
++ code = packet_flush_gently(hide_refs_proc->in);
+ if (code)
-+ die("hook refs-advertise died abnormally");
++ die("hook hide-refs died abnormally");
+
+ for (;;) {
+ enum packet_read_status status;
+
-+ status = packet_reader_read(reader);
++ status = packet_reader_read(hide_refs_reader);
+ if (status != PACKET_READ_NORMAL) {
-+ /* Check whether refs-advertise exited abnormally */
++ /* Check whether hide-refs exited abnormally */
+ if (status == PACKET_READ_EOF)
-+ die("hook refs-advertise died abnormally");
++ die("hook hide-refs died abnormally");
+ break;
+ }
+
+ strbuf_reset(&buf);
-+ strbuf_addstr(&buf, reader->line);
++ strbuf_addstr(&buf, hide_refs_reader->line);
+ }
+
-+ if (strncmp("ok ref ", buf.buf, 7))
-+ return -1;
++ if (!strncmp("hide", buf.buf, 4))
++ ret = 1;
+
-+ if (strcmp(refname, buf.buf + 7))
-+ return -1;
-+
-+ return 0;
-+}
-+
-+int filter_advertise_ref(const char *refname, const struct object_id *oid) {
-+ int result;
-+
-+ if (!hook_filter) {
-+ return 0;
-+ }
-+
-+ sigchain_push(SIGPIPE, SIG_IGN);
-+ result = do_filter_advertise_ref(refname, oid);
+ sigchain_pop(SIGPIPE);
-+
-+ return result;
++ return ret;
+}
+
-+static int do_filter_advertise_object(const struct object_id *oid) {
-+ struct child_process *proc;
-+ struct packet_reader *reader;
-+ struct strbuf buf = STRBUF_INIT;
-+ char *oid_hex;
-+ int code;
-+
-+ proc = &hook_filter->proc;
-+ reader = &hook_filter->reader;
-+ oid_hex = oid_to_hex(oid);
-+
-+ code = packet_write_fmt_gently(proc->in, "obj %s", oid_hex);
-+ if (code)
-+ die("hook refs-advertise died abnormally");
-+
-+ code = packet_flush_gently(proc->in);
-+ if (code)
-+ die("hook refs-advertise died abnormally");
-+
-+ for (;;) {
-+ enum packet_read_status status;
++static int ref_hidden_check(const char *refname, const char *refname_full, int force)
+ {
++ struct string_list *hide_refs_list = hide_refs;
+ int i;
+
+- if (!hide_refs)
++ if (force)
++ hide_refs_list = force_hide_refs;
+
-+ status = packet_reader_read(reader);
-+ if (status != PACKET_READ_NORMAL) {
-+ /* Check whether refs-advertise exited abnormally */
-+ if (status == PACKET_READ_EOF)
-+ die("hook refs-advertise died abnormally");
-+ break;
++ if (!hide_refs_list)
+ return 0;
+- for (i = hide_refs->nr - 1; i >= 0; i--) {
+- const char *match = hide_refs->items[i].string;
++ for (i = hide_refs_list->nr - 1; i >= 0; i--) {
++ const char *match = hide_refs_list->items[i].string;
+ const char *subject;
+ int neg = 0;
+ const char *p;
+@@ refs.c: int ref_is_hidden(const char *refname, const char *refname_full)
+ /* refname can be NULL when namespaces are used. */
+ if (subject &&
+ skip_prefix(subject, match, &p) &&
+- (!*p || *p == '/'))
+- return !neg;
++ (!*p || *p == '/')) {
++ if (neg)
++ return 0;
++ if (!force)
++ return 1;
++ return ref_force_hidden_check(refname, refname_full);
+ }
+ }
+ return 0;
+ }
+
++int ref_is_hidden(const char *refname, const char *refname_full)
++{
++ return ref_hidden_check(refname, refname_full, 0);
++}
+
-+ strbuf_reset(&buf);
-+ strbuf_addstr(&buf, reader->line);
-+ }
-+
-+ if (strncmp("ok obj ", buf.buf, 7))
-+ return -1;
-+
-+ if (strcmp(oid_hex, buf.buf + 7))
-+ return -1;
-+
-+ return 0;
++int ref_is_force_hidden(const char *refname, const char *refname_full)
++{
++ return ref_hidden_check(refname, refname_full, 1);
+}
+
-+int filter_advertise_object(const struct object_id *oid) {
-+ int result;
++#define OUR_REF (1u << 12)
++#define HIDDEN_REF (1u << 19)
++#define HIDDEN_REF_FORCE (1u << 20)
++static int has_force_hidden;
++int mark_our_ref(const char *refname, const char *refname_full,
++ const struct object_id *oid)
++{
++ struct object *o;
+
-+ if (!hook_filter || !oid) {
++ if (!oid || is_null_oid(oid)) {
+ return 0;
+ }
+
-+ sigchain_push(SIGPIPE, SIG_IGN);
-+ result = do_filter_advertise_object(oid);
-+ sigchain_pop(SIGPIPE);
++ o = lookup_unknown_object(the_repository, oid);
++ if (ref_is_force_hidden(refname, refname_full)) {
++ o->flags |= HIDDEN_REF_FORCE;
++ has_force_hidden = 1;
++ return 1;
++ }
++ if (ref_is_hidden(refname, refname_full)) {
++ o->flags |= HIDDEN_REF;
++ return 1;
++ }
++ o->flags |= OUR_REF;
++ return 0;
++}
+
-+ return result;
++int has_force_hidden_refs(void) {
++ return has_force_hidden;
+}
++
+ const char *find_descendant_ref(const char *dirname,
+ const struct string_list *extras,
+ const struct string_list *skip)
+
+ ## refs.h ##
+@@ refs.h: int parse_hide_refs_config(const char *var, const char *value, const char *);
+ * parameter always points to the full ref name.
+ */
+ int ref_is_hidden(const char *, const char *);
++int ref_is_force_hidden(const char *, const char *);
++/* return non-zero if the ref is hidden, otherwise 0 */
++int mark_our_ref(const char *refname, const char *refname_full,
++ const struct object_id *oid);
++int has_force_hidden_refs(void);
++void lazy_load_hidden_refs(void);
+
+ enum ref_type {
+ REF_TYPE_PER_WORKTREE, /* refs inside refs/ but not shared */
- ## refs/refs-advertise.h (new) ##
+ ## serve.c ##
@@
-+#ifndef REFS_REFS_ADVERTISE_H
-+#define REFS_REFS_ADVERTISE_H
-+
-+#include "../hash.h"
-+
-+void create_advertise_refs_filter(const char *command);
-+void clean_advertise_refs_filter(void);
-+int filter_advertise_ref(const char *refname, const struct object_id *oid);
-+int filter_advertise_object(const struct object_id *oid);
-+
-+#endif
+ #include "cache.h"
+ #include "repository.h"
+ #include "config.h"
++#include "refs.h"
+ #include "pkt-line.h"
+ #include "version.h"
+ #include "ls-refs.h"
+@@ serve.c: void protocol_v2_serve_loop(int stateless_rpc)
+ * a single request/response exchange
+ */
+ if (stateless_rpc) {
++ lazy_load_hidden_refs();
+ process_request();
+ } else {
+ for (;;)
- ## t/helper/test-refs-advertise.c (new) ##
+ ## t/helper/test-hide-refs.c (new) ##
@@
+#include "cache.h"
+#include "hash.h"
@@ t/helper/test-refs-advertise.c (new)
+#include "sigchain.h"
+#include "test-tool.h"
+
-+static const char *refs_advertise_usage[] = {
-+ "test-tool refs-advertise [<options>...]",
++static const char *hide_refs_usage[] = {
++ "test-tool hide-refs [<options>...]",
+ NULL
+};
+
-+static int can_upload_pack;
-+static int can_receive_pack;
-+static int can_ls_refs;
+static int die_read_version;
+static int die_write_version;
+static int die_read_first_ref;
+static int die_read_second_ref;
-+static int die_filter_refs;
-+static int upload_pack;
-+static int receive_pack;
-+static int ls_refs;
++static int die_after_proc_ref;
+static int verbose;
+static int version = 1;
+static int first_ref;
@@ t/helper/test-refs-advertise.c (new)
+ char ref_name[FLEX_ARRAY]; /* more */
+};
+
-+static void refs_advertise_verison(struct packet_reader *reader) {
++static void hide_refs_verison(struct packet_reader *reader) {
+ int server_version = 0;
+
+ if (die_read_version)
+ die("die with the --die-read-version option");
+
+ for (;;) {
-+ int linelen;
-+
+ if (packet_reader_read(reader) != PACKET_READ_NORMAL)
+ break;
+
@@ t/helper/test-refs-advertise.c (new)
+ server_version = atoi(reader->line+8);
+ if (server_version != 1)
+ die("bad protocol version: %d", server_version);
-+ linelen = strlen(reader->line);
-+ if (linelen < reader->pktlen) {
-+ const char *feature_list = reader->line + linelen + 1;
-+ if (parse_feature_request(feature_list, "git-upload-pack"))
-+ upload_pack = 1;
-+ if (parse_feature_request(feature_list, "git-receive-pack"))
-+ receive_pack = 1;
-+ if (parse_feature_request(feature_list, "ls-refs"))
-+ ls_refs = 1;
-+ }
+ }
+ }
+
+ if (die_write_version)
+ die("die with the --die-write-version option");
+
-+ if (can_upload_pack || can_receive_pack || can_ls_refs)
-+ packet_write_fmt(1, "version=%d%c%s%s%s\n",
-+ version, '\0',
-+ can_upload_pack ? "git-upload-pack ": "",
-+ can_receive_pack? "git-receive-pack ": "",
-+ can_ls_refs? "ls-refs ": "");
-+ else
-+ packet_write_fmt(1, "version=%d\n", version);
-+
++ packet_write_fmt(1, "version=%d\n", version);
+ packet_flush(1);
-+
-+ if ((upload_pack && !can_upload_pack) ||
-+ (receive_pack && !can_receive_pack) ||
-+ (ls_refs && !can_ls_refs)) {
-+ exit(0);
-+ }
+}
+
-+static void refs_advertise_read_refs(struct packet_reader *reader)
++static void hide_refs_proc(struct packet_reader *reader)
+{
+ const char *p;
+ struct strbuf buf = STRBUF_INIT;
+ enum packet_read_status status;
-+ int filter_ok = 0;
+
+ if (!first_ref) {
+ if (die_read_first_ref)
@@ t/helper/test-refs-advertise.c (new)
+ strbuf_addstr(&buf, reader->line);
+ }
+
-+ p = buf.buf;
-+
-+ if (unsorted_string_list_has_string(&returns, p)) {
-+ filter_ok = 1;
-+ }
-+
-+ // if it's a ref filter request, we response without the commit id
-+ if ((buf.len > (hash_size + 1)) && (strncmp("obj ", buf.buf, 4)))
-+ strbuf_setlen(&buf, buf.len - (hash_size + 1));
-+
-+ if (filter_ok) {
-+ packet_write_fmt(1, "%s %s\n", "ok", p);
-+ } else {
-+ packet_write_fmt(1, "%s %s\n", "ng", p);
++ p = strchr(buf.buf, ':');
++ if (unsorted_string_list_has_string(&returns, p + 1)) {
++ packet_write_fmt(1, "hide");
+ }
+
-+ if (die_filter_refs)
-+ die("die with the --die-filter-refs option");
++ if (die_after_proc_ref)
++ die("die with the --die-after-proc-refs option");
+
+ packet_flush(1);
+}
+
-+int cmd__refs_advertise(int argc, const char **argv) {
++int cmd__hide_refs(int argc, const char **argv) {
+ int nongit_ok = 0;
+ struct packet_reader reader;
+ const char *value = NULL;
+ struct option options[] = {
-+ OPT_BOOL(0, "can-upload-pack", &can_upload_pack,
-+ "support upload-pack command"),
-+ OPT_BOOL(0, "can-receive-pack", &can_receive_pack,
-+ "support upload-pack command"),
-+ OPT_BOOL(0, "can-ls-refs", &can_ls_refs,
-+ "support ls-refs command"),
+ OPT_BOOL(0, "die-read-version", &die_read_version,
+ "die when reading version"),
+ OPT_BOOL(0, "die-write-version", &die_write_version,
@@ t/helper/test-refs-advertise.c (new)
+ "die when reading first reference"),
+ OPT_BOOL(0, "die-read-second-ref", &die_read_second_ref,
+ "die when reading second reference"),
-+ OPT_BOOL(0, "die-filter-refs", &die_filter_refs,
-+ "die when filtering refs"),
-+ OPT_STRING_LIST('r', "return", &returns, "ref<SP>$refname<SP>$oid|obj<SP>$oid",
-+ "refs or objects that can advertise"),
++ OPT_BOOL(0, "die-after-proc-refs", &die_after_proc_ref,
++ "die after proc ref"),
++ OPT_STRING_LIST('r', "reserved", &returns, "refs-to-force-hidden",
++ "refs that will force hide"),
+ OPT__VERBOSE(&verbose, "be verbose"),
+ OPT_INTEGER('V', "version", &version,
+ "use this protocol version number"),
@@ t/helper/test-refs-advertise.c (new)
+
+ setup_git_directory_gently(&nongit_ok);
+
-+ argc = parse_options(argc, argv, "test-tools", options, refs_advertise_usage, 0);
++ argc = parse_options(argc, argv, "test-tools", options, hide_refs_usage, 0);
+ if (argc > 0)
-+ usage_msg_opt("Too many arguments.", refs_advertise_usage, options);
++ usage_msg_opt("Too many arguments.", hide_refs_usage, options);
+
+ packet_reader_init(&reader, 0, NULL, 0, PACKET_READ_CHOMP_NEWLINE | PACKET_READ_GENTLE_ON_EOF);
+
@@ t/helper/test-refs-advertise.c (new)
+ hash_size = GIT_SHA256_HEXSZ;
+ }
+
-+ refs_advertise_verison(&reader);
++ hide_refs_verison(&reader);
+ for (;;) {
-+ refs_advertise_read_refs(&reader);
++ hide_refs_proc(&reader);
+ }
+
+ return 0;
@@ t/helper/test-tool.c: static struct test_cmd cmds[] = {
{ "regex", cmd__regex },
{ "repository", cmd__repository },
{ "revision-walking", cmd__revision_walking },
-+ { "refs-advertise", cmd__refs_advertise },
++ { "hide-refs", cmd__hide_refs },
{ "run-command", cmd__run_command },
{ "scrap-cache-tree", cmd__scrap_cache_tree },
{ "serve-v2", cmd__serve_v2 },
@@ t/helper/test-tool.h: int cmd__reftable(int argc, const char **argv);
int cmd__regex(int argc, const char **argv);
int cmd__repository(int argc, const char **argv);
int cmd__revision_walking(int argc, const char **argv);
-+int cmd__refs_advertise(int argc, const char **argv);
++int cmd__hide_refs(int argc, const char **argv);
int cmd__run_command(int argc, const char **argv);
int cmd__scrap_cache_tree(int argc, const char **argv);
int cmd__serve_v2(int argc, const char **argv);
## upload-pack.c ##
@@
- #include "commit-graph.h"
- #include "commit-reach.h"
- #include "shallow.h"
-+#include "refs/refs-advertise.h"
-
- /* Remember to update object flag allocation in object.h */
- #define THEY_HAVE (1u << 11)
-@@ upload-pack.c: static void receive_needs(struct upload_pack_data *data,
- }
-
- o = parse_object(the_repository, &oid_buf);
-- if (!o) {
-+ if ((!o) || (filter_advertise_object(&oid_buf))) {
- packet_writer_error(&data->writer,
- "upload-pack: not our ref %s",
- oid_to_hex(&oid_buf));
-@@ upload-pack.c: static int mark_our_ref(const char *refname, const char *refname_full,
- o->flags |= HIDDEN_REF;
- return 1;
- }
-+
-+ if (filter_advertise_ref(refname, oid)) {
-+ o->flags |= HIDDEN_REF;
-+ return 1;
-+ }
-+
- o->flags |= OUR_REF;
- return 0;
- }
-@@ upload-pack.c: static void format_symref_info(struct strbuf *buf, struct string_list *symref)
+ #define NOT_SHALLOW (1u << 17)
+ #define CLIENT_SHALLOW (1u << 18)
+ #define HIDDEN_REF (1u << 19)
++#define HIDDEN_REF_FORCE (1u << 20)
- if (!symref->nr)
- return;
-- for_each_string_list_item(item, symref)
-- strbuf_addf(buf, " symref=%s:%s", item->string, (char *)item->util);
-+ for_each_string_list_item(item, symref) {
-+ if (!filter_advertise_ref((char *)item->util, NULL))
-+ strbuf_addf(buf, " symref=%s:%s", item->string, (char *)item->util);
-+ }
- }
-
- static void format_session_id(struct strbuf *buf, struct upload_pack_data *d) {
-@@ upload-pack.c: static int send_ref(const char *refname, const struct object_id *oid,
- static const char *capabilities = "multi_ack thin-pack side-band"
- " side-band-64k ofs-delta shallow deepen-since deepen-not"
- " deepen-relative no-progress include-tag multi_ack_detailed";
-- const char *refname_nons = strip_namespace(refname);
- struct object_id peeled;
- struct upload_pack_data *data = cb_data;
-+ const char *refname_nons = strip_namespace(refname);
-+ const char *refname_to_filter = refname_nons;
-
-- if (mark_our_ref(refname_nons, refname, oid))
-+ if (!strcmp(refname_nons, "HEAD")) {
-+ struct string_list_item *item = string_list_lookup(&data->symref, "HEAD");
-+ if (item) {
-+ refname_to_filter = (const char *)item->util;
-+ }
-+ }
-+
-+ if (mark_our_ref(refname_to_filter, refname, oid))
- return 0;
+-#define ALL_FLAGS (THEY_HAVE | OUR_REF | WANTED | COMMON_KNOWN | SHALLOW | \
+- NOT_SHALLOW | CLIENT_SHALLOW | HIDDEN_REF)
++#define ALL_FLAGS (THEY_HAVE |WANTED | COMMON_KNOWN | SHALLOW | \
++ NOT_SHALLOW | CLIENT_SHALLOW)
- if (capabilities) {
-@@ upload-pack.c: static void get_upload_pack_config(struct upload_pack_data *data)
- git_protected_config(upload_pack_protected_config, data);
+ /* Enum for allowed unadvertised object request (UOR) */
+ enum allow_uor {
+@@ upload-pack.c: static void receive_needs(struct upload_pack_data *data,
+ packet_flush(1);
}
-+static void clean_refs_advertise_filter(void) {
-+ clean_advertise_refs_filter();
-+}
-+
- void upload_pack(const int advertise_refs, const int stateless_rpc,
- const int timeout)
+-/* return non-zero if the ref is hidden, otherwise 0 */
+-static int mark_our_ref(const char *refname, const char *refname_full,
+- const struct object_id *oid)
+-{
+- struct object *o = lookup_unknown_object(the_repository, oid);
+-
+- if (ref_is_hidden(refname, refname_full)) {
+- o->flags |= HIDDEN_REF;
+- return 1;
+- }
+- o->flags |= OUR_REF;
+- return 0;
+-}
+-
+ static int check_ref(const char *refname_full, const struct object_id *oid,
+ int flag, void *cb_data)
{
- struct packet_reader reader;
- struct upload_pack_data data;
-
-+ create_advertise_refs_filter("git-upload-pack");
-+ atexit(clean_refs_advertise_filter);
-+
- upload_pack_data_init(&data);
- get_upload_pack_config(&data);
-
-@@ upload-pack.c: static int parse_want(struct packet_writer *writer, const char *line,
- else
- o = parse_object(the_repository, &oid);
-
-- if (!o) {
-+ if ((!o) || (filter_advertise_object(&oid))) {
- packet_writer_error(writer,
- "upload-pack: not our ref %s",
- oid_to_hex(&oid));
@@ upload-pack.c: static int parse_want_ref(struct packet_writer *writer, const char *line,
strbuf_addf(&refname, "%s%s", get_git_namespace(), refname_nons);
if (ref_is_hidden(refname_nons, refname.buf) ||
-- read_ref(refname.buf, &oid)) {
-+ read_ref(refname.buf, &oid) ||
-+ filter_advertise_ref(refname_nons, &oid)) {
++ ref_is_force_hidden(refname_nons, refname.buf) ||
+ read_ref(refname.buf, &oid)) {
packet_writer_error(writer, "unknown ref %s", refname_nons);
die("unknown ref %s", refname_nons);
- }
+@@ upload-pack.c: enum fetch_state {
+ FETCH_DONE,
+ };
+
++static int lazy_load_hidden = 0;
++// lazy load hidden refs for protocol V2
++void lazy_load_hidden_refs(void) {
++ lazy_load_hidden = 1;
++}
++
+ int upload_pack_v2(struct repository *r, struct packet_reader *request)
+ {
+ enum fetch_state state = FETCH_PROCESS_ARGS;
@@ upload-pack.c: int upload_pack_v2(struct repository *r, struct packet_reader *request)
+ state = FETCH_DONE;
+ break;
+ case FETCH_SEND_PACK:
++ if (lazy_load_hidden) {
++ head_ref_namespaced(check_ref, NULL);
++ for_each_namespaced_ref(check_ref, NULL);
++ }
++ if (has_force_hidden_refs())
++ check_non_tip(&data);
+ send_wanted_ref_info(&data);
+ send_shallow_info(&data);
- clear_object_flags(ALL_FLAGS);
+
+ ## upload-pack.h ##
+@@ upload-pack.h: struct strbuf;
+ int upload_pack_advertise(struct repository *r,
+ struct strbuf *value);
-+ create_advertise_refs_filter("git-upload-pack");
-+ atexit(clean_refs_advertise_filter);
-+
- upload_pack_data_init(&data);
- data.use_sideband = LARGE_PACKET_MAX;
- get_upload_pack_config(&data);
++void lazy_load_hidden_refs(void);
+ #endif /* UPLOAD_PACK_H */
2: 88504b3a08a ! 2: 72333c12c3f t1419: add test cases for refs-advertise hook
@@ Metadata
Author: Sun Chao <sunchao9@huawei.com>
## Commit message ##
- t1419: add test cases for refs-advertise hook
+ t1419: add test cases for hide-refs hook
- Add test cases for the new 'refs-advertise' hook which is used to
- filter the references during reference discovery phase and commit
- fetching phase.
+ Add test cases for the new 'hide-refs' hook which is used to
+ filter the references during reference discovery phase.
Signed-off-by: Sun Chao <sunchao9@huawei.com>
- ## t/t1419-refs-advertise-hooks.sh (new) ##
+ ## t/t1419-hide-refs-hook.sh (new) ##
@@
+#!/bin/sh
+#
+# Copyright (c) 2022 Sun Chao
+#
+
-+test_description='Test refs-advertise hook'
++test_description='Test hide-refs hook'
+
+GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
+export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
@@ t/t1419-refs-advertise-hooks.sh (new)
+ '
+}
+
-+run_refs_advertise_hook_tests() {
++run_hide_refs_hook_tests() {
+ case $1 in
+ http)
+ PROTOCOL="HTTP protocol"
@@ t/t1419-refs-advertise-hooks.sh (new)
+
+ GIT_TEST_PROTOCOL_VERSION=$2
+
-+ # Run test cases for 'refs-advertise' hook
++ # Run test cases for 'hide-refs' hook
+ for t in "$TEST_DIRECTORY"/t1419/test-*.sh
+ do
+ # Initialize the bare_repo repository and work_repo
@@ t/t1419-refs-advertise-hooks.sh (new)
+ cp -rf work_repo work_repo.dump
+
+ git -C bare_repo.git config --local http.receivepack true
++ git -C bare_repo.git config --add transfer.hiderefs force:HEAD
++ git -C bare_repo.git config --add transfer.hiderefs force:refs
+ cp -rf bare_repo.git bare_repo.git.dump
+
+ if test "$1" = "http"; then
@@ t/t1419-refs-advertise-hooks.sh (new)
+# Load test cases that only need to be executed once.
+for t in "$TEST_DIRECTORY"/t1419/once-*.sh
+do
++ git -C "$BAREREPO_GIT_DIR" config --add transfer.hiderefs force:HEAD
++ git -C "$BAREREPO_GIT_DIR" config --add transfer.hiderefs force:refs
+ . "$t"
+done
+
+for protocol in 1 2
+do
-+ # Run test cases for 'refs-advertise' hook on local file protocol.
-+ run_refs_advertise_hook_tests local $protocol
++ # Run test cases for 'hide-refs' hook on local file protocol.
++ run_hide_refs_hook_tests local $protocol
+done
+
+ROOT_PATH="$PWD"
@@ t/t1419-refs-advertise-hooks.sh (new)
+start_httpd
+set_askpass user@host pass@host
+
-+# Run test cases for 'refs-advertise' hook on HTTP protocol.
++# Run test cases for 'hide-refs' hook on HTTP protocol.
+for protocol in 1 2
+do
-+ run_refs_advertise_hook_tests http $protocol
++ run_hide_refs_hook_tests http $protocol
+done
+
+test_done
@@ t/t1419/common-functions.sh (new)
+ -e "s#$BAREREPO_PREFIX/bare_repo.git#<URL/of/bare_repo.git>#"
+}
+
-+filter_out_refs_advertise_output() {
++filter_out_hide_refs_output() {
+ make_user_friendly_and_stable_output | sed 's/^[0-9a-f]\{4\}//g'
+}
+
@@ t/t1419/common-functions.sh (new)
+ test_cmp show-ref.expect show-ref.filtered
+}
- ## t/t1419/once-0000-abnormal-refs-advertise-hook.sh (new) ##
+ ## t/t1419/once-0000-abnormal-hide-refs-hook.sh (new) ##
@@
-+test_expect_success "builtin protocol (protocol: 1): setup refs-advertise hook which die when read version" '
-+ write_script "$BAREREPO_GIT_DIR/hooks/refs-advertise" <<-EOF
-+ test-tool refs-advertise \
-+ --can-upload-pack \
-+ --can-receive-pack \
-+ --can-ls-refs \
-+ --die-read-version
++test_expect_success "builtin protocol (protocol: 1): setup hide-refs hook which die when read version" '
++ write_script "$BAREREPO_GIT_DIR/hooks/hide-refs" <<-EOF
++ test-tool hide-refs \
++ --die-read-version \
++ -r refs/heads/main
+ EOF
+'
+
-+test_expect_success "builtin protocol (protocol: 1): upload-pack --advertise-refs while refs-advertise hook die when read version" '
++test_expect_success "builtin protocol (protocol: 1): upload-pack --advertise-refs while hide-refs hook die when read version" '
+ test_must_fail git -c protocol.version=1 upload-pack --advertise-refs "$BAREREPO_URL" >out 2>&1 &&
+ cat out | grep "fatal: " | make_user_friendly_and_stable_output >actual &&
+ format_and_save_expect <<-EOF &&
+ fatal: die with the --die-read-version option
-+ fatal: can not read version message from hook refs-advertise
++ fatal: can not read version message from hook hide-refs
+ EOF
+ test_cmp expect actual
+'
+
-+test_expect_success "builtin protocol (protocol: 1): setup refs-advertise hook which die when write version" '
-+ write_script "$BAREREPO_GIT_DIR/hooks/refs-advertise" <<-EOF
-+ test-tool refs-advertise \
-+ --can-upload-pack \
-+ --can-receive-pack \
-+ --can-ls-refs \
-+ --die-write-version
++test_expect_success "builtin protocol (protocol: 1): setup hide-refs hook which die when write version" '
++ write_script "$BAREREPO_GIT_DIR/hooks/hide-refs" <<-EOF
++ test-tool hide-refs --die-write-version
+ EOF
+'
+
-+test_expect_success "builtin protocol (protocol: 1): upload-pack --advertise-refs while refs-advertise hook die when write version" '
++test_expect_success "builtin protocol (protocol: 1): upload-pack --advertise-refs while hide-refs hook die when write version" '
+ test_must_fail git -c protocol.version=1 upload-pack --advertise-refs "$BAREREPO_URL" >out 2>&1 &&
+ cat out | grep "fatal: " | make_user_friendly_and_stable_output >actual &&
+ format_and_save_expect <<-EOF &&
+ fatal: die with the --die-write-version option
-+ fatal: can not read version message from hook refs-advertise
++ fatal: can not read version message from hook hide-refs
+ EOF
+ test_cmp expect actual
+'
+
-+test_expect_success "builtin protocol (protocol: 1): setup refs-advertise hook which die when read first filter request" '
-+ write_script "$BAREREPO_GIT_DIR/hooks/refs-advertise" <<-EOF
-+ test-tool refs-advertise \
-+ --can-upload-pack \
-+ --can-receive-pack \
-+ --can-ls-refs \
-+ --die-read-first-ref
++test_expect_success "builtin protocol (protocol: 1): setup hide-refs hook which die when read first filter request" '
++ write_script "$BAREREPO_GIT_DIR/hooks/hide-refs" <<-EOF
++ test-tool hide-refs --die-read-first-ref
+ EOF
+'
+
-+test_expect_success "builtin protocol (protocol: 1): upload-pack --advertise-refs while refs-advertise hook die when read first filter request" '
++test_expect_success "builtin protocol (protocol: 1): upload-pack --advertise-refs while hide-refs hook die when read first filter request" '
+ test_must_fail git -c protocol.version=1 upload-pack --advertise-refs "$BAREREPO_URL" >out 2>&1 &&
+ cat out | grep "fatal: " | make_user_friendly_and_stable_output >actual &&
+ format_and_save_expect <<-EOF &&
+ fatal: die with the --die-read-first-ref option
-+ fatal: hook refs-advertise died abnormally
++ fatal: hook hide-refs died abnormally
+ EOF
+ test_cmp expect actual
+'
+
-+test_expect_success "builtin protocol (protocol: 1): setup refs-advertise hook which die when read second filter request" '
-+ write_script "$BAREREPO_GIT_DIR/hooks/refs-advertise" <<-EOF
-+ test-tool refs-advertise \
-+ --can-upload-pack \
-+ --can-receive-pack \
-+ --can-ls-refs \
-+ --die-read-second-ref
++test_expect_success "builtin protocol (protocol: 1): setup hide-refs hook which die when read second filter request" '
++ write_script "$BAREREPO_GIT_DIR/hooks/hide-refs" <<-EOF
++ test-tool hide-refs --die-read-second-ref
+ EOF
+'
+
-+test_expect_success "builtin protocol (protocol: 1): upload-pack --advertise-refs while refs-advertise hook die when read second filter request" '
++test_expect_success "builtin protocol (protocol: 1): upload-pack --advertise-refs while hide-refs hook die when read second filter request" '
+ test_must_fail git -c protocol.version=1 upload-pack --advertise-refs "$BAREREPO_URL" >out 2>&1 &&
+ cat out | grep "fatal: " | make_user_friendly_and_stable_output >actual &&
+ format_and_save_expect <<-EOF &&
+ fatal: die with the --die-read-second-ref option
-+ fatal: hook refs-advertise died abnormally
++ fatal: hook hide-refs died abnormally
+ EOF
+ test_cmp expect actual
+'
+
-+test_expect_success "builtin protocol (protocol: 1): setup refs-advertise hook which die while filtring refs" '
-+ write_script "$BAREREPO_GIT_DIR/hooks/refs-advertise" <<-EOF
-+ test-tool refs-advertise \
-+ --can-upload-pack \
-+ --can-receive-pack \
-+ --can-ls-refs \
-+ --die-filter-refs
++test_expect_success "builtin protocol (protocol: 1): setup hide-refs hook which die while filtring refs" '
++ write_script "$BAREREPO_GIT_DIR/hooks/hide-refs" <<-EOF
++ test-tool hide-refs --die-after-proc-refs
+ EOF
+'
+
-+test_expect_success "builtin protocol (protocol: 1): upload-pack --advertise-refs while refs-advertise hook die while filtring refs" '
++test_expect_success "builtin protocol (protocol: 1): upload-pack --advertise-refs while hide-refs hook die while filtring refs" '
+ test_must_fail git -c protocol.version=1 upload-pack --advertise-refs "$BAREREPO_URL" >out 2>&1 &&
+ cat out | grep "fatal: " | make_user_friendly_and_stable_output >actual &&
+ format_and_save_expect <<-EOF &&
-+ fatal: die with the --die-filter-refs option
-+ fatal: hook refs-advertise died abnormally
++ fatal: die with the --die-after-proc-refs option
++ fatal: hook hide-refs died abnormally
+ EOF
+ test_cmp expect actual
+'
+
-+test_expect_success "builtin protocol (protocol: 2): setup refs-advertise hook which die when read version" '
-+ write_script "$BAREREPO_GIT_DIR/hooks/refs-advertise" <<-EOF
-+ test-tool refs-advertise \
-+ --can-upload-pack \
-+ --can-receive-pack \
-+ --can-ls-refs \
-+ --die-read-version
++test_expect_success "builtin protocol (protocol: 2): setup hide-refs hook which die when read version" '
++ write_script "$BAREREPO_GIT_DIR/hooks/hide-refs" <<-EOF
++ test-tool hide-refs --die-read-version
+ EOF
+'
+
-+test_expect_success "builtin protocol (protocol: 2): upload-pack --advertise-refs while refs-advertise hook die when read version" '
++test_expect_success "builtin protocol (protocol: 2): upload-pack --advertise-refs while hide-refs hook die when read version" '
+ test_must_fail git -c protocol.version=2 upload-pack --advertise-refs "$BAREREPO_URL" >out 2>&1 &&
+ cat out | grep "fatal: " | make_user_friendly_and_stable_output >actual &&
+ format_and_save_expect <<-EOF &&
+ fatal: die with the --die-read-version option
-+ fatal: can not read version message from hook refs-advertise
++ fatal: can not read version message from hook hide-refs
+ EOF
+ test_cmp expect actual
+'
+
-+test_expect_success "builtin protocol (protocol: 2): setup refs-advertise hook which die when write version" '
-+ write_script "$BAREREPO_GIT_DIR/hooks/refs-advertise" <<-EOF
-+ test-tool refs-advertise \
-+ --can-upload-pack \
-+ --can-receive-pack \
-+ --can-ls-refs \
-+ --die-write-version
++test_expect_success "builtin protocol (protocol: 2): setup hide-refs hook which die when write version" '
++ write_script "$BAREREPO_GIT_DIR/hooks/hide-refs" <<-EOF
++ test-tool hide-refs --die-write-version
+ EOF
+'
+
-+test_expect_success "builtin protocol (protocol: 2): upload-pack --advertise-refs while refs-advertise hook die when write version" '
++test_expect_success "builtin protocol (protocol: 2): upload-pack --advertise-refs while hide-refs hook die when write version" '
+ test_must_fail git -c protocol.version=2 upload-pack --advertise-refs "$BAREREPO_URL" >out 2>&1 &&
+ cat out | grep "fatal: " | make_user_friendly_and_stable_output >actual &&
+ format_and_save_expect <<-EOF &&
+ fatal: die with the --die-write-version option
-+ fatal: can not read version message from hook refs-advertise
++ fatal: can not read version message from hook hide-refs
+ EOF
+ test_cmp expect actual
+'
+
-+test_expect_success "builtin protocol (protocol: 2): setup refs-advertise hook which die when read first filter request" '
-+ write_script "$BAREREPO_GIT_DIR/hooks/refs-advertise" <<-EOF
-+ test-tool refs-advertise \
-+ --can-upload-pack \
-+ --can-receive-pack \
-+ --can-ls-refs \
-+ --die-read-first-ref
++test_expect_success "builtin protocol (protocol: 2): setup hide-refs hook which die when read first filter request" '
++ write_script "$BAREREPO_GIT_DIR/hooks/hide-refs" <<-EOF
++ test-tool hide-refs --die-read-first-ref
+ EOF
+'
+
-+test_expect_success "builtin protocol (protocol: 2): upload-pack --advertise-refs while refs-advertise hook die when read first filter request" '
++test_expect_success "builtin protocol (protocol: 2): upload-pack --advertise-refs while hide-refs hook die when read first filter request" '
+ test_must_fail git -c protocol.version=2 upload-pack --advertise-refs "$BAREREPO_URL" >out 2>&1 &&
+ cat out | grep "fatal: " | make_user_friendly_and_stable_output >actual &&
+ format_and_save_expect <<-EOF &&
+ fatal: die with the --die-read-first-ref option
-+ fatal: hook refs-advertise died abnormally
++ fatal: hook hide-refs died abnormally
+ EOF
+ test_cmp expect actual
+'
+
-+test_expect_success "builtin protocol (protocol: 2): setup refs-advertise hook which die when read second filter request" '
-+ write_script "$BAREREPO_GIT_DIR/hooks/refs-advertise" <<-EOF
-+ test-tool refs-advertise \
-+ --can-upload-pack \
-+ --can-receive-pack \
-+ --can-ls-refs \
-+ --die-read-second-ref
++test_expect_success "builtin protocol (protocol: 2): setup hide-refs hook which die when read second filter request" '
++ write_script "$BAREREPO_GIT_DIR/hooks/hide-refs" <<-EOF
++ test-tool hide-refs --die-read-second-ref
+ EOF
+'
+
-+test_expect_success "builtin protocol (protocol: 2): upload-pack --advertise-refs while refs-advertise hook die when read second filter request" '
++test_expect_success "builtin protocol (protocol: 2): upload-pack --advertise-refs while hide-refs hook die when read second filter request" '
+ test_must_fail git -c protocol.version=2 upload-pack --advertise-refs "$BAREREPO_URL" >out 2>&1 &&
+ cat out | grep "fatal: " | make_user_friendly_and_stable_output >actual &&
+ format_and_save_expect <<-EOF &&
+ fatal: die with the --die-read-second-ref option
-+ fatal: hook refs-advertise died abnormally
++ fatal: hook hide-refs died abnormally
+ EOF
+ test_cmp expect actual
+'
+
-+test_expect_success "builtin protocol (protocol: 2): setup refs-advertise hook which die while filtring refs" '
-+ write_script "$BAREREPO_GIT_DIR/hooks/refs-advertise" <<-EOF
-+ test-tool refs-advertise \
-+ --can-upload-pack \
-+ --can-receive-pack \
-+ --can-ls-refs \
-+ --die-filter-refs
++test_expect_success "builtin protocol (protocol: 2): setup hide-refs hook which die while filtring refs" '
++ write_script "$BAREREPO_GIT_DIR/hooks/hide-refs" <<-EOF
++ test-tool hide-refs --die-after-proc-refs
+ EOF
+'
+
-+test_expect_success "builtin protocol (protocol: 2): upload-pack --advertise-refs while refs-advertise hook die while filtring refs" '
++test_expect_success "builtin protocol (protocol: 2): upload-pack --advertise-refs while hide-refs hook die while filtring refs" '
+ test_must_fail git -c protocol.version=2 upload-pack --advertise-refs "$BAREREPO_URL" >out 2>&1 &&
+ cat out | grep "fatal: " | make_user_friendly_and_stable_output >actual &&
+ format_and_save_expect <<-EOF &&
-+ fatal: die with the --die-filter-refs option
-+ fatal: hook refs-advertise died abnormally
++ fatal: die with the --die-after-proc-refs option
++ fatal: hook hide-refs died abnormally
+ EOF
+ test_cmp expect actual
+'
- ## t/t1419/test-0000-standard-git-clone.sh (new) ##
+ ## t/t1419/test-0001-ls-remote-with-hide-refs-hook.sh (new) ##
@@
-+test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): mirror clone" '
-+ rm -rf local.git &&
-+ git -c protocol.version=$GIT_TEST_PROTOCOL_VERSION clone --mirror "$BAREREPO_URL" local.git &&
-+ git -c protocol.version=$GIT_TEST_PROTOCOL_VERSION -C local.git show-ref -d >out 2>&1 &&
-+ refs_num=$(cat out | wc -l) &&
-+ make_user_friendly_and_stable_output <out >actual &&
-+ format_and_save_expect <<-EOF &&
-+ <COMMIT-A> refs/heads/dev
-+ <COMMIT-B> refs/heads/main
-+ <COMMIT-C> refs/pull-requests/1/head
-+ <COMMIT-TAG-v123> refs/tags/v123
-+ <COMMIT-D> refs/tags/v123^{}
++test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): setup hide-refs hook which hide no refs" '
++ write_script "$BAREREPO_GIT_DIR/hooks/hide-refs" <<-EOF
++ test-tool hide-refs
+ EOF
-+ test_cmp expect actual
+'
+
-+test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): ls-remote" '
++test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): ls-remote while hide-refs hook hide no refs" '
+ git -c protocol.version=$GIT_TEST_PROTOCOL_VERSION ls-remote "$BAREREPO_URL" >out 2>&1 &&
-+ refs_num=$(cat out | wc -l) &&
+ make_user_friendly_and_stable_output <out >actual &&
+ format_and_save_expect <<-EOF &&
+ <COMMIT-B> HEAD
@@ t/t1419/test-0000-standard-git-clone.sh (new)
+ test_cmp expect actual
+'
+
-+test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): upload-pack" '
-+ git -c protocol.version=$GIT_TEST_PROTOCOL_VERSION upload-pack --advertise-refs "$BAREREPO_GIT_DIR" >out 2>&1 &&
-+ filter_out_refs_advertise_output <out >actual &&
-+ format_and_save_expect <<-EOF &&
-+ <COMMIT-B> HEAD
-+ <COMMIT-A> refs/heads/dev
-+ <COMMIT-B> refs/heads/main
-+ <COMMIT-C> refs/pull-requests/1/head
-+ <COMMIT-TAG-v123> refs/tags/v123
-+ <COMMIT-D> refs/tags/v123^{}
-+ EOF
-+ test_cmp expect actual
-+'
-+
-+test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): receive-pack" '
-+ git -c protocol.version=$GIT_TEST_PROTOCOL_VERSION receive-pack --advertise-refs "$BAREREPO_GIT_DIR" >out 2>&1 &&
-+ filter_out_refs_advertise_output <out >actual &&
-+ format_and_save_expect <<-EOF &&
-+ <COMMIT-A> refs/heads/dev
-+ <COMMIT-B> refs/heads/main
-+ <COMMIT-C> refs/pull-requests/1/head
-+ <COMMIT-TAG-v123> refs/tags/v123
-+ EOF
-+ test_cmp expect actual
-+'
-
- ## t/t1419/test-0001-standard-git-push.sh (new) ##
-@@
-+test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): push to main" '
-+ create_commits_in work_repo E &&
-+ git -c protocol.version=$GIT_TEST_PROTOCOL_VERSION -C work_repo push origin HEAD:main >out 2>&1 &&
-+ make_user_friendly_and_stable_output <out >out.tmp &&
-+ sed "s/$(get_abbrev_oid $E)[0-9a-f]*/<COMMIT-E>/g" <out.tmp >actual &&
-+ format_and_save_expect <<-EOF &&
-+ remote: # pre-receive hook Z
-+ remote: pre-receive< <COMMIT-B> <COMMIT-E> refs/heads/main Z
-+ remote: # update hook Z
-+ remote: update< refs/heads/main <COMMIT-B> <COMMIT-E> Z
-+ remote: # post-receive hook Z
-+ remote: post-receive< <COMMIT-B> <COMMIT-E> refs/heads/main Z
-+ To <URL/of/bare_repo.git>
-+ <COMMIT-B>..<COMMIT-E> HEAD -> main
-+ EOF
-+ test_cmp expect actual
-+'
-+
-+test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): push to delete ref" '
-+ git -c protocol.version=$GIT_TEST_PROTOCOL_VERSION -C work_repo push origin :dev >out 2>&1 &&
-+ make_user_friendly_and_stable_output <out >out.tmp &&
-+ sed "s/$(get_abbrev_oid $E)[0-9a-f]*/<COMMIT-E>/g" <out.tmp >actual &&
-+ format_and_save_expect <<-EOF &&
-+ remote: # pre-receive hook Z
-+ remote: pre-receive< <COMMIT-A> <ZERO-OID> refs/heads/dev Z
-+ remote: # update hook Z
-+ remote: update< refs/heads/dev <COMMIT-A> <ZERO-OID> Z
-+ remote: # post-receive hook Z
-+ remote: post-receive< <COMMIT-A> <ZERO-OID> refs/heads/dev Z
-+ To <URL/of/bare_repo.git>
-+ - [deleted] dev
-+ EOF
-+ test_cmp expect actual
-+'
-
- ## t/t1419/test-0002-ls-remote-with-refs-advertise-hook.sh (new) ##
-@@
-+test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): setup refs-advertise hook which handle no command" '
-+ write_script "$BAREREPO_GIT_DIR/hooks/refs-advertise" <<-EOF
-+ test-tool refs-advertise
++test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): setup hide-refs hook which hide all refs" '
++ write_script "$BAREREPO_GIT_DIR/hooks/hide-refs" <<-EOF
++ test-tool hide-refs \
++ -r "HEAD" \
++ -r "refs/heads/dev" \
++ -r "refs/heads/main" \
++ -r "refs/pull-requests/1/head" \
++ -r "refs/tags/v123"
+ EOF
+'
+
-+test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): ls-remote while refs-advertise hook handle no command" '
++test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): ls-remote while hide-refs hook hide all refs" '
+ git -c protocol.version=$GIT_TEST_PROTOCOL_VERSION ls-remote "$BAREREPO_URL" >out 2>&1 &&
+ make_user_friendly_and_stable_output <out >actual &&
+ format_and_save_expect <<-EOF &&
-+ <COMMIT-B> HEAD
-+ <COMMIT-A> refs/heads/dev
-+ <COMMIT-B> refs/heads/main
-+ <COMMIT-C> refs/pull-requests/1/head
-+ <COMMIT-TAG-v123> refs/tags/v123
-+ <COMMIT-D> refs/tags/v123^{}
+ EOF
+ test_cmp expect actual
+'
+
-+test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): setup refs-advertise hook which advertise all refs" '
-+ write_script "$BAREREPO_GIT_DIR/hooks/refs-advertise" <<-EOF
-+ test-tool refs-advertise \
-+ --can-upload-pack \
-+ --can-ls-refs \
-+ -r "ref refs/heads/dev $A" \
-+ -r "obj $A" \
-+ -r "ref refs/heads/main $B" \
-+ -r "obj $B" \
-+ -r "ref refs/pull-requests/1/head $C" \
-+ -r "obj $C" \
-+ -r "ref refs/tags/v123 $TAG" \
-+ -r "obj $D"
++test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): setup hide-refs hook which hide branches" '
++ write_script "$BAREREPO_GIT_DIR/hooks/hide-refs" <<-EOF
++ test-tool hide-refs \
++ -r "HEAD" \
++ -r "refs/heads/dev" \
++ -r "refs/heads/main"
+ EOF
+'
+
-+test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): ls-remote all refs" '
++test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): ls-remote while hide-refs hook hide branches" '
+ git -c protocol.version=$GIT_TEST_PROTOCOL_VERSION ls-remote "$BAREREPO_URL" >out 2>&1 &&
+ make_user_friendly_and_stable_output <out >actual &&
+ format_and_save_expect <<-EOF &&
-+ <COMMIT-B> HEAD
-+ <COMMIT-A> refs/heads/dev
-+ <COMMIT-B> refs/heads/main
+ <COMMIT-C> refs/pull-requests/1/head
+ <COMMIT-TAG-v123> refs/tags/v123
+ <COMMIT-D> refs/tags/v123^{}
@@ t/t1419/test-0002-ls-remote-with-refs-advertise-hook.sh (new)
+ test_cmp expect actual
+'
+
-+test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): setup refs-advertise hook which advertise branches" '
-+ write_script "$BAREREPO_GIT_DIR/hooks/refs-advertise" <<-EOF
-+ test-tool refs-advertise \
-+ --can-upload-pack \
-+ --can-ls-refs \
-+ -r "ref refs/heads/dev $A" \
-+ -r "obj $A" \
-+ -r "ref refs/heads/main $B" \
-+ -r "obj $B"
++test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): setup hide-refs hook which hide pull refs and tags" '
++ write_script "$BAREREPO_GIT_DIR/hooks/hide-refs" <<-EOF
++ test-tool hide-refs \
++ -r "refs/pull-requests/1/head" \
++ -r "refs/tags/v123"
+ EOF
+'
+
-+test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): ls-remote branches" '
++test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): ls-remote while hide-refs hook hide pull refs and tags" '
+ git -c protocol.version=$GIT_TEST_PROTOCOL_VERSION ls-remote "$BAREREPO_URL" >out 2>&1 &&
+ make_user_friendly_and_stable_output <out >actual &&
+ format_and_save_expect <<-EOF &&
@@ t/t1419/test-0002-ls-remote-with-refs-advertise-hook.sh (new)
+ <COMMIT-B> refs/heads/main
+ EOF
+ test_cmp expect actual
-+'
-+
-+test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): setup refs-advertise hook which advertise pull refs and tags" '
-+ write_script "$BAREREPO_GIT_DIR/hooks/refs-advertise" <<-EOF
-+ test-tool refs-advertise \
-+ --can-upload-pack \
-+ --can-ls-refs \
-+ -r "ref refs/pull-requests/1/head $C" \
-+ -r "obj $C" \
-+ -r "ref refs/tags/v123 $TAG" \
-+ -r "obj $D"
-+ EOF
-+'
-+
-+test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): ls-remote pull refs and tags" '
-+ git -c protocol.version=$GIT_TEST_PROTOCOL_VERSION ls-remote "$BAREREPO_URL" >out 2>&1 &&
-+ make_user_friendly_and_stable_output <out >actual &&
-+ format_and_save_expect <<-EOF &&
-+ <COMMIT-C> refs/pull-requests/1/head
-+ <COMMIT-TAG-v123> refs/tags/v123
-+ <COMMIT-D> refs/tags/v123^{}
-+ EOF
-+ test_cmp expect actual
+'
- ## t/t1419/test-0003-upload-pack-with-refs-advertise-hook.sh (new) ##
+ ## t/t1419/test-0002-upload-pack-with-hide-refs-hook.sh (new) ##
@@
-+test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): setup refs-advertise hook which handle no command" '
-+ write_script "$BAREREPO_GIT_DIR/hooks/refs-advertise" <<-EOF
-+ test-tool refs-advertise
++test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): setup hide-refs hook which hide no refs" '
++ write_script "$BAREREPO_GIT_DIR/hooks/hide-refs" <<-EOF
++ test-tool hide-refs
+ EOF
+'
+
-+test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): mirror clone while refs-advertise hook handle no command" '
++test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): mirror clone while hide-refs hook hide no refs" '
+ rm -rf local.git &&
+ git -c protocol.version=$GIT_TEST_PROTOCOL_VERSION clone --mirror "$BAREREPO_URL" local.git &&
-+ git -c protocol.version=$GIT_TEST_PROTOCOL_VERSION -C local.git show-ref -d >out 2>&1 &&
++ git -C local.git show-ref -d >out 2>&1 &&
+ make_user_friendly_and_stable_output <out >actual &&
+ format_and_save_expect <<-EOF &&
+ <COMMIT-A> refs/heads/dev
@@ t/t1419/test-0003-upload-pack-with-refs-advertise-hook.sh (new)
+ test_cmp expect actual
+'
+
-+test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): setup refs-advertise hook which advertise all refs" '
-+ write_script "$BAREREPO_GIT_DIR/hooks/refs-advertise" <<-EOF
-+ test-tool refs-advertise \
-+ --can-upload-pack \
-+ --can-ls-refs \
-+ -r "ref refs/heads/dev $A" \
-+ -r "obj $A" \
-+ -r "ref refs/heads/main $B" \
-+ -r "obj $B" \
-+ -r "ref refs/pull-requests/1/head $C" \
-+ -r "obj $C" \
-+ -r "ref refs/tags/v123 $TAG" \
-+ -r "obj $TAG" \
-+ -r "obj $D"
++test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): setup hide-refs hook which hide all refs" '
++ write_script "$BAREREPO_GIT_DIR/hooks/hide-refs" <<-EOF
++ test-tool hide-refs \
++ -r "HEAD" \
++ -r "refs/heads/dev" \
++ -r "refs/heads/main" \
++ -r "refs/pull-requests/1/head" \
++ -r "refs/tags/v123"
+ EOF
+'
+
-+test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): mirror clone all refs" '
++test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): mirror clone while hide-refs hide all refs" '
+ rm -rf local.git &&
+ git -c protocol.version=$GIT_TEST_PROTOCOL_VERSION clone --mirror "$BAREREPO_URL" local.git &&
-+ git -c protocol.version=$GIT_TEST_PROTOCOL_VERSION -C local.git show-ref -d >out 2>&1 &&
++ test_must_fail git -C local.git show-ref -d >out 2>&1 &&
+ make_user_friendly_and_stable_output <out >actual &&
+ format_and_save_expect <<-EOF &&
-+ <COMMIT-A> refs/heads/dev
-+ <COMMIT-B> refs/heads/main
-+ <COMMIT-C> refs/pull-requests/1/head
-+ <COMMIT-TAG-v123> refs/tags/v123
-+ <COMMIT-D> refs/tags/v123^{}
+ EOF
+ test_cmp expect actual
+'
+
-+test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): setup refs-advertise hook which advertise branches" '
-+ write_script "$BAREREPO_GIT_DIR/hooks/refs-advertise" <<-EOF
-+ test-tool refs-advertise \
-+ --can-upload-pack \
-+ --can-ls-refs \
-+ -r "ref refs/heads/dev $A" \
-+ -r "obj $A" \
-+ -r "ref refs/heads/main $B" \
-+ -r "obj $B"
++test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): setup hide-refs hook which hide branches" '
++ write_script "$BAREREPO_GIT_DIR/hooks/hide-refs" <<-EOF
++ test-tool hide-refs \
++ -r "HEAD" \
++ -r "refs/heads/dev" \
++ -r "refs/heads/main"
+ EOF
+'
+
+test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): mirror clone branches" '
+ rm -rf local.git &&
+ git -c protocol.version=$GIT_TEST_PROTOCOL_VERSION clone --mirror "$BAREREPO_URL" local.git &&
-+ git -c protocol.version=$GIT_TEST_PROTOCOL_VERSION -C local.git show-ref -d >out 2>&1 &&
++ git -C local.git show-ref -d >out 2>&1 &&
+ make_user_friendly_and_stable_output <out >actual &&
+ format_and_save_expect <<-EOF &&
-+ <COMMIT-A> refs/heads/dev
-+ <COMMIT-B> refs/heads/main
++ <COMMIT-C> refs/pull-requests/1/head
++ <COMMIT-TAG-v123> refs/tags/v123
++ <COMMIT-D> refs/tags/v123^{}
+ EOF
+ test_cmp expect actual
+'
+
-+test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): setup refs-advertise hook which advertise branches" '
-+ write_script "$BAREREPO_GIT_DIR/hooks/refs-advertise" <<-EOF
-+ test-tool refs-advertise \
-+ --can-upload-pack \
-+ --can-ls-refs \
-+ -r "ref refs/heads/dev $A" \
-+ -r "obj $A" \
-+ -r "ref refs/heads/main $B" \
-+ -r "obj $B"
++test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): setup hide-refs hook which some branches" '
++ write_script "$BAREREPO_GIT_DIR/hooks/hide-refs" <<-EOF
++ test-tool hide-refs \
++ -r "HEAD" \
++ -r "refs/heads/dev"
+ EOF
+'
+
-+test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): fetch a not advertised commit" '
++test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): fetch a tip commit which is not hidden" '
+ rm -rf local.git &&
-+ git -c protocol.version=$GIT_TEST_PROTOCOL_VERSION init local.git &&
-+ git -c protocol.version=$GIT_TEST_PROTOCOL_VERSION -C local.git remote add origin "$BAREREPO_URL" &&
-+ test_must_fail git -C local.git fetch "$BAREREPO_URL" $D
++ git init local.git &&
++ git -C local.git remote add origin "$BAREREPO_URL" &&
++ git -C local.git -c protocol.version=$GIT_TEST_PROTOCOL_VERSION fetch "$BAREREPO_URL" $B
++'
++
++test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): config allowAnySHA1InWant to true" '
++ git -C "$BAREREPO_GIT_DIR" config uploadpack.allowTipSHA1InWant true &&
++ git -C "$BAREREPO_GIT_DIR" config uploadpack.allowReachableSHA1InWant true
+'
+
-+test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): setup refs-advertise hook which advertise pull refs and tags" '
-+ write_script "$BAREREPO_GIT_DIR/hooks/refs-advertise" <<-EOF
-+ test-tool refs-advertise \
-+ --can-upload-pack \
-+ --can-ls-refs \
-+ -r "ref refs/pull-requests/1/head $C" \
-+ -r "obj $C" \
-+ -r "ref refs/tags/v123 $TAG" \
-+ -r "obj $TAG" \
-+ -r "obj $D"
++test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): fetch a non-tip commit which is not hidden" '
++ rm -rf local.git &&
++ git init local.git &&
++ git -C local.git remote add origin "$BAREREPO_URL" &&
++ git -C local.git -c protocol.version=$GIT_TEST_PROTOCOL_VERSION fetch "$BAREREPO_URL" $A
++'
++
++test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): setup hide-refs hook which hide pull refs and tags" '
++ write_script "$BAREREPO_GIT_DIR/hooks/hide-refs" <<-EOF
++ test-tool hide-refs \
++ -r "refs/pull-requests/1/head" \
++ -r "refs/tags/v123"
+ EOF
+'
+
-+test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): mirror clone pull refs and tags" '
++test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): mirror clone while hide-refs hook hide pull refs and tags" '
+ rm -rf local.git &&
+ git -c protocol.version=$GIT_TEST_PROTOCOL_VERSION clone --mirror "$BAREREPO_URL" local.git &&
-+ git -c protocol.version=$GIT_TEST_PROTOCOL_VERSION -C local.git show-ref -d >out 2>&1 &&
++ git -C local.git show-ref -d >out 2>&1 &&
+ make_user_friendly_and_stable_output <out >actual &&
+ format_and_save_expect <<-EOF &&
-+ <COMMIT-C> refs/pull-requests/1/head
-+ <COMMIT-TAG-v123> refs/tags/v123
-+ <COMMIT-D> refs/tags/v123^{}
++ <COMMIT-A> refs/heads/dev
++ <COMMIT-B> refs/heads/main
+ EOF
+ test_cmp expect actual
+'
+
-+test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): clone a not advertised branch" '
++test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): config allowAnySHA1InWant to true" '
++ git -C "$BAREREPO_GIT_DIR" config uploadpack.allowTipSHA1InWant true &&
++ git -C "$BAREREPO_GIT_DIR" config uploadpack.allowReachableSHA1InWant true
++'
++
++test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): fetch a non-tip commit which is hidden" '
+ rm -rf local.git &&
-+ test_must_fail git -c protocol.version=$GIT_TEST_PROTOCOL_VERSION clone "$BAREREPO_URL" local.git -b main &&
-+ test ! -d local.git
++ git init local.git &&
++ git -C local.git remote add origin "$BAREREPO_URL" &&
++ test_must_fail git -C local.git -c protocol.version=$GIT_TEST_PROTOCOL_VERSION fetch "$BAREREPO_URL" $C
+'
- ## t/t1419/test-0004-receive-pack-with-refs-advertise-hook.sh (new) ##
+ ## t/t1419/test-0003-receive-pack-with-hide-refs-hook.sh (new) ##
@@
-+test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): setup refs-advertise hook which handle no command" '
-+ write_script "$BAREREPO_GIT_DIR/hooks/refs-advertise" <<-EOF
-+ test-tool refs-advertise
++test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): setup hide-refs hook which hide no refs" '
++ write_script "$BAREREPO_GIT_DIR/hooks/hide-refs" <<-EOF
++ test-tool hide-refs
+ EOF
+'
+
-+test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): push to main while refs-advertise hook handle no command" '
++test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): push to main while hide-refs hook hide no refs" '
+ create_commits_in work_repo E &&
+ git -c protocol.version=$GIT_TEST_PROTOCOL_VERSION -C work_repo push origin HEAD:main >out 2>&1 &&
+ make_user_friendly_and_stable_output <out >out.tmp &&
@@ t/t1419/test-0004-receive-pack-with-refs-advertise-hook.sh (new)
+ test_cmp expect actual
+'
+
-+test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): create ref while refs-advertise hook handle no command" '
++test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): create ref while hide-refs hook hide no refs" '
+ git -c protocol.version=$GIT_TEST_PROTOCOL_VERSION -C work_repo push origin HEAD:new >out 2>&1 &&
+ make_user_friendly_and_stable_output <out >out.tmp &&
+ sed "s/$(get_abbrev_oid $E)[0-9a-f]*/<COMMIT-E>/g" <out.tmp >actual &&
@@ t/t1419/test-0004-receive-pack-with-refs-advertise-hook.sh (new)
+ test_cmp expect actual
+'
+
-+test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): push to delete ref while refs-advertise hook handle no command" '
++test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): push to delete ref while hide-refs hook hide no refs" '
+ git -c protocol.version=$GIT_TEST_PROTOCOL_VERSION -C work_repo push origin :dev >out 2>&1 &&
+ make_user_friendly_and_stable_output <out >out.tmp &&
+ sed "s/$(get_abbrev_oid $E)[0-9a-f]*/<COMMIT-E>/g" <out.tmp >actual &&
@@ t/t1419/test-0004-receive-pack-with-refs-advertise-hook.sh (new)
+ test_cmp expect actual
+'
+
-+test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): setup refs-advertise hook which advertise nothing" '
++test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): setup hide-refs hook which hide all refs" '
+ rm -rf work_repo &&
+ cp -rf work_repo.dump work_repo &&
+ rm -rf "$BAREREPO_GIT_DIR" &&
+ cp -rf bare_repo.git.dump "$BAREREPO_GIT_DIR" &&
-+ write_script "$BAREREPO_GIT_DIR/hooks/refs-advertise" <<-EOF
-+ test-tool refs-advertise \
-+ --can-receive-pack \
-+ --can-ls-refs
++ write_script "$BAREREPO_GIT_DIR/hooks/hide-refs" <<-EOF
++ test-tool hide-refs \
++ -r "HEAD" \
++ -r "refs/heads/dev" \
++ -r "refs/heads/main" \
++ -r "refs/pull-requests/1/head" \
++ -r "refs/tags/v123"
+ EOF
+'
+
-+test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): push to main while refs-advertise hook advertise nothing" '
++test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): push to main while hide-refs hook hide all refs" '
+ create_commits_in work_repo E &&
+ test_must_fail git -c protocol.version=$GIT_TEST_PROTOCOL_VERSION -C work_repo push origin HEAD:main >out 2>&1 &&
+ make_user_friendly_and_stable_output <out >out.tmp &&
@@ t/t1419/test-0004-receive-pack-with-refs-advertise-hook.sh (new)
+ format_and_save_expect <<-EOF &&
+ remote: # pre-receive hook Z
+ remote: pre-receive< <ZERO-OID> <COMMIT-E> refs/heads/main Z
-+ remote: # update hook Z
-+ remote: update< refs/heads/main <ZERO-OID> <COMMIT-E> Z
-+ remote: error: cannot lock ref "refs/heads/main": reference already exists Z
+ To <URL/of/bare_repo.git>
-+ ! [remote rejected] HEAD -> main (failed to update ref)
-+ error: failed to push some refs to "<URL/of/bare_repo.git>"
-+ EOF
-+ test_cmp expect actual
-+'
-+
-+test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): create ref while while refs-advertise hook advertise nothing" '
-+ git -c protocol.version=$GIT_TEST_PROTOCOL_VERSION -C work_repo push origin HEAD:new >out 2>&1 &&
-+ make_user_friendly_and_stable_output <out >out.tmp &&
-+ sed "s/$(get_abbrev_oid $E)[0-9a-f]*/<COMMIT-E>/g" <out.tmp >actual &&
-+ format_and_save_expect <<-EOF &&
-+ remote: # pre-receive hook Z
-+ remote: pre-receive< <ZERO-OID> <COMMIT-E> refs/heads/new Z
-+ remote: # update hook Z
-+ remote: update< refs/heads/new <ZERO-OID> <COMMIT-E> Z
-+ remote: # post-receive hook Z
-+ remote: post-receive< <ZERO-OID> <COMMIT-E> refs/heads/new Z
-+ To <URL/of/bare_repo.git>
-+ * [new branch] HEAD -> new
-+ EOF
-+ test_cmp expect actual
-+'
-+
-+test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): push to delete ref while while refs-advertise hook advertise nothing" '
-+ test_must_fail git -c protocol.version=$GIT_TEST_PROTOCOL_VERSION -C work_repo push origin :dev >out 2>&1 &&
-+ make_user_friendly_and_stable_output <out >out.tmp &&
-+ sed "s/$(get_abbrev_oid $E)[0-9a-f]*/<COMMIT-E>/g" <out.tmp >actual &&
-+ format_and_save_expect <<-EOF &&
-+ error: unable to delete "dev": remote ref does not exist
-+ error: failed to push some refs to "<URL/of/bare_repo.git>"
-+ EOF
-+ test_cmp expect actual
-+'
-+
-+test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): setup refs-advertise hook which advertise all refs" '
-+ rm -rf work_repo &&
-+ cp -rf work_repo.dump work_repo &&
-+ rm -rf "$BAREREPO_GIT_DIR" &&
-+ cp -rf bare_repo.git.dump "$BAREREPO_GIT_DIR" &&
-+ write_script "$BAREREPO_GIT_DIR/hooks/refs-advertise" <<-EOF
-+ test-tool refs-advertise \
-+ --can-receive-pack \
-+ --can-ls-refs \
-+ -r "ref refs/heads/dev $A" \
-+ -r "obj $A" \
-+ -r "ref refs/heads/main $B" \
-+ -r "obj $B" \
-+ -r "ref refs/pull-requests/1/head $C" \
-+ -r "obj $C" \
-+ -r "ref refs/tags/v123 $TAG" \
-+ -r "obj $TAG" \
-+ -r "obj $D"
-+ EOF
-+'
-+
-+test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): push to main while refs-advertise hook advertise all refs" '
-+ create_commits_in work_repo E &&
-+ git -c protocol.version=$GIT_TEST_PROTOCOL_VERSION -C work_repo push origin HEAD:main >out 2>&1 &&
-+ make_user_friendly_and_stable_output <out >out.tmp &&
-+ sed "s/$(get_abbrev_oid $E)[0-9a-f]*/<COMMIT-E>/g" <out.tmp >actual &&
-+ format_and_save_expect <<-EOF &&
-+ remote: # pre-receive hook Z
-+ remote: pre-receive< <COMMIT-B> <COMMIT-E> refs/heads/main Z
-+ remote: # update hook Z
-+ remote: update< refs/heads/main <COMMIT-B> <COMMIT-E> Z
-+ remote: # post-receive hook Z
-+ remote: post-receive< <COMMIT-B> <COMMIT-E> refs/heads/main Z
-+ To <URL/of/bare_repo.git>
-+ <COMMIT-B>..<COMMIT-E> HEAD -> main
-+ EOF
-+ test_cmp expect actual
-+'
-+
-+test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): create ref while while refs-advertise hook advertise all refs" '
-+ git -c protocol.version=$GIT_TEST_PROTOCOL_VERSION -C work_repo push origin HEAD:new >out 2>&1 &&
-+ make_user_friendly_and_stable_output <out >out.tmp &&
-+ sed "s/$(get_abbrev_oid $E)[0-9a-f]*/<COMMIT-E>/g" <out.tmp >actual &&
-+ format_and_save_expect <<-EOF &&
-+ remote: # pre-receive hook Z
-+ remote: pre-receive< <ZERO-OID> <COMMIT-E> refs/heads/new Z
-+ remote: # update hook Z
-+ remote: update< refs/heads/new <ZERO-OID> <COMMIT-E> Z
-+ remote: # post-receive hook Z
-+ remote: post-receive< <ZERO-OID> <COMMIT-E> refs/heads/new Z
-+ To <URL/of/bare_repo.git>
-+ * [new branch] HEAD -> new
-+ EOF
-+ test_cmp expect actual
-+'
-+
-+test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): push to delete ref while while refs-advertise hook advertise all refs" '
-+ git -c protocol.version=$GIT_TEST_PROTOCOL_VERSION -C work_repo push origin :dev >out 2>&1 &&
-+ make_user_friendly_and_stable_output <out >out.tmp &&
-+ sed "s/$(get_abbrev_oid $E)[0-9a-f]*/<COMMIT-E>/g" <out.tmp >actual &&
-+ format_and_save_expect <<-EOF &&
-+ remote: # pre-receive hook Z
-+ remote: pre-receive< <COMMIT-A> <ZERO-OID> refs/heads/dev Z
-+ remote: # update hook Z
-+ remote: update< refs/heads/dev <COMMIT-A> <ZERO-OID> Z
-+ remote: # post-receive hook Z
-+ remote: post-receive< <COMMIT-A> <ZERO-OID> refs/heads/dev Z
-+ To <URL/of/bare_repo.git>
-+ - [deleted] dev
-+ EOF
-+ test_cmp expect actual
-+'
-+
-+test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): setup refs-advertise hook which advertise pull refs and tags" '
-+ rm -rf work_repo &&
-+ cp -rf work_repo.dump work_repo &&
-+ rm -rf "$BAREREPO_GIT_DIR" &&
-+ cp -rf bare_repo.git.dump "$BAREREPO_GIT_DIR" &&
-+ write_script "$BAREREPO_GIT_DIR/hooks/refs-advertise" <<-EOF
-+ test-tool refs-advertise \
-+ --can-receive-pack \
-+ --can-ls-refs \
-+ -r "ref refs/pull-requests/1/head $C" \
-+ -r "obj $C" \
-+ -r "ref refs/tags/v123 $TAG" \
-+ -r "obj $TAG" \
-+ -r "obj $D"
-+ EOF
-+'
-+
-+test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): push to main while refs-advertise hook advertise pull refs and tags" '
-+ create_commits_in work_repo E &&
-+ test_must_fail git -c protocol.version=$GIT_TEST_PROTOCOL_VERSION -C work_repo push origin HEAD:main >out 2>&1 &&
-+ make_user_friendly_and_stable_output <out >out.tmp &&
-+ sed "s/$(get_abbrev_oid $E)[0-9a-f]*/<COMMIT-E>/g" <out.tmp >actual &&
-+ format_and_save_expect <<-EOF &&
-+ remote: # pre-receive hook Z
-+ remote: pre-receive< <ZERO-OID> <COMMIT-E> refs/heads/main Z
-+ remote: # update hook Z
-+ remote: update< refs/heads/main <ZERO-OID> <COMMIT-E> Z
-+ remote: error: cannot lock ref "refs/heads/main": reference already exists Z
-+ To <URL/of/bare_repo.git>
-+ ! [remote rejected] HEAD -> main (failed to update ref)
-+ error: failed to push some refs to "<URL/of/bare_repo.git>"
-+ EOF
-+ test_cmp expect actual
-+'
-+
-+test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): create ref while while refs-advertise hook advertise pull refs and tags" '
-+ git -c protocol.version=$GIT_TEST_PROTOCOL_VERSION -C work_repo push origin HEAD:new >out 2>&1 &&
-+ make_user_friendly_and_stable_output <out >out.tmp &&
-+ sed "s/$(get_abbrev_oid $E)[0-9a-f]*/<COMMIT-E>/g" <out.tmp >actual &&
-+ format_and_save_expect <<-EOF &&
-+ remote: # pre-receive hook Z
-+ remote: pre-receive< <ZERO-OID> <COMMIT-E> refs/heads/new Z
-+ remote: # update hook Z
-+ remote: update< refs/heads/new <ZERO-OID> <COMMIT-E> Z
-+ remote: # post-receive hook Z
-+ remote: post-receive< <ZERO-OID> <COMMIT-E> refs/heads/new Z
-+ To <URL/of/bare_repo.git>
-+ * [new branch] HEAD -> new
-+ EOF
-+ test_cmp expect actual
-+'
-+
-+test_expect_success "$PROTOCOL (protocol: $GIT_TEST_PROTOCOL_VERSION): push to delete ref while while refs-advertise hook advertise pull refs and tags" '
-+ test_must_fail git -c protocol.version=$GIT_TEST_PROTOCOL_VERSION -C work_repo push origin :dev >out 2>&1 &&
-+ make_user_friendly_and_stable_output <out >out.tmp &&
-+ sed "s/$(get_abbrev_oid $E)[0-9a-f]*/<COMMIT-E>/g" <out.tmp >actual &&
-+ format_and_save_expect <<-EOF &&
-+ error: unable to delete "dev": remote ref does not exist
++ ! [remote rejected] HEAD -> main (deny updating a hidden ref)
+ error: failed to push some refs to "<URL/of/bare_repo.git>"
+ EOF
+ test_cmp expect actual
3: d98357d5f64 ! 3: e737997eb31 doc: add documentation for the refs-advertise hook
@@ Metadata
Author: Sun Chao <16657101987@163.com>
## Commit message ##
- doc: add documentation for the refs-advertise hook
+ doc: add documentation for the hide-refs hook
- "git upload-pack" or "git recevie-pack" can use "refs-advertise"
- hook to filter the references and commits during reference discovery
- phase and commit fetching phase.
+ "git upload-pack" or "git recevie-pack" can use "hide-refs"
+ hook to filter the references during reference discovery phase.
Signed-off-by: Sun Chao <sunchao9@huawei.com>
@@ Documentation/githooks.txt: If this hook exits with a non-zero status, `git push
pushing anything. Information about why the push is rejected may be sent
to the user by writing to standard error.
-+[[refs-advertise]]
-+refs-advertise
-+~~~~~~~~~~~~
++[[hide-refs]]
++hide-refs
++~~~~~~~~~
+
-+This hook is invoked by 'git-receive-pack' and 'git-upload-pack' during the
-+reference discovery phase and the commit fetching phase, each reference and
-+commit to fetch will be filtered by this hook. The hook executes once with
-+no arguments for each 'git-upload-pack' and 'git-receive-pack' process and
-+if the exit status is non-zero, `git push` and `git fetch` will abort.
++This hook would be invoked by 'git-receive-pack' and 'git-upload-pack'
++during the reference discovery phase, each reference and will be filtered
++by this hook. The hook executes once with no arguments for each
++'git-upload-pack' and 'git-receive-pack' process. Once the hook is invoked,
++a version number and server process name ('uploadpack' or 'receive') will
++send to it in pkt-line format, followed by a flush-pkt. The hook should
++response with its version number.
+
-+Once the hook is invoked, a version number and server process name
-+('git-upload-pack' or 'git-receive-pack' or 'ls-refs') should send to it in
-+packet-line format, followed by a flush-pkt. The hook should response with
-+its version number and process name list it support. If the list does not
-+contains the server process name, the server will close the connection with
-+the hook and keep going without the hook child process.
++During reference discovery phase, each reference will be filtered by this
++hook. In the following example, the letter 'G' stands for 'git-receive-pack'
++or 'git-upload-pack' and the letter 'H' stands for this hook. The hook
++decides if the reference will be hidden or not, it sends result back in
++pkt-line format protocol, a response "hide" the references will hide
++to the client and can not fetch it even in protocol V2.
+
-+During reference discovery phase, each reference will be filtered by this hook,
-+In the following example, the letter 'G' stands for 'git-receive-pack' or
-+'git-upload-pack' and the letter 'H' stands for this hook. The hook decides if
-+the reference will be advertised or not, it sends result back with pkt-line format
-+protocol, a response in "ok ref <ref>" format followed by a flush-pkt means
-+the references "<ref>" can be advertised, and "ng ref <ref>" means not.
++ # Version negotiation
++ G: PKT-LINE(version=1\0uploadpack)
++ G: flush-pkt
++ H: PKT-LINE(version=1)
++ H: flush-pkt
+
-+ # Version negotiation
-+ G: PKT-LINE(version=1\0git-upload-pack)
-+ G: flush-pkt
-+ H: PKT-LINE(version=1\0git-upload-pack git-receive-pack ls-refs)
-+ H: flush-pkt
++ # Send reference filter request to hook
++ G: PKT-LINE(ref <refname>:<refnamefull>)
++ G: flush-pkt
+
-+ # Send reference filter request to hook
-+ G: PKT-LINE(ref <ref> <oid>)
-+ G: flush-pkt
++ # Receive result from the hook.
++ # Case 1: this reference is hidden
++ H: PKT-LINE(hide)
++ H: flush-pkt
+
-+ # Receive result from the hook.
-+ # Case 1: this reference is valid
-+ H: PKT-LINE(ok ref <ref>)
-+ H: flush-pkt
-+ # Case 2: this reference is filtered out
-+ H: PKT-LINE(ng ref <ref>)
-+ H: flush-pkt
++ # Case 2: this reference can be advertised
++ H: flush-pkt
+
-+During commit fetch phase of 'git-upload-pack' process, git client may send `want <oid>`
-+requests and 'git-upload-pack' will send object filter requests to the hook to check if
-+the object "<oid>" will be sent to the client or not. In the following example, the letter
-+'G' stands for 'git-upload-pack' and the letter 'H' stands for this hook.
++To enable the `hide-refs` hook, we should config hiderefs with `force:`
++option, eg:
+
-+The hook will decides if a commit will be sent to the client or not, it sends result with
-+pkt-line format protocol to `git-upload-pack`, a response in "ok obj <oid>" format
-+followed by a flush-pkt means the object "<oid>" can be sent to client, and "ng obj <oid>"
-+means not.
++ git config --add transfer.hiderefs force:refs/prefix1/
++ git config --add uploadpack.hiderefs force:!refs/prefix2/
+
-+ # Version negotiation
-+ G: PKT-LINE(version=1\0ls-refs)
-+ G: flush-pkt
-+ H: PKT-LINE(version=1\0git-upload-pack git-receive-pack ls-refs)
-+ H: flush-pkt
-+
-+ # Send commit filter request to hook
-+ G: PKT-LINE(obj <oid>)
-+ G: flush-pkt
-+
-+ # Receive result from the hook.
-+ # Case 1: this object is valid
-+ H: PKT-LINE(ok obj <oid>)
-+ H: flush-pkt
-+ # Case 2: this object is filtered out
-+ H: PKT-LINE(ng obj <oid>)
-+ H: flush-pkt
++the `hide-refs` will be called during reference discovery phase and
++check each matched reference, a 'hide' reponse means the reference will
++be hidden for its private data and even the `allowTipSHA1InWant` and
++`allowReachableSHA1InWant` is set to true.
+
[[pre-receive]]
pre-receive
--
gitgitgadget
next prev parent reply other threads:[~2022-08-15 0:54 UTC|newest]
Thread overview: 42+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-08-03 16:17 [PATCH 0/3] refs-advertise: add hook to filter advertised refs Sun Chao via GitGitGadget
2022-08-03 16:17 ` [PATCH 1/3] " Sun Chao via GitGitGadget
2022-08-03 16:17 ` [PATCH 2/3] t1419: add test cases for refs-advertise hook Sun Chao via GitGitGadget
2022-08-03 16:17 ` [PATCH 3/3] doc: add documentation for the " Sun Chao via GitGitGadget
2022-08-03 20:27 ` [PATCH 0/3] refs-advertise: add hook to filter advertised refs Junio C Hamano
2022-08-04 8:27 ` 孙超
2022-08-10 1:06 ` Jiang Xin
2022-08-10 13:09 ` 孙超
2022-08-15 0:54 ` Sun Chao via GitGitGadget [this message]
2022-08-15 0:54 ` [PATCH v2 1/3] hide-refs: add hook to force hide refs Sun Chao via GitGitGadget
2022-08-15 0:54 ` [PATCH v2 2/3] t1419: add test cases for hide-refs hook Sun Chao via GitGitGadget
2022-08-15 0:54 ` [PATCH v2 3/3] doc: add documentation for the " Sun Chao via GitGitGadget
2022-08-15 4:12 ` Eric Sunshine
2022-08-15 14:49 ` 孙超
2022-08-15 16:02 ` Junio C Hamano
2022-08-15 14:56 ` [PATCH v3 0/3] hide-refs: add hook to force hide refs Sun Chao via GitGitGadget
2022-08-15 14:56 ` [PATCH v3 1/3] " Sun Chao via GitGitGadget
2022-08-15 14:56 ` [PATCH v3 2/3] t1419: add test cases for hide-refs hook Sun Chao via GitGitGadget
2022-08-15 14:56 ` [PATCH v3 3/3] doc: add documentation for the " Sun Chao via GitGitGadget
2022-08-15 15:01 ` [PATCH v4 0/3] hide-refs: add hook to force hide refs Sun Chao via GitGitGadget
2022-08-15 15:01 ` [PATCH v4 1/3] " Sun Chao via GitGitGadget
2022-08-15 18:18 ` Junio C Hamano
2022-08-16 11:22 ` 孙超
2022-08-18 18:51 ` Calvin Wan
2022-08-19 15:30 ` 孙超
2022-08-15 15:01 ` [PATCH v4 2/3] t1419: add test cases for hide-refs hook Sun Chao via GitGitGadget
2022-08-15 15:01 ` [PATCH v4 3/3] doc: add documentation for the " Sun Chao via GitGitGadget
2022-09-09 15:06 ` [PATCH v5 0/5] hiderefs: add hide-refs hook to hide refs dynamically Sun Chao via GitGitGadget
2022-09-09 15:06 ` [PATCH v5 1/5] " Sun Chao via GitGitGadget
2022-09-13 17:01 ` Junio C Hamano
2022-09-16 17:52 ` Junio C Hamano
2022-09-17 8:14 ` 孙超
2022-09-09 15:06 ` [PATCH v5 2/5] hiderefs: use new flag to mark force hidden refs Sun Chao via GitGitGadget
2022-09-09 15:06 ` [PATCH v5 3/5] hiderefs: hornor hide flags in wire protocol V2 Sun Chao via GitGitGadget
2022-09-09 15:06 ` [PATCH v5 4/5] test: add test cases for hide-refs hook Sun Chao via GitGitGadget
2022-09-09 15:06 ` [PATCH v5 5/5] doc: add documentation for the " Sun Chao via GitGitGadget
2022-09-20 8:22 ` [PATCH v6 0/5] hiderefs: add hide-refs hook to hide refs dynamically Sun Chao via GitGitGadget
2022-09-20 8:22 ` [PATCH v6 1/5] " Sun Chao via GitGitGadget
2022-09-20 8:22 ` [PATCH v6 2/5] hiderefs: use a new flag to mark force hidden refs Sun Chao via GitGitGadget
2022-09-20 8:22 ` [PATCH v6 3/5] hiderefs: hornor hide flags in wire protocol V2 Sun Chao via GitGitGadget
2022-09-20 8:22 ` [PATCH v6 4/5] test: add test cases for hide-refs hook Sun Chao via GitGitGadget
2022-09-20 8:22 ` [PATCH v6 5/5] doc: add documentation for the " Sun Chao via GitGitGadget
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=pull.1301.v2.git.git.1660524865.gitgitgadget@gmail.com \
--to=gitgitgadget@gmail.com \
--cc=16657101987@163.com \
--cc=git@vger.kernel.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.