Skip to content

Commit 6c430a6

Browse files
committed
Merge branch 'jx/proc-receive-hook'
"git receive-pack" that accepts requests by "git push" learned to outsource most of the ref updates to the new "proc-receive" hook. * jx/proc-receive-hook: doc: add documentation for the proc-receive hook transport: parse report options for tracking refs t5411: test updates of remote-tracking branches receive-pack: new config receive.procReceiveRefs doc: add document for capability report-status-v2 New capability "report-status-v2" for git-push receive-pack: feed report options to post-receive receive-pack: add new proc-receive hook t5411: add basic test cases for proc-receive hook transport: not report a non-head push as a branch
2 parents 48794ac + d6edc18 commit 6c430a6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+4325
-100
lines changed

Documentation/config/receive.txt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,28 @@ receive.hideRefs::
114114
An attempt to update or delete a hidden ref by `git push` is
115115
rejected.
116116

117+
receive.procReceiveRefs::
118+
This is a multi-valued variable that defines reference prefixes
119+
to match the commands in `receive-pack`. Commands matching the
120+
prefixes will be executed by an external hook "proc-receive",
121+
instead of the internal `execute_commands` function. If this
122+
variable is not defined, the "proc-receive" hook will never be
123+
used, and all commands will be executed by the internal
124+
`execute_commands` function.
125+
+
126+
For example, if this variable is set to "refs/for", pushing to reference
127+
such as "refs/for/master" will not create or update a reference named
128+
"refs/for/master", but may create or update a pull request directly by
129+
running the hook "proc-receive".
130+
+
131+
Optional modifiers can be provided in the beginning of the value to filter
132+
commands for specific actions: create (a), modify (m), delete (d).
133+
A `!` can be included in the modifiers to negate the reference prefix entry.
134+
E.g.:
135+
+
136+
git config --system --add receive.procReceiveRefs ad:refs/heads
137+
git config --system --add receive.procReceiveRefs !:refs/heads
138+
117139
receive.updateServerInfo::
118140
If set to true, git-receive-pack will run git-update-server-info
119141
after receiving data from git-push and updating refs.

Documentation/githooks.txt

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,68 @@ The default 'update' hook, when enabled--and with
335335
`hooks.allowunannotated` config option unset or set to false--prevents
336336
unannotated tags to be pushed.
337337

338+
[[proc-receive]]
339+
proc-receive
340+
~~~~~~~~~~~~
341+
342+
This hook is invoked by linkgit:git-receive-pack[1]. If the server has
343+
set the multi-valued config variable `receive.procReceiveRefs`, and the
344+
commands sent to 'receive-pack' have matching reference names, these
345+
commands will be executed by this hook, instead of by the internal
346+
`execute_commands()` function. This hook is responsible for updating
347+
the relevant references and reporting the results back to 'receive-pack'.
348+
349+
This hook executes once for the receive operation. It takes no
350+
arguments, but uses a pkt-line format protocol to communicate with
351+
'receive-pack' to read commands, push-options and send results. In the
352+
following example for the protocol, the letter 'S' stands for
353+
'receive-pack' and the letter 'H' stands for this hook.
354+
355+
# Version and features negotiation.
356+
S: PKT-LINE(version=1\0push-options atomic...)
357+
S: flush-pkt
358+
H: PKT-LINE(version=1\0push-options...)
359+
H: flush-pkt
360+
361+
# Send commands from server to the hook.
362+
S: PKT-LINE(<old-oid> <new-oid> <ref>)
363+
S: ... ...
364+
S: flush-pkt
365+
# Send push-options only if the 'push-options' feature is enabled.
366+
S: PKT-LINE(push-option)
367+
S: ... ...
368+
S: flush-pkt
369+
370+
# Receive result from the hook.
371+
# OK, run this command successfully.
372+
H: PKT-LINE(ok <ref>)
373+
# NO, I reject it.
374+
H: PKT-LINE(ng <ref> <reason>)
375+
# Fall through, let 'receive-pack' to execute it.
376+
H: PKT-LINE(ok <ref>)
377+
H: PKT-LINE(option fall-through)
378+
# OK, but has an alternate reference. The alternate reference name
379+
# and other status can be given in option directives.
380+
H: PKT-LINE(ok <ref>)
381+
H: PKT-LINE(option refname <refname>)
382+
H: PKT-LINE(option old-oid <old-oid>)
383+
H: PKT-LINE(option new-oid <new-oid>)
384+
H: PKT-LINE(option forced-update)
385+
H: ... ...
386+
H: flush-pkt
387+
388+
Each command for the 'proc-receive' hook may point to a pseudo-reference
389+
and always has a zero-old as its old-oid, while the 'proc-receive' hook
390+
may update an alternate reference and the alternate reference may exist
391+
already with a non-zero old-oid. For this case, this hook will use
392+
"option" directives to report extended attributes for the reference given
393+
by the leading "ok" directive.
394+
395+
The report of the commands of this hook should have the same order as
396+
the input. The exit status of the 'proc-receive' hook only determines
397+
the success or failure of the group of commands sent to it, unless
398+
atomic push is in use.
399+
338400
[[post-receive]]
339401
post-receive
340402
~~~~~~~~~~~~

