All of lore.kernel.org
 help / color / mirror / Atom feed
From: Karthik Nayak <karthik.188@gmail.com>
To: git@vger.kernel.org
Cc: ps@pks.im, gitster@pobox.com, jltobler@gmail.com,
	 kristofferhaugsbakk@fastmail.com,
	Karthik Nayak <karthik.188@gmail.com>,
	 Phillip Wood <phillip.wood@dunelm.org.uk>
Subject: [PATCH v4 0/3] hook: introduce the receive-report hook
Date: Wed, 26 Aug 2026 12:19:36 +0200	[thread overview]
Message-ID: <20260826-758-introduce-hook-v4-0-6b14975ad957@gmail.com> (raw)
In-Reply-To: <20260818-758-introduce-hook-v1-1-8a8d89e65838@gmail.com>

Introduce a new receive-report hook which kicks in after the reference
transaction is complete, but before the report is sent to the client.
The hook receives the pkt-line encoded report in its stdin and its
stdout replaces the report transferred to the user. If the hook exits
with a non-zero exit code, all references are marked as rejected.

The first patch, adds missing documentation to 'git-receive-pack.adoc'.
The second patch refactors code and the third patch contains the new
hook.

---
Changes in v4:
- Change the name of the hook to be 'receive-report' to avoid ambiguity.
- Link to v3: https://patch.msgid.link/20260824-758-introduce-hook-v3-0-499526f0a062@gmail.com

Changes in v3:
- Move out addition of proc-receive hook doc to 'git-receive-pack.adoc'
  into a new commit.
- Add a new commit to move out the response generation in receive-pack
  to a new function.
- Instead of die-ing on non-zero exit code, we modify each reference to
  indicate that the hook failed.
- Instead of correctly listing out the protocol, link to
  linkgit:gitprotocol-pack[5], as the protocol also differs between v1
  and v2.
- Link to v2: https://patch.msgid.link/20260821-758-introduce-hook-v2-1-e90e2f7ac2cf@gmail.com

Changes in v2:
- Modify the documentation and commit message to be more verbose.
- Add documentation to 'git-receive-pack.adoc'
- Use 'ret' as the variable name for the return code.
- Modify the test to also check for the 'remote:'.
- Link to v1: https://patch.msgid.link/20260818-758-introduce-hook-v1-1-8a8d89e65838@gmail.com

 To: git@vger.kernel.org
 CC: ps@pks.im
 CC: gitster@pobox.com
 CC: jltobler@gmail.com
 CC: kristofferhaugsbakk@fastmail.com
 CC: phillip.wood123@gmail.com

---
Karthik Nayak (3):
      doc: add proc-receive hook info in 'git-receive-pack.adoc'
      receive-pack: move message generation to separate function
      hook: introduce the receive-report hook

 Documentation/git-receive-pack.adoc |  15 +++
 Documentation/githooks.adoc         |  43 ++++++++
 builtin/receive-pack.c              | 137 ++++++++++++++++--------
 t/meson.build                       |   1 +
 t/t5412-receive-report-hook.sh      | 200 ++++++++++++++++++++++++++++++++++++
 5 files changed, 356 insertions(+), 40 deletions(-)

Range-diff versus v3:

