In my planned speech at the Git Merge 2020 conference, this series of patches is a core part of AGit-Flow (a centralized workflow like Gerrit). Due to a coronavirus outbreak in China, I was unable to attend the meeting. I wrote a blog "AGit-Flow and git-repo" based on my planned speech, see: https://git-repo.info/en/2020/03/agit-flow-and-git-repo/ Git calls an internal `execute_commands` function to handle commands sent from the client to `git-receive-pack`. Regardless of what references the user pushes, git creates or updates the corresponding references if the user has write permission. A contributor who has no write permission cannot push to repository directly. So, the contributor has to write commits to an alternate location and sends pull request by emails or by other ways. We call this distributed workflow. It would be more convenient to work in a centralized workflow like what Gerrit provided for some cases. For example, a read-only user may run the following `git push` command to push commits to a special reference to create a code review, instead of updating a reference directly. git push -o reviewers=user1,user2 \ -o oldoid=89c082363ac950d224a7259bfba3ccfbf4c560c4 \ origin \ HEAD:refs/for/<branch-name>/<session> The `<branch-name>` in the above example can be as simple as "master", or a more complicated branch name like "foo/bar". The `<session>` in the above example command can be the local branch name of the clien- side, such as "my/topic". To support this kind of workflow in CGit, add a filter and a new handler. The filter will check the prefix of the reference name, and if the command has a special reference name, the filter will add a specific tag (`exec_by_hook`) to the command. Commands with this specific tag will be executed by a new handler (an external hook named "execute-commands") instead of the internal `execute_commands` function. We can use the external "execute-commands" hook to create pull requests or send emails. The centralized workflow is not a replacement for the distributed workflow, but a supplement. Especially for lightweight code contribution or for working on a project with multiple repositories. We also implement a command line tool for this kind of workflow, see: https://github.com/aliyun/git-repo-go Jiang Xin (7): receive-pack: new external execute-commands hook receive-pack: feed all commands to post-receive receive-pack: try `execute-commands --pre-receive` receive-pack: read env from execute-commands output refs.c: refactor to reuse ref_is_hidden() receive-pack: new config receive.executeCommandsHookRefs hook: add document and example for "execute-commands" hook Documentation/config/receive.txt | 11 + Documentation/githooks.txt | 43 ++ builtin/receive-pack.c | 228 +++++++- refs.c | 11 +- refs.h | 1 + t/t5411-execute-commands-hook.sh | 698 +++++++++++++++++++++++ templates/hooks--execute-commands.sample | 131 +++++ 7 files changed, 1093 insertions(+), 30 deletions(-) create mode 100755 t/t5411-execute-commands-hook.sh create mode 100755 templates/hooks--execute-commands.sample -- 2.25.1.362.g51ebf55b93