Documentation/technical/pack-protocol.txt

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -503,8 +503,8 @@ The reference discovery phase is done nearly the same way as it is in the
503503
fetching protocol. Each reference obj-id and name on the server is sent
504504
in packet-line format to the client, followed by a flush-pkt. The only
505505
real difference is that the capability listing is different - the only
506-
possible values are 'report-status', 'delete-refs', 'ofs-delta' and
507-
'push-options'.
506+
possible values are 'report-status', 'report-status-v2', 'delete-refs',
507+
'ofs-delta', 'atomic' and 'push-options'.
508508

509509
Reference Update Request and Packfile Transfer
510510
----------------------------------------------
@@ -625,7 +625,7 @@ Report Status
625625
-------------
626626

627627
After receiving the pack data from the sender, the receiver sends a
628-
report if 'report-status' capability is in effect.
628+
report if 'report-status' or 'report-status-v2' capability is in effect.
629629
It is a short listing of what happened in that update. It will first
630630
list the status of the packfile unpacking as either 'unpack ok' or
631631
'unpack [error]'. Then it will list the status for each of the references
@@ -647,6 +647,41 @@ update was successful, or 'ng [refname] [error]' if the update was not.
647647
error-msg = 1*(OCTET) ; where not "ok"
648648
----
649649

650+
The 'report-status-v2' capability extends the protocol by adding new option
651+
lines in order to support reporting of reference rewritten by the
652+
'proc-receive' hook. The 'proc-receive' hook may handle a command for a
653+
pseudo-reference which may create or update one or more references, and each
654+
reference may have different name, different new-oid, and different old-oid.
655+
656+
----
657+
report-status-v2 = unpack-status
658+
1*(command-status-v2)
659+
flush-pkt
660+
661+
unpack-status = PKT-LINE("unpack" SP unpack-result)
662+
unpack-result = "ok" / error-msg
663+
664+
command-status-v2 = command-ok-v2 / command-fail
665+
command-ok-v2 = command-ok
666+
*option-line
667+
668+
command-ok = PKT-LINE("ok" SP refname)
669+
command-fail = PKT-LINE("ng" SP refname SP error-msg)
670+
671+
error-msg = 1*(OCTET) ; where not "ok"
672+
673+
option-line = *1(option-refname)
674+
*1(option-old-oid)
675+
*1(option-new-oid)
676+
*1(option-forced-update)
677+
678+
option-refname = PKT-LINE("option" SP "refname" SP refname)
679+
option-old-oid = PKT-LINE("option" SP "old-oid" SP obj-id)
680+
option-new-oid = PKT-LINE("option" SP "new-oid" SP obj-id)
681+
option-force = PKT-LINE("option" SP "forced-update")
682+
683+
----
684+
650685
Updates can be unsuccessful for a number of reasons. The reference can have
651686
changed since the reference discovery phase was originally sent, meaning
652687
someone pushed in the meantime. The reference being pushed could be a

Documentation/technical/protocol-capabilities.txt

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ was sent. Server MUST NOT ignore capabilities that client requested
2222
and server advertised. As a consequence of these rules, server MUST
2323
NOT advertise capabilities it does not understand.
2424

25-
The 'atomic', 'report-status', 'delete-refs', 'quiet', and 'push-cert'
26-
capabilities are sent and recognized by the receive-pack (push to server)
27-
process.
25+
The 'atomic', 'report-status', 'report-status-v2', 'delete-refs', 'quiet',
26+
and 'push-cert' capabilities are sent and recognized by the receive-pack
27+
(push to server) process.
2828

2929
The 'ofs-delta' and 'side-band-64k' capabilities are sent and recognized
3030
by both upload-pack and receive-pack protocols. The 'agent' capability
@@ -284,6 +284,17 @@ each reference was updated successfully. If any of those were not
284284
successful, it will send back an error message. See pack-protocol.txt
285285
for example messages.
286286

287+
report-status-v2
288+
----------------
289+
290+
Capability 'report-status-v2' extends capability 'report-status' by
291+
adding new "option" directives in order to support reference rewritten by
292+
the "proc-receive" hook. The "proc-receive" hook may handle a command
293+
for a pseudo-reference which may create or update a reference with
294+
different name, new-oid, and old-oid. While the capability
295+
'report-status' cannot report for such case. See pack-protocol.txt
296+
for details.
297+
287298
delete-refs
288299
-----------
289300

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -720,6 +720,7 @@ TEST_BUILTINS_OBJS += test-parse-pathspec-file.o
720720
TEST_BUILTINS_OBJS += test-path-utils.o
721721
TEST_BUILTINS_OBJS += test-pkt-line.o
722722
TEST_BUILTINS_OBJS += test-prio-queue.o
723+
TEST_BUILTINS_OBJS += test-proc-receive.o
723724
TEST_BUILTINS_OBJS += test-progress.o
724725
TEST_BUILTINS_OBJS += test-reach.o
725726
TEST_BUILTINS_OBJS += test-read-cache.o

0 commit comments

Comments
 (0)