1:  b899f31ffa = 1:  30784c0448 doc: add proc-receive hook info in 'git-receive-pack.adoc'
2:  335182cd3d = 2:  55d6a46815 receive-pack: move message generation to separate function
3:  80aa575dab ! 3:  99eeafb537 hook: introduce the report hook for git-receive-pack(1)
    @@ Metadata
     Author: Karthik Nayak <karthik.188@gmail.com>
     
      ## Commit message ##
    -    hook: introduce the report hook for git-receive-pack(1)
    +    hook: introduce the receive-report hook
     
         When running 'git-receive-pack(1)', there is no way for the server to
         intercept and modify the status report before it is sent back to the
    @@ Commit message
             too late, at the point where we have already reported success to the
             client.
     
    -    Introduce a new 'report' hook. The hook receives the complete pkt-line
    -    encoded status report on standard input, after all ref updates have
    -    been applied to the repository by execute_commands() but before the
    +    Introduce a new 'receive-report' hook. The hook receives the complete
    +    pkt-line encoded status report on standard input, after all ref updates
    +    have been applied to the repository by execute_commands() but before the
         report is sent to the client. See linkgit:gitprotocol-pack[5] details on
         the protocol structure.
     
    @@ Commit message
           status if any ref is 'ng'.
     
         - Non-zero exit: the hook's stdout is discarded, receive-pack modifies
    -      all references to be rejected with a 'report hook failed' error.
    +      all references to be rejected with a 'receive-report hook failed'
    +      error.
     
         In both cases, any output the hook writes to standard error is
         forwarded to the client over the sideband channel and appears as
    @@ Documentation/git-receive-pack.adoc: requests. It handles refs whose names match
      `receive.procReceiveRefs` and executes the actual ref updates. See
      linkgit:githooks[5] for the full protocol description.
      
    -+REPORT HOOK
    -+-----------
    ++RECEIVE-REPORT HOOK
    ++-------------------
     +This hook is invoked by 'git-receive-pack' after all the ref updates
     +have been applied but before the report is sent to the client. The hook
     +receives the complete report in pkt-line format on stdin and its stdout
    @@ Documentation/githooks.adoc: The exit status of the hook is ignored for any stat
      status will cause the transaction to be aborted. The hook will not be
      called with "aborted" state in that case.
      
    -+report
    -+~~~~~~
    ++receive-report
    ++~~~~~~~~~~~~~~
     +
     +This hook is invoked by linkgit:git-receive-pack[1] when it reacts to
     +`git push` and updates references in its repository. It executes on
    @@ Documentation/githooks.adoc: The exit status of the hook is ignored for any stat
     +
     +* To abort the entire push unconditionally, exit with a non-zero
     +  status. In this case the hook's stdout is discarded, `receive-pack`
    -+  modifies all references to be rejected with a 'report hook failed'
    -+  error.
    ++  modifies all references to be rejected with a 'receive-report hook
    ++  failed' error.
     +
     +Any output written to standard error is forwarded to the client over
     +the sideband channel and will appear as `remote:` lines on clients
    @@ builtin/receive-pack.c: static int run_update_hook(struct command *cmd)
      	return code;
      }
      
    -+static int run_report_hook(struct strbuf *report)
    ++static int run_receive_report_hook(struct strbuf *report)
     +{
     +	struct child_process proc = CHILD_PROCESS_INIT;
     +	struct async sideband_async;
    @@ builtin/receive-pack.c: static int run_update_hook(struct command *cmd)
     +	const char *hook_path;
     +	int ret;
     +
    -+	hook_path = find_hook(the_repository, "report");
    ++	hook_path = find_hook(the_repository, "receive-report");
     +	if (!hook_path)
     +		return 0;
     +
     +	strvec_push(&proc.args, hook_path);
    -+	proc.trace2_hook_name = "report";
    ++	proc.trace2_hook_name = "receive-report";
     +
     +	prepare_sideband_async(&sideband_async, &saved_stderr,
     +			       &sideband_async_started);
    @@ builtin/receive-pack.c: static void report(struct command *commands, const char
     -	generate_response(&buf, commands, unpack_status, false);
     +	generate_response(&buf, commands, unpack_status, false, NULL);
     +
    -+	if (run_report_hook(&buf)) {
    ++	if (run_receive_report_hook(&buf)) {
     +		strbuf_reset(&buf);
     +		generate_response(&buf, commands, unpack_status, false,
    -+				  "report hook failed");
    ++				  "receive-report hook failed");
     +	}
      
      	if (use_sideband)
    @@ builtin/receive-pack.c: static void report_v2(struct command *commands, const ch
     -	generate_response(&buf, commands, unpack_status, true);
     +	generate_response(&buf, commands, unpack_status, true, NULL);
     +
    -+	if (run_report_hook(&buf)) {
    ++	if (run_receive_report_hook(&buf)) {
     +		strbuf_reset(&buf);
     +		generate_response(&buf, commands, unpack_status, true,
    -+			  "report hook failed");
    ++			  "receive-report hook failed");
     +	}
      
      	if (use_sideband)
    @@ t/meson.build: integration_tests = [
        't5409-colorize-remote-messages.sh',
        't5410-receive-pack.sh',
        't5411-proc-receive-hook.sh',
    -+  't5412-report-hook.sh',
    ++  't5412-receive-report-hook.sh',
        't5500-fetch-pack.sh',
        't5501-fetch-push-alternates.sh',
        't5502-quickfetch.sh',
     
    - ## t/t5412-report-hook.sh (new) ##
    + ## t/t5412-receive-report-hook.sh (new) ##
     @@
     +#!/bin/sh
     +
    -+test_description='test report hook'
    ++test_description='test receive-report hook'
     +
     +GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
     +export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
    @@ t/t5412-report-hook.sh (new)
     +	test_when_finished "git -C workbench remote remove origin" &&
     +	git init --bare upstream &&
     +
    -+	test_hook -C upstream --setup report <<-\EOF &&
    ++	test_hook -C upstream --setup receive-report <<-\EOF &&
     +	cat
     +	EOF
     +
    @@ t/t5412-report-hook.sh (new)
     +	git -C workbench remote add origin ../upstream &&
     +	git -C workbench push origin $A:refs/heads/main &&
     +
    -+	test_hook -C upstream --setup report <<-\EOF &&
    ++	test_hook -C upstream --setup receive-report <<-\EOF &&
     +	exit 1
     +	EOF
     +
    @@ t/t5412-report-hook.sh (new)
     +	make_user_friendly_and_stable_output <out >actual &&
     +	cat >expect <<-\EOF &&
     +	To ../upstream
    -+	 ! [remote rejected] <COMMIT-B> -> main (report hook failed)
    ++	 ! [remote rejected] <COMMIT-B> -> main (receive-report hook failed)
     +	EOF
     +	test_cmp expect actual
     +'
    @@ t/t5412-report-hook.sh (new)
     +	test_when_finished "git -C workbench remote remove origin" &&
     +
     +	git init --bare upstream &&
    -+	test_hook -C upstream --setup report <<-EOF &&
    ++	test_hook -C upstream --setup receive-report <<-EOF &&
     +	tee raw
     +	EOF
     +
    @@ t/t5412-report-hook.sh (new)
     +	git -C workbench remote add origin ../upstream &&
     +	git -C workbench push origin $A:refs/heads/main &&
     +
    -+	test_hook -C upstream --setup report <<-\EOF &&
    ++	test_hook -C upstream --setup receive-report <<-\EOF &&
     +	test-tool pkt-line unpack |
     +	sed "s/^ok /ng /" |
     +	test-tool pkt-line pack
    @@ t/t5412-report-hook.sh (new)
     +	git -C workbench remote add origin ../upstream &&
     +	git -C workbench push origin $A:refs/heads/main &&
     +
    -+	test_hook -C upstream --setup report <<-\EOF &&
    ++	test_hook -C upstream --setup receive-report <<-\EOF &&
     +	echo "push rejected: service X is down" >&2
     +	test-tool pkt-line unpack |
     +	sed "s/^ok \(.*\)/ng \1 service-x-is-down/" |
    @@ t/t5412-report-hook.sh (new)
     +	git -C workbench remote add origin ../upstream &&
     +	git -C workbench push origin $A:refs/heads/main &&
     +
    -+	test_hook -C upstream --setup report <<-\EOF &&
    ++	test_hook -C upstream --setup receive-report <<-\EOF &&
     +	echo "push rejected: service X is down" >&2
     +	tee raw
     +	EOF
    @@ t/t5412-report-hook.sh (new)
     +	git -C workbench remote add origin ../upstream &&
     +	git -C workbench push origin $A:refs/heads/main &&
     +
    -+	test_hook -C upstream --setup report <<-\EOF &&
    ++	test_hook -C upstream --setup receive-report <<-\EOF &&
     +	echo "hook-stderr-message" >&2
     +	exit 1
     +	EOF

---
base-commit: 11c6700f10234578d10523faf35656ca491425c9
change-id: 20260812-758-introduce-hook-5b3af9f1a7e8


Thanks
- Karthik


  parent reply	other threads:[~2026-08-26 10:19 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-18  7:55 [PATCH] hook: introduce the report hook for git-receive-pack(1) Karthik Nayak
2026-08-18 20:54 ` Junio C Hamano
2026-08-19  7:03 ` Kristoffer Haugsbakk
2026-08-19 12:11   ` Karthik Nayak
2026-08-19 14:47     ` Kristoffer Haugsbakk
2026-08-19  7:39 ` Patrick Steinhardt
2026-08-19 13:13   ` Karthik Nayak
2026-08-19 13:20     ` Patrick Steinhardt
2026-08-19 13:24       ` Karthik Nayak
2026-08-20  9:50 ` Phillip Wood
2026-08-20 15:43   ` Junio C Hamano
2026-08-21 12:51   ` Karthik Nayak
2026-08-21 13:34 ` [PATCH v2] " Karthik Nayak
2026-08-21 13:49   ` Patrick Steinhardt
2026-08-21 16:08     ` Karthik Nayak
2026-08-24  5:32       ` Patrick Steinhardt
2026-08-24  8:14         ` Karthik Nayak
2026-08-21 16:55     ` Junio C Hamano
2026-08-24 10:20 ` [PATCH v3 0/3] " Karthik Nayak
2026-08-24 10:20   ` [PATCH v3 1/3] doc: add proc-receive hook info in 'git-receive-pack.adoc' Karthik Nayak
2026-08-24 10:21   ` [PATCH v3 2/3] receive-pack: move message generation to separate function Karthik Nayak
2026-08-24 10:21   ` [PATCH v3 3/3] hook: introduce the report hook for git-receive-pack(1) Karthik Nayak
2026-08-24 15:35   ` [PATCH v3 0/3] " Junio C Hamano
2026-08-24 15:57     ` Junio C Hamano
2026-08-24 17:00       ` Patrick Steinhardt
2026-08-26  8:35     ` Karthik Nayak
2026-08-26 14:39       ` Junio C Hamano
2026-08-26 10:19 ` Karthik Nayak [this message]
2026-08-26 10:19   ` [PATCH v4 1/3] doc: add proc-receive hook info in 'git-receive-pack.adoc' Karthik Nayak
2026-08-31  6:44     ` Patrick Steinhardt
2026-08-31 18:22       ` Karthik Nayak
2026-08-26 10:19   ` [PATCH v4 2/3] receive-pack: move message generation to separate function Karthik Nayak
2026-08-31  6:44     ` Patrick Steinhardt
2026-08-31 19:05       ` Karthik Nayak
2026-08-26 10:19   ` [PATCH v4 3/3] hook: introduce the receive-report hook Karthik Nayak
2026-08-31  6:45     ` Patrick Steinhardt
2026-09-01 15:19 ` [PATCH v5 0/3] " Karthik Nayak
2026-09-01 15:19   ` [PATCH v5 1/3] doc: add proc-receive hook info in 'git-receive-pack.adoc' Karthik Nayak
2026-09-01 15:19   ` [PATCH v5 2/3] receive-pack: move message generation to separate function Karthik Nayak
2026-09-01 16:23     ` Junio C Hamano
2026-09-02 11:23       ` Karthik Nayak
2026-09-01 15:19   ` [PATCH v5 3/3] hook: introduce the receive-report hook Karthik Nayak
2026-09-01 17:03     ` Junio C Hamano
2026-09-02 14:42       ` Karthik Nayak

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=20260826-758-introduce-hook-v4-0-6b14975ad957@gmail.com \
    --to=karthik.188@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=jltobler@gmail.com \
    --cc=kristofferhaugsbakk@fastmail.com \
    --cc=phillip.wood@dunelm.org.uk \
    --cc=ps@pks.im \
    /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.