git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: "Ævar Arnfjörð Bjarmason" <avarab@gmail.com>
To: git@vger.kernel.org
Cc: "Emily Shaffer" <emilyshaffer@google.com>,
	"Junio C Hamano" <gitster@pobox.com>, "Jeff King" <peff@peff.net>,
	"Taylor Blau" <me@ttaylorr.com>,
	"Felipe Contreras" <felipe.contreras@gmail.com>,
	"Eric Sunshine" <sunshine@sunshineco.com>,
	"brian m . carlson" <sandals@crustytoothpaste.net>,
	"Josh Steadmon" <steadmon@google.com>,
	"Jonathan Tan" <jonathantanmy@google.com>,
	"Derrick Stolee" <stolee@gmail.com>,
	"Ævar Arnfjörð Bjarmason" <avarab@gmail.com>
Subject: [PATCH v4 0/5] config-based hooks restarted
Date: Thu,  9 Sep 2021 14:41:58 +0200	[thread overview]
Message-ID: <cover-v4-0.5-00000000000-20210909T122802Z-avarab@gmail.com> (raw)
In-Reply-To: <20210819033450.3382652-1-emilyshaffer@google.com>

This is a re-roll of Emily's es/config-based-hooks topic that goes on
top of the v5 of my ab/config-based-hooks-base, and which doesn't have
errors under SANITIZE=leak.

Emily: Sorry, I've got no intention to steal this one too, hopefully
you can get around to your own re-roll.

But per my
https://lore.kernel.org/git/87sfyfgtfh.fsf@evledraar.gmail.com/ the
lack of this re-roll is is currently blocking the pick-up of my
re-rolled v5 of ab/config-based-hooks-base at [1], as well as causing
a failure in "seen" when combined with my ab/sanitize-leak-ci (and
hn/reftable, but that's another issue...).

Junio: So hopefully you can pick up the v5[1] of the base topic now &
this preliminary v4 of es/config-based-hooks.

The range-diff below is against Emily's 30ffe98601e, i.e. her v3 at
[2].

This version is based on Emily's preliminary cf1f8e34a34
(nasamuffin/config-based-hooks-restart), which appeared to be her
August 31 rebasing addressing of many outstanding points in the v3
series.

My own changes on top of that were twofold: Adjustments to changes in
the base topic (many done to make the overall diff/changes here
smaller), and memory leak fixes to get this to pass under
SANITIZE=leak, there's various other minor but not-notable changes
here and there, see the range-diff.

1. https://lore.kernel.org/git/cover-v5-00.36-00000000000-20210902T125110Z-avarab@gmail.com/
2. https://lore.kernel.org/git/20210819033450.3382652-1-emilyshaffer@google.com/

Emily Shaffer (5):
  hook: run a list of hooks instead
  hook: allow parallel hook execution
  hook: introduce "git hook list"
  hook: include hooks from the config
  hook: allow out-of-repo 'git hook' invocations

 Documentation/config.txt      |   2 +
 Documentation/config/hook.txt |  22 +++
 Documentation/git-hook.txt    | 157 ++++++++++++++++++-
 builtin/am.c                  |   4 +-
 builtin/checkout.c            |   2 +-
 builtin/clone.c               |   2 +-
 builtin/hook.c                |  71 ++++++++-
 builtin/merge.c               |   2 +-
 builtin/rebase.c              |   2 +-
 builtin/receive-pack.c        |   9 +-
 builtin/worktree.c            |   2 +-
 commit.c                      |   2 +-
 git.c                         |   2 +-
 hook.c                        | 277 +++++++++++++++++++++++++++++-----
 hook.h                        |  45 +++++-
 read-cache.c                  |   2 +-
 refs.c                        |   2 +-
 reset.c                       |   3 +-
 sequencer.c                   |   4 +-
 t/t1800-hook.sh               | 194 +++++++++++++++++++++++-
 transport.c                   |   2 +-
 21 files changed, 734 insertions(+), 74 deletions(-)
 create mode 100644 Documentation/config/hook.txt

Range-diff against v3:
1:  6d6400329cd ! 1:  2f0cac14965 hook: run a list of hooks instead
    @@ Commit message
         executable for a single hook event.
     
         Signed-off-by: Emily Shaffer <emilyshaffer@google.com>
    +    Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
      ## builtin/hook.c ##
     @@ builtin/hook.c: static int run(int argc, const char **argv, const char *prefix)
    @@ builtin/hook.c: static int run(int argc, const char **argv, const char *prefix)
      	const char *hook_name;
     -	const char *hook_path;
     +	struct list_head *hooks;
    -+
      	struct option run_options[] = {
      		OPT_BOOL(0, "ignore-missing", &ignore_missing,
      			 N_("exit quietly with a zero exit code if the requested hook cannot be found")),
     @@ builtin/hook.c: static int run(int argc, const char **argv, const char *prefix)
    - 	git_config(git_default_config, NULL);
    - 
    + 	 * run_hooks() instead...
    + 	 */
      	hook_name = argv[0];
     -	if (ignore_missing)
    ++	hooks = list_hooks(hook_name);
    ++	if (list_empty(hooks)) {
    ++		clear_hook_list(hooks);
    ++
    + 		/* ... act like a plain run_hooks() under --ignore-missing */
     -		return run_hooks_oneshot(hook_name, &opt);
     -	hook_path = find_hook(hook_name);
     -	if (!hook_path) {
    -+	hooks = list_hooks(hook_name);
    -+	if (list_empty(hooks)) {
    -+		/* ... act like run_hooks_oneshot() under --ignore-missing */
     +		if (ignore_missing)
     +			return 0;
      		error("cannot find a hook named %s", hook_name);
    @@ builtin/hook.c: static int run(int argc, const char **argv, const char *prefix)
     
      ## hook.c ##
     @@
    - #include "hook-list.h"
    + #include "run-command.h"
      #include "config.h"
      
     +static void free_hook(struct hook *ptr)
     +{
    -+	if (ptr)
    -+		free(ptr->feed_pipe_cb_data);
    ++	if (!ptr)
    ++		return;
    ++
    ++	free(ptr->feed_pipe_cb_data);
     +	free(ptr);
     +}
     +
    @@ hook.c
     +	struct list_head *pos, *tmp;
     +	list_for_each_safe(pos, tmp, head)
     +		remove_hook(pos);
    ++	free(head);
     +}
     +
    - static int known_hook(const char *name)
    + const char *find_hook(const char *name)
      {
    - 	const char **p;
    + 	static struct strbuf path = STRBUF_INIT;
     @@ hook.c: const char *find_hook(const char *name)
      
      int hook_exists(const char *name)
      {
     -	return !!find_hook(name);
    -+	return !list_empty(list_hooks(name));
    ++	struct list_head *hooks;
    ++	int exists;
    ++
    ++	hooks = list_hooks(name);
    ++	exists = !list_empty(hooks);
    ++	clear_hook_list(hooks);
    ++
    ++	return exists;
     +}
     +
     +struct list_head *list_hooks(const char *hookname)
    @@ hook.c: static int notify_hook_finished(int result,
      }
      
     -int run_hooks(const char *hook_name, const char *hook_path,
    --	      struct run_hooks_opt *options)
     +int run_hooks(const char *hook_name, struct list_head *hooks,
    -+		    struct run_hooks_opt *options)
    + 	      struct run_hooks_opt *options)
      {
     -	struct strbuf abs_path = STRBUF_INIT;
     -	struct hook my_hook = {
    @@ hook.c: int run_hooks(const char *hook_name, const char *hook_path,
     -		my_hook.hook_path = abs_path.buf;
     -	}
     -	cb_data.run_me = &my_hook;
    -+
     +	cb_data.head = hooks;
     +	cb_data.run_me = list_first_entry(hooks, struct hook, list);
      
    @@ hook.c: int run_hooks_oneshot(const char *hook_name, struct run_hooks_opt *optio
      
     -	ret = run_hooks(hook_name, hook_path, options);
     +	ret = run_hooks(hook_name, hooks, options);
    -+
    + 
      cleanup:
      	run_hooks_opt_clear(options);
    -+	clear_hook_list(hooks);
    - 	return ret;
    - }
     
      ## hook.h ##
     @@
    @@ hook.h
      #include "run-command.h"
     +#include "list.h"
      
    - /*
    -  * Returns the path to the hook file, or NULL if the hook is missing
    -@@ hook.h: const char *find_hook(const char *name);
    - int hook_exists(const char *hookname);
    - 
      struct hook {
     +	struct list_head list;
      	/* The path to the hook */
      	const char *hook_path;
      
    -@@ hook.h: struct hook {
    - 	void *feed_pipe_cb_data;
    - };
    - 
    -+/*
    -+ * Provides a linked list of 'struct hook' detailing commands which should run
    -+ * in response to the 'hookname' event, in execution order.
    -+ */
    -+struct list_head *list_hooks(const char *hookname);
    -+
    - struct run_hooks_opt
    - {
    - 	/* Environment vars to be set for each hook */
     @@ hook.h: struct hook_cb_data {
      	/* rc reflects the cumulative failure state */
      	int rc;
    @@ hook.h: struct hook_cb_data {
      	struct hook *run_me;
      	struct run_hooks_opt *options;
      	int *invoked_hook;
    +@@ hook.h: struct hook_cb_data {
    + const char *find_hook(const char *name);
    + 
    + /**
    +- * A boolean version of find_hook()
    ++ * Provides a linked list of 'struct hook' detailing commands which should run
    ++ * in response to the 'hookname' event, in execution order.
    ++ */
    ++struct list_head *list_hooks(const char *hookname);
    ++
    ++/**
    ++ * A boolean version of list_hooks()
    +  */
    + int hook_exists(const char *hookname);
    + 
     @@ hook.h: void run_hooks_opt_clear(struct run_hooks_opt *o);
    + 
    + /**
    +  * Takes an already resolved hook found via find_hook() and runs
    +- * it. Does not call run_hooks_opt_clear() for you.
    ++ * it. Does not call run_hooks_opt_clear() for you, but does call
    ++ * clear_hook_list().
       *
       * See run_hooks_oneshot() for the simpler one-shot API.
       */
     -int run_hooks(const char *hookname, const char *hook_path,
    --	      struct run_hooks_opt *options);
     +int run_hooks(const char *hookname, struct list_head *hooks,
    -+		    struct run_hooks_opt *options);
    - 
    - /**
    -  * Calls find_hook() on your "hook_name" and runs the hooks (if any)
    -@@ hook.h: int run_hooks(const char *hookname, const char *hook_path,
    -  */
    - int run_hooks_oneshot(const char *hook_name, struct run_hooks_opt *options);
    + 	      struct run_hooks_opt *options);
      
    -+/* Empties the list at 'head', calling 'free_hook()' on each entry */
    ++/**
    ++ * Empties the list at 'head', calling 'free_hook()' on each
    ++ * entry. Called implicitly by run_hooks() (and run_hooks_oneshot()).
    ++ */
     +void clear_hook_list(struct list_head *head);
     +
    - #endif
    + /**
    +  * Calls find_hook() on your "hook_name" and runs the hooks (if any)
    +  * with run_hooks().
2:  dfb995ce4d4 ! 2:  b03e70c805e hook: allow parallel hook execution
    @@ Commit message
         Signed-off-by: Emily Shaffer <emilyshaffer@google.com>
         Helped-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
    + ## Documentation/config.txt ##
    +@@ Documentation/config.txt: include::config/guitool.txt[]
    + 
    + include::config/help.txt[]
    + 
    ++include::config/hook.txt[]
    ++
    + include::config/http.txt[]
    + 
    + include::config/i18n.txt[]
    +
      ## Documentation/config/hook.txt (new) ##
     @@
     +hook.jobs::
    @@ Documentation/git-hook.txt: OPTIONS
     +--jobs::
     +	Only valid for `run`.
     ++
    -+Specify how many hooks to run simultaneously. If this flag is not specified, use
    -+the value of the `hook.jobs` config. If the config is not specified, use the
    -+number of CPUs on the current system. Some hooks may be ineligible for
    -+parallelization: for example, 'commit-msg' intends hooks modify the commit
    -+message body and cannot be parallelized.
    ++Specify how many hooks to run simultaneously. If this flag is not specified,
    ++uses the value of the `hook.jobs` config, see linkgit:git-config[1]. If the
    ++config is not specified, uses the number of CPUs on the current system. Some
    ++hooks may be ineligible for parallelization: for example, 'commit-msg' intends
    ++hooks modify the commit message body and cannot be parallelized.
     +
     +CONFIGURATION
     +-------------
    @@ hook.c: static int notify_hook_finished(int result,
     +}
     +
      int run_hooks(const char *hook_name, struct list_head *hooks,
    - 		    struct run_hooks_opt *options)
    + 	      struct run_hooks_opt *options)
      {
     @@ hook.c: int run_hooks(const char *hook_name, struct list_head *hooks,
      		.options = options,
    @@ hook.c: int run_hooks(const char *hook_name, struct list_head *hooks,
      
      	if (!options)
      		BUG("a struct run_hooks_opt must be provided to run_hooks");
    - 
    --
    +@@ hook.c: int run_hooks(const char *hook_name, struct list_head *hooks,
      	cb_data.head = hooks;
      	cb_data.run_me = list_first_entry(hooks, struct hook, list);
      
    @@ hook.h: struct run_hooks_opt
     +	 */
     +	int jobs;
     +
    - 	/* Resolve and run the "absolute_path(hook)" instead of
    + 	/*
    + 	 * Resolve and run the "absolute_path(hook)" instead of
      	 * "hook". Used for "git worktree" hooks
    - 	 */
     @@ hook.h: struct run_hooks_opt
      	int *invoked_hook;
      };
      
     -#define RUN_HOOKS_OPT_INIT { \
    --	.env = STRVEC_INIT, \
    --	.args = STRVEC_INIT, \
    --}
    --
    - /*
    -  * To specify a 'struct string_list', set 'run_hooks_opt.feed_pipe_ctx' to the
    -  * string_list and set 'run_hooks_opt.feed_pipe' to 'pipe_from_string_list()'.
    -@@ hook.h: struct hook_cb_data {
    - 	int *invoked_hook;
    - };
    - 
     +#define RUN_HOOKS_OPT_INIT_SERIAL { \
     +	.jobs = 1, \
     +	.env = STRVEC_INIT, \
    @@ hook.h: struct hook_cb_data {
     +
     +#define RUN_HOOKS_OPT_INIT_PARALLEL { \
     +	.jobs = 0, \
    -+	.env = STRVEC_INIT, \
    -+	.args = STRVEC_INIT, \
    -+}
    -+
    - void run_hooks_opt_clear(struct run_hooks_opt *o);
    - 
    - /**
    + 	.env = STRVEC_INIT, \
    + 	.args = STRVEC_INIT, \
    + }
     
      ## read-cache.c ##
     @@ read-cache.c: static int do_write_locked_index(struct index_state *istate, struct lock_file *l
3:  c8a04306e90 ! 3:  3e647b8dba7 hook: introduce "git hook list"
    @@ Commit message
         hooks were configured and whether or not they will run.
     
         Signed-off-by: Emily Shaffer <emilyshaffer@google.com>
    +    Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
      ## Documentation/git-hook.txt ##
     @@ Documentation/git-hook.txt: SYNOPSIS
    @@ builtin/hook.c: static const char * const builtin_hook_run_usage[] = {
     +
     +static int list(int argc, const char **argv, const char *prefix)
     +{
    -+	struct list_head *head, *pos;
    ++	struct list_head *hooks;
    ++	struct list_head *pos;
     +	const char *hookname = NULL;
    -+	struct strbuf hookdir_annotation = STRBUF_INIT;
    -+
     +	struct option list_options[] = {
     +		OPT_END(),
     +	};
    ++	int ret = 0;
     +
     +	argc = parse_options(argc, argv, prefix, list_options,
     +			     builtin_hook_list_usage, 0);
     +
    -+	if (argc < 1)
    ++	/*
    ++	 * The only unnamed argument provided should be the hook-name; if we add
    ++	 * arguments later they probably should be caught by parse_options.
    ++	 */
    ++	if (argc != 1)
     +		usage_msg_opt(_("You must specify a hook event name to list."),
     +			      builtin_hook_list_usage, list_options);
     +
     +	hookname = argv[0];
     +
    -+	head = hook_list(hookname);
    ++	hooks = list_hooks(hookname);
     +
    -+	if (list_empty(head))
    -+		return 1;
    ++	if (list_empty(hooks)) {
    ++		ret = 1;
    ++		goto cleanup;
    ++	}
     +
    -+	list_for_each(pos, head) {
    ++	list_for_each(pos, hooks) {
     +		struct hook *item = list_entry(pos, struct hook, list);
     +		item = list_entry(pos, struct hook, list);
     +		if (item)
     +			printf("%s\n", item->hook_path);
     +	}
     +
    -+	clear_hook_list(head);
    -+	strbuf_release(&hookdir_annotation);
    ++cleanup:
    ++	clear_hook_list(hooks);
     +
    -+	return 0;
    ++	return ret;
     +}
      static int run(int argc, const char **argv, const char *prefix)
      {
    @@ builtin/hook.c: int cmd_hook(int argc, const char **argv, const char *prefix)
      		return run(argc, argv, prefix);
      
     
    - ## hook.c ##
    -@@ hook.c: struct list_head *list_hooks(const char *hookname)
    - {
    - 	struct list_head *hook_head = xmalloc(sizeof(struct list_head));
    + ## t/t1800-hook.sh ##
    +@@ t/t1800-hook.sh: test_expect_success 'git hook usage' '
    + 	test_expect_code 129 git hook run &&
    + 	test_expect_code 129 git hook run -h &&
    + 	test_expect_code 129 git hook run --unknown 2>err &&
    ++	test_expect_code 129 git hook list &&
    ++	test_expect_code 129 git hook list -h &&
    + 	grep "unknown option" err
    + '
      
    -+
    - 	INIT_LIST_HEAD(hook_head);
    +@@ t/t1800-hook.sh: test_expect_success 'git hook run -- pass arguments' '
    + 	test_cmp expect actual
    + '
      
    - 	if (!hookname)
    -@@ hook.c: struct list_head *list_hooks(const char *hookname)
    - 
    - 	if (have_git_dir()) {
    - 		const char *hook_path = find_hook(hookname);
    --
    --		/* Add the hook from the hookdir */
    - 		if (hook_path) {
    - 			struct hook *to_add = xmalloc(sizeof(*to_add));
    - 			to_add->hook_path = hook_path;
    ++test_expect_success 'git hook list: does-not-exist hook' '
    ++	test_expect_code 1 git hook list does-not-exist
    ++'
    ++
    ++test_expect_success 'git hook list: existing hook' '
    ++	cat >expect <<-\EOF &&
    ++	.git/hooks/test-hook
    ++	EOF
    ++	git hook list test-hook >actual &&
    ++	test_cmp expect actual
    ++'
    ++
    + test_expect_success 'git hook run -- out-of-repo runs excluded' '
    + 	write_script .git/hooks/test-hook <<-EOF &&
    + 	echo Test hook
4:  af14116d0fa < -:  ----------- hook: allow running non-native hooks
5:  2bbb179962e ! 4:  d0f5b30fb27 hook: include hooks from the config
    @@ Metadata
      ## Commit message ##
         hook: include hooks from the config
     
    -    Teach the hook.[hc] library to parse configs to populare the list of
    +    Teach the hook.[hc] library to parse configs to populate the list of
         hooks to run for a given event.
     
         Multiple commands can be specified for a given hook by providing
         multiple "hook.<friendly-name>.command = <path-to-hook>" and
    -    "hook.<friendly-name>.event = <hook-event>" lines. Hooks will be run in
    -    config order of the "hook.<name>.event" lines.
    +    "hook.<friendly-name>.event = <hook-event>" lines. Hooks will be started
    +    in config order of the "hook.<name>.event" lines (but may run in
    +    parallel).
     
         For example:
     
    -      $ git config --list | grep ^hook
    +      $ git config --get-regexp "^hook\."
           hook.bar.command=~/bar.sh
           hook.bar.event=pre-commit
     
    -      $ git hook run
    -      # Runs ~/bar.sh
    -      # Runs .git/hooks/pre-commit
    +      # Will run ~/bar.sh, then .git/hooks/pre-commit
    +      $ git hook run pre-commit
     
         Signed-off-by: Emily Shaffer <emilyshaffer@google.com>
     
    @@ Documentation/config/hook.txt
      	hook execution. If unspecified, defaults to the number of processors on
     
      ## Documentation/git-hook.txt ##
    -@@ Documentation/git-hook.txt: Git is unlikely to use for a native hook later on. For example, Git is much less
    - likely to create a `mytool-validate-commit` hook than it is to create a
    - `validate-commit` hook.
    +@@ Documentation/git-hook.txt: This command is an interface to git hooks (see linkgit:githooks[5]).
    + Currently it only provides a convenience wrapper for running hooks for
    + use by git itself. In the future it might gain other functionality.
      
    -+This command parses the default configuration files for pairs of configs like
    ++It's possible to use this command to refer to hooks which are not native to Git,
    ++for example if a wrapper around Git wishes to expose hooks into its own
    ++operation in a way which is already familiar to Git users. However, wrappers
    ++invoking such hooks should be careful to name their hook events something which
    ++Git is unlikely to use for a native hook later on. For example, Git is much less
    ++likely to create a `mytool-validate-commit` hook than it is to create a
    ++`validate-commit` hook.
    ++
    ++This command parses the default configuration files for sets of configs like
     +so:
     +
     +  [hook "linter"]
     +    event = pre-commit
    -+    command = ~/bin/linter --c
    ++    command = ~/bin/linter --cpp20
     +
    -+In this example, `[hook "linter"]` represents one script - `~/bin/linter --c` -
    -+which can be shared by many repos, and even by many hook events, if appropriate.
    ++In this example, `[hook "linter"]` represents one script - `~/bin/linter
    ++--cpp20` - which can be shared by many repos, and even by many hook events, if
    ++appropriate.
    ++
    ++To add an unrelated hook which runs on a different event, for example a
    ++spell-checker for your commit messages, you would write a configuration like so:
    ++
    ++  [hook "linter"]
    ++    event = pre-commit
    ++    command = ~/bin/linter --cpp20
    ++  [hook "spellcheck"]
    ++    event = commit-msg
    ++    command = ~/bin/spellchecker
    ++
    ++With this config, when you run 'git commit', first `~/bin/linter --cpp20` will
    ++have a chance to check your files to be committed (during the `pre-commit` hook
    ++event`), and then `~/bin/spellchecker` will have a chance to check your commit
    ++message (during the `commit-msg` hook event).
     +
     +Commands are run in the order Git encounters their associated
     +`hook.<name>.event` configs during the configuration parse (see
    @@ Documentation/git-hook.txt: Git is unlikely to use for a native hook later on. F
     +  [hook "linter"]
     +    event = pre-commit
     +    event = pre-push
    -+    command = ~/bin/linter --c
    ++    command = ~/bin/linter --cpp20
     +
    -+With this config, `~/bin/linter --c` would be run by Git before a commit is
    ++With this config, `~/bin/linter --cpp20` would be run by Git before a commit is
     +generated (during `pre-commit`) as well as before a push is performed (during
     +`pre-push`).
     +
    @@ Documentation/git-hook.txt: Git is unlikely to use for a native hook later on. F
     +
     +  [hook "linter"]
     +    event = pre-commit
    -+    command = ~/bin/linter --c
    ++    command = ~/bin/linter --cpp20
     +  [hook "no-leaks"]
     +    event = pre-commit
     +    command = ~/bin/leak-detector
     +
     +With this config, before a commit is generated (during `pre-commit`), Git would
    -+first start `~/bin/linter --c` and second start `~/bin/leak-detector`. It would
    -+evaluate the output of each when deciding whether to proceed with the commit.
    ++first start `~/bin/linter --cpp20` and second start `~/bin/leak-detector`. It
    ++would evaluate the output of each when deciding whether to proceed with the
    ++commit.
     +
     +For a full list of hook events which you can set your `hook.<name>.event` to,
     +and how hooks are invoked during those events, see linkgit:githooks[5].
     +
    ++Git will ignore any `hook.<name>.event` that specifies an event it doesn't
    ++recognize. This is intended so that tools which wrap Git can use the hook
    ++infrastructure to run their own hooks; see <<WRAPPERS>> for more guidance.
    ++
     +In general, when instructions suggest adding a script to
    -+`.git/hooks/<hook-event>`, you can specify it in the config instead by running
    -+`git config --add hook.<some-name>.command <path-to-script> && git config --add
    -+hook.<some-name>.event <hook-event>` - this way you can share the script between
    -+multiple repos. That is, `cp ~/my-script.sh ~/project/.git/hooks/pre-commit`
    -+would become `git config --add hook.my-script.command ~/my-script.sh && git
    -+config --add hook.my-script.event pre-commit`.
    ++`.git/hooks/<hook-event>`, you can specify it in the config instead by running:
    ++
    ++----
    ++git config hook.<some-name>.command <path-to-script>
    ++git config --add hook.<some-name>.event <hook-event>
    ++----
    ++
    ++This way you can share the script between multiple repos. That is, `cp
    ++~/my-script.sh ~/project/.git/hooks/pre-commit` would become:
    ++
    ++----
    ++git config hook.my-script.command ~/my-script.sh
    ++git config --add hook.my-script.event pre-commit
    ++----
     +
      SUBCOMMANDS
      -----------
    @@ Documentation/git-hook.txt: Git is unlikely to use for a native hook later on. F
      +
      Any positional arguments to the hook should be passed after an
      optional `--` (or `--end-of-options`, see linkgit:gitcli[7]). The
    +@@ Documentation/git-hook.txt: config is not specified, uses the number of CPUs on the current system. Some
    + hooks may be ineligible for parallelization: for example, 'commit-msg' intends
    + hooks modify the commit message body and cannot be parallelized.
    + 
    ++[[WRAPPERS]]
    ++WRAPPERS
    ++--------
    ++
    ++`git hook run` has been designed to make it easy for tools which wrap Git to
    ++configure and execute hooks using the Git hook infrastructure. It is possible to
    ++provide arguments, environment variables (TODO this is missing from reroll TODO),
    ++and stdin via the command line, as well as specifying parallel or series
    ++execution if the user has provided multiple hooks.
    ++
    ++Assuming your wrapper wants to support a hook named "mywrapper-start-tests", you
    ++can have your users specify their hooks like so:
    ++
    ++  [hook "setup-test-dashboard"]
    ++    event = mywrapper-start-tests
    ++    command = ~/mywrapper/setup-dashboard.py --tap
    ++
    ++Then, in your 'mywrapper' tool, you can invoke any users' configured hooks by
    ++running:
    ++
    ++----
    ++git hook run mywrapper-start-tests \
    ++  # providing something to stdin
    ++  --stdin some-tempfile-123 \
    ++  # setting an env var (TODO THIS IS MISSING TODO)
    ++  --env MYWRAPPER_EXECUTION_MODE=foo \
    ++  # execute hooks in serial
    ++  --jobs 1 \
    ++  # plus some arguments of your own...
    ++  -- \
    ++  --testname bar \
    ++  baz
    ++----
    ++
    ++Take care to name your wrapper's hook events in a way which is unlikely to
    ++overlap with Git's native hooks (see linkgit:githooks[5]) - a hook event named
    ++`mywrappertool-validate-commit` is much less likely to be added to native Git
    ++than a hook event named `validate-commit`. If Git begins to use a hook event
    ++named the same thing as your wrapper hook, it may invoke your users' hooks in
    ++unintended and unsupported ways.
    ++
    + CONFIGURATION
    + -------------
    + include::config/hook.txt[]
     
      ## builtin/hook.c ##
     @@ builtin/hook.c: static int list(int argc, const char **argv, const char *prefix)
    @@ builtin/hook.c: static int list(int argc, const char **argv, const char *prefix)
     +						  : _("hook from hookdir"));
      	}
      
    - 	clear_hook_list(head);
    + cleanup:
     
      ## hook.c ##
     @@ hook.c: static void free_hook(struct hook *ptr)
    + 	if (!ptr)
    + 		return;
    + 
    ++	free(ptr->name);
    + 	free(ptr->feed_pipe_cb_data);
      	free(ptr);
      }
      
    @@ hook.c: static void free_hook(struct hook *ptr)
     +
     +	if (!to_add) {
     +		/* adding a new hook, not moving an old one */
    -+		to_add = xmalloc(sizeof(*to_add));
    -+		to_add->name = name;
    -+		to_add->feed_pipe_cb_data = NULL;
    ++		to_add = xcalloc(1, sizeof(*to_add));
    ++		to_add->name = xstrdup_or_null(name);
     +	}
     +
     +	list_add_tail(&to_add->list, head);
    @@ hook.c: static void free_hook(struct hook *ptr)
      {
      	struct hook *hook_to_remove = list_entry(to_remove, struct hook, list);
     @@ hook.c: int hook_exists(const char *name)
    + 	return exists;
    + }
      
    - struct hook_config_cb
    - {
    --	struct strbuf *hook_key;
    ++struct hook_config_cb
    ++{
     +	const char *hook_event;
    - 	struct list_head *list;
    - };
    - 
    ++	struct list_head *list;
    ++};
    ++
     +/*
     + * Callback for git_config which adds configured hooks to a hook list.  Hooks
     + * can be configured by specifying both hook.<friend-name>.command = <path> and
    @@ hook.c: int hook_exists(const char *name)
     +	 */
     +	strbuf_add(&subsection_cpy, subsection, subsection_len);
     +
    -+	append_or_move_hook(data->list, strbuf_detach(&subsection_cpy, NULL));
    -+
    ++	append_or_move_hook(data->list, subsection_cpy.buf);
    ++	strbuf_release(&subsection_cpy);
     +
     +	return 0;
     +}
     +
      struct list_head *list_hooks(const char *hookname)
    - {
    - 	if (!known_hook(hookname))
    -@@ hook.c: struct list_head *list_hooks(const char *hookname)
    - struct list_head *list_hooks_gently(const char *hookname)
      {
      	struct list_head *hook_head = xmalloc(sizeof(struct list_head));
     +	struct hook_config_cb cb_data = {
    @@ hook.c: struct list_head *list_hooks(const char *hookname)
      		BUG("null hookname was provided to hook_list()!");
      
     -	if (have_git_dir()) {
    --		const char *hook_path = find_hook_gently(hookname);
    +-		const char *hook_path = find_hook(hookname);
    ++	/* Add the hooks from the config, e.g. hook.myhook.event = pre-commit */
    ++	git_config(hook_config_lookup, &cb_data);
    + 
    +-		/* Add the hook from the hookdir */
     -		if (hook_path) {
     -			struct hook *to_add = xmalloc(sizeof(*to_add));
     -			to_add->hook_path = hook_path;
    @@ hook.c: struct list_head *list_hooks(const char *hookname)
     -			list_add_tail(&to_add->list, hook_head);
     -		}
     -	}
    -+	/* Add the hooks from the config, e.g. hook.myhook.event = pre-commit */
    -+	git_config(hook_config_lookup, &cb_data);
    -+
     +	/* Add the hook from the hookdir. The placeholder makes it easier to
     +	 * allocate work in pick_next_hook. */
    -+	if (find_hook_gently(hookname))
    ++	if (find_hook(hookname))
     +		append_or_move_hook(hook_head, NULL);
      
      	return hook_head;
    @@ hook.c: static int pick_next_hook(struct child_process *cp,
      	cp->trace2_hook_name = hook_cb->hook_name;
      	cp->dir = hook_cb->options->dir;
      
    -+	/* to enable oneliners, let config-specified hooks run in shell.
    -+	 * config-specified hooks have a name. */
    ++	/*
    ++	 * to enable oneliners, let config-specified hooks run in shell.
    ++	 * config-specified hooks have a name.
    ++	 */
     +	cp->use_shell = !!run_me->name;
     +
      	/* add command */
    @@ hook.c: static int pick_next_hook(struct child_process *cp,
     +		}
     +
     +		strvec_push(&cp->args, command);
    ++		free(command);
    ++		strbuf_release(&cmd_key);
     +	} else {
     +		/* ...from hookdir. */
     +		const char *hook_path = NULL;
     +		/*
    -+		 *
     +		 * At this point we are already running, so don't validate
    -+		 * whether the hook name is known or not.
    ++		 * whether the hook name is known or not. Validation was
    ++		 * performed earlier in list_hooks().
     +		 */
    -+		hook_path = find_hook_gently(hook_cb->hook_name);
    ++		hook_path = find_hook(hook_cb->hook_name);
     +		if (!hook_path)
     +			BUG("hookdir hook in hook list but no hookdir hook present in filesystem");
     +
    @@ hook.c: static int notify_start_failure(struct strbuf *out,
      }
     
      ## hook.h ##
    -@@ hook.h: int hook_exists(const char *hookname);
    +@@
      
      struct hook {
      	struct list_head list;
    @@ hook.h: int hook_exists(const char *hookname);
     +	 * The friendly name of the hook. NULL indicates the hook is from the
     +	 * hookdir.
     +	 */
    -+	const char *name;
    ++	char *name;
      
      	/*
      	 * Use this to keep state for your feed_pipe_fn if you are using
     
      ## t/t1800-hook.sh ##
     @@
    - #!/bin/bash
    + #!/bin/sh
      
     -test_description='git-hook command'
     +test_description='git-hook command and config-managed multihooks'
    @@ t/t1800-hook.sh
      . ./test-lib.sh
      
     +setup_hooks () {
    ++	test_config hook.ghi.command "/path/ghi"
     +	test_config hook.ghi.event pre-commit --add
    -+	test_config hook.ghi.command "/path/ghi" --add
    ++	test_config hook.ghi.event test-hook --add
    ++	test_config_global hook.def.command "/path/def"
     +	test_config_global hook.def.event pre-commit --add
    -+	test_config_global hook.def.command "/path/def" --add
     +}
     +
     +setup_hookdir () {
    @@ t/t1800-hook.sh
      	test_expect_code 129 git hook run -h &&
     +	test_expect_code 129 git hook list -h &&
      	test_expect_code 129 git hook run --unknown 2>err &&
    - 	grep "unknown option" err
    - '
    + 	test_expect_code 129 git hook list &&
    + 	test_expect_code 129 git hook list -h &&
    +@@ t/t1800-hook.sh: test_expect_success 'git hook list: does-not-exist hook' '
    + 
    + test_expect_success 'git hook list: existing hook' '
    + 	cat >expect <<-\EOF &&
    +-	.git/hooks/test-hook
    ++	hook from hookdir
    + 	EOF
    + 	git hook list test-hook >actual &&
    + 	test_cmp expect actual
     @@ t/t1800-hook.sh: test_expect_success 'stdin to hooks' '
      	test_cmp expect actual
      '
    @@ t/t1800-hook.sh: test_expect_success 'stdin to hooks' '
     +test_expect_success 'git hook list orders by config order' '
     +	setup_hooks &&
     +
    -+	cat >expected <<-EOF &&
    ++	cat >expected <<-\EOF &&
     +	def
     +	ghi
     +	EOF
    @@ t/t1800-hook.sh: test_expect_success 'stdin to hooks' '
     +	# configuring it locally.
     +	test_config hook.def.event "pre-commit" --add &&
     +
    -+	cat >expected <<-EOF &&
    ++	cat >expected <<-\EOF &&
     +	ghi
     +	def
     +	EOF
    @@ t/t1800-hook.sh: test_expect_success 'stdin to hooks' '
     +	test_cmp expected actual
     +'
     +
    ++test_expect_success 'hook can be configured for multiple events' '
    ++	setup_hooks &&
    ++
    ++	# 'ghi' should be included in both 'pre-commit' and 'test-hook'
    ++	git hook list pre-commit >actual &&
    ++	grep "ghi" actual &&
    ++	git hook list test-hook >actual &&
    ++	grep "ghi" actual
    ++'
    ++
     +test_expect_success 'git hook list shows hooks from the hookdir' '
     +	setup_hookdir &&
     +
    -+	cat >expected <<-EOF &&
    ++	cat >expected <<-\EOF &&
     +	hook from hookdir
     +	EOF
     +
    @@ t/t1800-hook.sh: test_expect_success 'stdin to hooks' '
     +'
     +
     +test_expect_success 'inline hook definitions resolve paths' '
    -+	write_script sample-hook.sh <<-EOF &&
    ++	write_script sample-hook.sh <<-\EOF &&
     +	echo \"Sample Hook\"
     +	EOF
     +
    @@ t/t1800-hook.sh: test_expect_success 'stdin to hooks' '
     +	test_config hook.stdin-b.event "test-hook" --add &&
     +	test_config hook.stdin-b.command "xargs -P1 -I% echo b%" --add &&
     +
    -+	cat >input <<-EOF &&
    ++	cat >input <<-\EOF &&
     +	1
     +	2
     +	3
     +	EOF
     +
    -+	cat >expected <<-EOF &&
    ++	cat >expected <<-\EOF &&
     +	a1
     +	a2
     +	a3
    @@ t/t1800-hook.sh: test_expect_success 'stdin to hooks' '
     +	echo 3
     +	EOF
     +
    -+	cat >expected <<-EOF &&
    ++	cat >expected <<-\EOF &&
     +	1
     +	2
     +	3
    @@ t/t1800-hook.sh: test_expect_success 'stdin to hooks' '
     +
     +	rm -rf .git/hooks
     +'
    ++
    ++test_expect_success 'rejects hooks with no commands configured' '
    ++	test_config hook.broken.event "test-hook" &&
    ++
    ++	echo broken >expected &&
    ++	git hook list test-hook >actual &&
    ++	test_cmp expected actual &&
    ++	test_must_fail git hook run test-hook
    ++'
    ++
      test_done
6:  30ffe98601e ! 5:  5d5e9726fd8 hook: allow out-of-repo 'git hook' invocations
    @@ git.c: static struct cmd_struct commands[] = {
      	{ "init-db", cmd_init_db },
     
      ## hook.c ##
    -@@ hook.c: struct list_head *list_hooks_gently(const char *hookname)
    +@@ hook.c: struct list_head *list_hooks(const char *hookname)
      
      	/* Add the hook from the hookdir. The placeholder makes it easier to
      	 * allocate work in pick_next_hook. */
    --	if (find_hook_gently(hookname))
    -+	if (have_git_dir() && find_hook_gently(hookname))
    +-	if (find_hook(hookname))
    ++	if (have_git_dir() && find_hook(hookname))
      		append_or_move_hook(hook_head, NULL);
      
      	return hook_head;
     
      ## t/t1800-hook.sh ##
    -@@ t/t1800-hook.sh: test_expect_success 'git hook run -- pass arguments' '
    +@@ t/t1800-hook.sh: test_expect_success 'git hook list: existing hook' '
      	test_cmp expect actual
      '
      
-- 
2.33.0.867.g88ec4638586


  parent reply	other threads:[~2021-09-09 14:18 UTC|newest]

Thread overview: 479+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-03-11  2:10 [PATCH v8 00/37] config-based hooks Emily Shaffer
2021-03-11  2:10 ` [PATCH v8 01/37] doc: propose hooks managed by the config Emily Shaffer
2021-03-11  2:10 ` [PATCH v8 02/37] hook: scaffolding for git-hook subcommand Emily Shaffer
2021-03-11  2:10 ` [PATCH v8 03/37] hook: add list command Emily Shaffer
2021-03-12  8:20   ` Ævar Arnfjörð Bjarmason
2021-03-24 17:31     ` Emily Shaffer
2021-03-25 12:36       ` Ævar Arnfjörð Bjarmason
2021-03-11  2:10 ` [PATCH v8 04/37] hook: include hookdir hook in list Emily Shaffer
2021-03-12  8:30   ` Ævar Arnfjörð Bjarmason
2021-03-24 17:56     ` Emily Shaffer
2021-03-24 19:11       ` Junio C Hamano
2021-03-24 19:23         ` Eric Sunshine
2021-03-24 20:07           ` Emily Shaffer
2021-03-11  2:10 ` [PATCH v8 05/37] hook: teach hook.runHookDir Emily Shaffer
2021-03-12  8:33   ` Ævar Arnfjörð Bjarmason
2021-03-24 18:46     ` Emily Shaffer
2021-03-24 22:38       ` Ævar Arnfjörð Bjarmason
2021-03-11  2:10 ` [PATCH v8 06/37] hook: implement hookcmd.<name>.skip Emily Shaffer
2021-03-12  8:49   ` Ævar Arnfjörð Bjarmason
2021-03-11  2:10 ` [PATCH v8 07/37] parse-options: parse into strvec Emily Shaffer
2021-03-12  8:50   ` Ævar Arnfjörð Bjarmason
2021-03-24 20:34     ` Emily Shaffer
2021-03-11  2:10 ` [PATCH v8 08/37] hook: add 'run' subcommand Emily Shaffer
2021-03-12  8:54   ` Ævar Arnfjörð Bjarmason
2021-03-24 21:29     ` Emily Shaffer
2021-03-12 10:22   ` Junio C Hamano
2021-03-11  2:10 ` [PATCH v8 09/37] hook: introduce hook_exists() Emily Shaffer
2021-03-11  2:10 ` [PATCH v8 10/37] hook: support passing stdin to hooks Emily Shaffer
2021-03-12  9:00   ` Ævar Arnfjörð Bjarmason
2021-03-12 10:22   ` Junio C Hamano
2021-03-11  2:10 ` [PATCH v8 11/37] run-command: allow stdin for run_processes_parallel Emily Shaffer
2021-03-11  2:10 ` [PATCH v8 12/37] hook: allow parallel hook execution Emily Shaffer
2021-03-11  2:10 ` [PATCH v8 13/37] hook: allow specifying working directory for hooks Emily Shaffer
2021-03-11  2:10 ` [PATCH v8 14/37] run-command: add stdin callback for parallelization Emily Shaffer
2021-03-11  2:10 ` [PATCH v8 15/37] hook: provide stdin by string_list or callback Emily Shaffer
2021-03-11  2:10 ` [PATCH v8 16/37] run-command: allow capturing of collated output Emily Shaffer
2021-03-11  2:10 ` [PATCH v8 17/37] hooks: allow callers to capture output Emily Shaffer
2021-03-12  9:08   ` Ævar Arnfjörð Bjarmason
2021-03-24 21:54     ` Emily Shaffer
2021-03-11  2:10 ` [PATCH v8 18/37] commit: use config-based hooks Emily Shaffer
2021-03-12 10:22   ` Junio C Hamano
2021-03-11  2:10 ` [PATCH v8 19/37] am: convert applypatch hooks to use config Emily Shaffer
2021-03-12 10:23   ` Junio C Hamano
2021-03-29 23:39     ` Emily Shaffer
2021-03-11  2:10 ` [PATCH v8 20/37] merge: use config-based hooks for post-merge hook Emily Shaffer
2021-03-11  2:10 ` [PATCH v8 21/37] gc: use hook library for pre-auto-gc hook Emily Shaffer
2021-03-11  2:10 ` [PATCH v8 22/37] rebase: teach pre-rebase to use hook.h Emily Shaffer
2021-03-12 10:24   ` Junio C Hamano
2021-03-11  2:10 ` [PATCH v8 23/37] read-cache: convert post-index-change hook to use config Emily Shaffer
2021-03-12 10:22   ` Junio C Hamano
2021-03-29 23:56     ` Emily Shaffer
2021-03-11  2:10 ` [PATCH v8 24/37] receive-pack: convert push-to-checkout hook to hook.h Emily Shaffer
2021-03-12 10:24   ` Junio C Hamano
2021-03-29 23:59     ` Emily Shaffer
2021-03-30  0:10       ` Junio C Hamano
2021-03-11  2:10 ` [PATCH v8 25/37] git-p4: use 'git hook' to run hooks Emily Shaffer
2021-03-11  2:10 ` [PATCH v8 26/37] hooks: convert 'post-checkout' hook to hook library Emily Shaffer
2021-03-11  2:10 ` [PATCH v8 27/37] hook: convert 'post-rewrite' hook to config Emily Shaffer
2021-03-11  2:10 ` [PATCH v8 28/37] transport: convert pre-push hook to use config Emily Shaffer
2021-03-11  2:10 ` [PATCH v8 29/37] reference-transaction: look for hooks in config Emily Shaffer
2021-03-11  2:10 ` [PATCH v8 30/37] receive-pack: convert 'update' hook to hook.h Emily Shaffer
2021-03-11  2:10 ` [PATCH v8 31/37] proc-receive: acquire hook list from hook.h Emily Shaffer
2021-03-11  2:10 ` [PATCH v8 32/37] post-update: use hook.h library Emily Shaffer
2021-03-12  9:14   ` Ævar Arnfjörð Bjarmason
2021-03-30  0:01     ` Emily Shaffer
2021-03-11  2:10 ` [PATCH v8 33/37] receive-pack: convert receive hooks to hook.h Emily Shaffer
2021-03-11  2:10 ` [PATCH v8 34/37] bugreport: use hook_exists instead of find_hook Emily Shaffer
2021-03-11  2:10 ` [PATCH v8 35/37] git-send-email: use 'git hook run' for 'sendemail-validate' Emily Shaffer
2021-03-12  9:21   ` Ævar Arnfjörð Bjarmason
2021-03-30  0:03     ` Emily Shaffer
2021-03-31 21:47     ` Emily Shaffer
2021-03-31 22:06       ` Junio C Hamano
2021-04-01 18:08         ` Emily Shaffer
2021-04-01 18:55           ` Junio C Hamano
2021-04-02 11:34       ` [PATCH 0/2] git-send-email: refactor duplicate $? checks into a function Ævar Arnfjörð Bjarmason
2021-04-02 11:34         ` [PATCH 1/2] git-send-email: replace "map" in void context with "for" Ævar Arnfjörð Bjarmason
2021-04-02 21:31           ` Junio C Hamano
2021-04-02 21:37             ` Emily Shaffer
2021-04-02 11:34         ` [PATCH 2/2] git-send-email: refactor duplicate $? checks into a function Ævar Arnfjörð Bjarmason
2021-04-02 21:36           ` Junio C Hamano
2021-04-04  9:19         ` [PATCH v2 0/4] refactor duplicate $? checks into a function + improve errors Ævar Arnfjörð Bjarmason
2021-04-04  9:19           ` [PATCH v2 1/4] git-send-email: replace "map" in void context with "for" Ævar Arnfjörð Bjarmason
2021-04-04  9:19           ` [PATCH v2 2/4] git-send-email: refactor duplicate $? checks into a function Ævar Arnfjörð Bjarmason
2021-04-05 19:11             ` Junio C Hamano
2021-04-05 23:47             ` Junio C Hamano
2021-04-08 22:43               ` Junio C Hamano
2021-04-08 22:46                 ` Junio C Hamano
2021-04-08 23:54                   ` Ævar Arnfjörð Bjarmason
2021-04-09  0:08                     ` Junio C Hamano
2021-05-03 20:30                       ` Emily Shaffer
2021-04-04  9:19           ` [PATCH v2 3/4] git-send-email: test full --validate output Ævar Arnfjörð Bjarmason
2021-04-04  9:19           ` [PATCH v2 4/4] git-send-email: improve --validate error output Ævar Arnfjörð Bjarmason
2021-04-05 19:14             ` Junio C Hamano
2021-04-06 14:00           ` [PATCH v3 0/3] refactor duplicate $? checks into a function + improve errors Ævar Arnfjörð Bjarmason
2021-04-06 14:00             ` [PATCH v3 1/3] git-send-email: test full --validate output Ævar Arnfjörð Bjarmason
2021-04-06 14:00             ` [PATCH v3 2/3] git-send-email: refactor duplicate $? checks into a function Ævar Arnfjörð Bjarmason
2021-04-06 14:00             ` [PATCH v3 3/3] git-send-email: improve --validate error output Ævar Arnfjörð Bjarmason
2021-04-06 20:33             ` [PATCH v3 0/3] refactor duplicate $? checks into a function + improve errors Junio C Hamano
2021-03-12 23:29   ` [PATCH v8 35/37] git-send-email: use 'git hook run' for 'sendemail-validate' Emily Shaffer
2021-03-11  2:10 ` [PATCH v8 36/37] run-command: stop thinking about hooks Emily Shaffer
2021-03-12  9:23   ` Ævar Arnfjörð Bjarmason
2021-03-30  0:07     ` Emily Shaffer
2021-03-11  2:10 ` [PATCH v8 37/37] docs: unify githooks and git-hook manpages Emily Shaffer
2021-03-12  9:29   ` Ævar Arnfjörð Bjarmason
2021-03-30  0:10     ` Emily Shaffer
2021-04-07  2:36   ` Junio C Hamano
2021-04-08 20:20     ` Jeff Hostetler
2021-04-08 21:17       ` Junio C Hamano
2021-04-08 23:46     ` Emily Shaffer
2021-04-09  0:03       ` Junio C Hamano
2021-03-11 22:26 ` [PATCH v8 00/37] config-based hooks Junio C Hamano
2021-03-12 23:27   ` Emily Shaffer
2021-03-12  9:49 ` Ævar Arnfjörð Bjarmason
2021-03-17 18:41   ` Emily Shaffer
2021-03-17 19:16     ` Emily Shaffer
2021-03-12 11:13 ` Ævar Arnfjörð Bjarmason
2021-03-25 12:41   ` Ævar Arnfjörð Bjarmason
2021-05-27  0:08 ` [PATCH v9 00/37] propose " Emily Shaffer
2021-05-27  0:08   ` [PATCH v9 01/37] doc: propose hooks managed by the config Emily Shaffer
2021-05-27  0:08   ` [PATCH v9 02/37] hook: introduce git-hook subcommand Emily Shaffer
2021-05-27  2:18     ` Junio C Hamano
2021-05-27  0:08   ` [PATCH v9 03/37] hook: include hookdir hook in list Emily Shaffer
2021-05-27  0:08   ` [PATCH v9 04/37] hook: teach hook.runHookDir Emily Shaffer
2021-05-27  0:08   ` [PATCH v9 05/37] hook: implement hookcmd.<name>.skip Emily Shaffer
2021-05-27  0:08   ` [PATCH v9 06/37] parse-options: parse into strvec Emily Shaffer
2021-05-27  0:08   ` [PATCH v9 07/37] hook: add 'run' subcommand Emily Shaffer
2021-06-03  9:07     ` Ævar Arnfjörð Bjarmason
2021-06-03 22:29       ` Junio C Hamano
2021-05-27  0:08   ` [PATCH v9 08/37] hook: introduce hook_exists() Emily Shaffer
2021-05-27  0:08   ` [PATCH v9 09/37] hook: support passing stdin to hooks Emily Shaffer
2021-05-27  0:08   ` [PATCH v9 10/37] run-command: allow stdin for run_processes_parallel Emily Shaffer
2021-05-27  0:08   ` [PATCH v9 11/37] hook: allow parallel hook execution Emily Shaffer
2021-05-27  0:08   ` [PATCH v9 12/37] hook: allow specifying working directory for hooks Emily Shaffer
2021-05-27  0:08   ` [PATCH v9 13/37] run-command: add stdin callback for parallelization Emily Shaffer
2021-05-27  0:08   ` [PATCH v9 14/37] hook: provide stdin by string_list or callback Emily Shaffer
2021-05-27  0:08   ` [PATCH v9 15/37] run-command: allow capturing of collated output Emily Shaffer
2021-05-27  0:08   ` [PATCH v9 16/37] hooks: allow callers to capture output Emily Shaffer
2021-05-27  0:08   ` [PATCH v9 17/37] commit: use config-based hooks Emily Shaffer
2021-05-27  0:08   ` [PATCH v9 18/37] am: convert applypatch hooks to use config Emily Shaffer
2021-05-27  0:08   ` [PATCH v9 19/37] merge: use config-based hooks for post-merge hook Emily Shaffer
2021-05-27  0:08   ` [PATCH v9 20/37] gc: use hook library for pre-auto-gc hook Emily Shaffer
2021-05-27  0:08   ` [PATCH v9 21/37] rebase: teach pre-rebase to use hook.h Emily Shaffer
2021-05-27  0:08   ` [PATCH v9 22/37] read-cache: convert post-index-change hook to use config Emily Shaffer
2021-05-27 23:04     ` Ævar Arnfjörð Bjarmason
2021-05-28  1:09       ` Taylor Blau
2021-05-31 19:21       ` Felipe Contreras
2021-05-27  0:08   ` [PATCH v9 23/37] receive-pack: convert push-to-checkout hook to hook.h Emily Shaffer
2021-05-27  0:08   ` [PATCH v9 24/37] git-p4: use 'git hook' to run hooks Emily Shaffer
2021-05-27  0:08   ` [PATCH v9 25/37] hooks: convert 'post-checkout' hook to hook library Emily Shaffer
2021-05-27  0:08   ` [PATCH v9 26/37] hook: convert 'post-rewrite' hook to config Emily Shaffer
2021-05-27  0:08   ` [PATCH v9 27/37] transport: convert pre-push hook to use config Emily Shaffer
2021-05-27  0:08   ` [PATCH v9 28/37] reference-transaction: look for hooks in config Emily Shaffer
2021-05-27  0:08   ` [PATCH v9 29/37] receive-pack: convert 'update' hook to hook.h Emily Shaffer
2021-05-27  0:08   ` [PATCH v9 30/37] proc-receive: acquire hook list from hook.h Emily Shaffer
2021-05-27  0:08   ` [PATCH v9 31/37] post-update: use hook.h library Emily Shaffer
2021-06-14  9:09     ` Ævar Arnfjörð Bjarmason
2021-05-27  0:08   ` [PATCH v9 32/37] receive-pack: convert receive hooks to hook.h Emily Shaffer
2021-05-27  0:08   ` [PATCH v9 33/37] bugreport: use hook_exists instead of find_hook Emily Shaffer
2021-05-27  0:08   ` [PATCH v9 34/37] git-send-email: use 'git hook run' for 'sendemail-validate' Emily Shaffer
2021-05-27 11:56     ` Ævar Arnfjörð Bjarmason
2021-05-27  0:08   ` [PATCH v9 35/37] run-command: stop thinking about hooks Emily Shaffer
2021-05-27  0:08   ` [PATCH v9 36/37] doc: clarify fsmonitor-watchman specification Emily Shaffer
2021-05-27  0:08   ` [PATCH v9 37/37] docs: link githooks and git-hook manpages Emily Shaffer
2021-06-03  9:18     ` Ævar Arnfjörð Bjarmason
2021-05-27 11:49   ` [PATCH v9 00/37] propose config-based hooks Ævar Arnfjörð Bjarmason
2021-05-27 13:36   ` Ævar Arnfjörð Bjarmason
2021-05-27 17:46     ` Felipe Contreras
2021-05-28 12:11     ` [PATCH 00/31] minimal restart of "config-based-hooks" Ævar Arnfjörð Bjarmason
2021-05-28 12:11       ` [PATCH 01/31] hooks tests: don't leave "actual" nonexisting on failure Ævar Arnfjörð Bjarmason
2021-05-28 12:11       ` [PATCH 02/31] gc tests: add a test for the "pre-auto-gc" hook Ævar Arnfjörð Bjarmason
2021-05-28 12:11       ` [PATCH 03/31] hook: add 'run' subcommand Ævar Arnfjörð Bjarmason
2021-05-28 12:11       ` [PATCH 04/31] run-command.h: move find_hook() to hook.h Ævar Arnfjörð Bjarmason
2021-05-28 12:11       ` [PATCH 05/31] hook.c: add a hook_exists() wrapper and use it in bugreport.c Ævar Arnfjörð Bjarmason
2021-05-28 12:11       ` [PATCH 06/31] gc: use hook library for pre-auto-gc hook Ævar Arnfjörð Bjarmason
2021-05-28 12:11       ` [PATCH 07/31] rebase: teach pre-rebase to use hook.h Ævar Arnfjörð Bjarmason
2021-05-28 12:11       ` [PATCH 08/31] am: convert applypatch hooks to use config Ævar Arnfjörð Bjarmason
2021-05-28 12:11       ` [PATCH 09/31] hooks: convert 'post-checkout' hook to hook library Ævar Arnfjörð Bjarmason
2021-05-28 12:11       ` [PATCH 10/31] merge: use config-based hooks for post-merge hook Ævar Arnfjörð Bjarmason
2021-05-28 12:11       ` [PATCH 11/31] git hook run: add an --ignore-missing flag Ævar Arnfjörð Bjarmason
2021-05-28 12:11       ` [PATCH 12/31] send-email: use 'git hook run' for 'sendemail-validate' Ævar Arnfjörð Bjarmason
2021-05-28 12:11       ` [PATCH 13/31] git-p4: use 'git hook' to run hooks Ævar Arnfjörð Bjarmason
2021-05-28 12:11       ` [PATCH 14/31] commit: use hook.h to execute hooks Ævar Arnfjörð Bjarmason
2021-05-28 12:11       ` [PATCH 15/31] read-cache: convert post-index-change hook to use config Ævar Arnfjörð Bjarmason
2021-05-28 12:11       ` [PATCH 16/31] receive-pack: convert push-to-checkout hook to hook.h Ævar Arnfjörð Bjarmason
2021-06-02  0:51         ` Felipe Contreras
2021-05-28 12:11       ` [PATCH 17/31] run-command: allow stdin for run_processes_parallel Ævar Arnfjörð Bjarmason
2021-05-28 12:11       ` [PATCH 18/31] hook: support passing stdin to hooks Ævar Arnfjörð Bjarmason
2021-05-28 12:11       ` [PATCH 19/31] am: convert 'post-rewrite' hook to hook.h Ævar Arnfjörð Bjarmason
2021-05-28 12:11       ` [PATCH 20/31] run-command: add stdin callback for parallelization Ævar Arnfjörð Bjarmason
2021-05-28 12:11       ` [PATCH 21/31] hook: provide stdin by string_list or callback Ævar Arnfjörð Bjarmason
2021-06-02  1:00         ` Felipe Contreras
2021-05-28 12:11       ` [PATCH 22/31] hook: convert 'post-rewrite' hook in sequencer.c to hook.h Ævar Arnfjörð Bjarmason
2021-05-28 12:11       ` [PATCH 23/31] transport: convert pre-push hook to use config Ævar Arnfjörð Bjarmason
2021-05-28 12:11       ` [PATCH 24/31] reference-transaction: use hook.h to run hooks Ævar Arnfjörð Bjarmason
2021-05-28 12:11       ` [PATCH 25/31] run-command: allow capturing of collated output Ævar Arnfjörð Bjarmason
2021-05-28 12:11       ` [PATCH 26/31] hooks: allow callers to capture output Ævar Arnfjörð Bjarmason
2021-05-28 12:11       ` [PATCH 27/31] receive-pack: convert 'update' hook to hook.h Ævar Arnfjörð Bjarmason
2021-06-02  1:04         ` Felipe Contreras
2021-05-28 12:11       ` [PATCH 28/31] post-update: use hook.h library Ævar Arnfjörð Bjarmason
2021-05-28 12:11       ` [PATCH 29/31] receive-pack: convert receive hooks to hook.h Ævar Arnfjörð Bjarmason
2021-05-28 12:11       ` [PATCH 30/31] hooks: fix a TOCTOU in "did we run a hook?" heuristic Ævar Arnfjörð Bjarmason
2021-05-28 12:48         ` Bagas Sanjaya
2021-05-28 14:11           ` Ævar Arnfjörð Bjarmason
2021-05-28 12:11       ` [PATCH 31/31] hook-list.h: add a generated list of hooks, like config-list.h Ævar Arnfjörð Bjarmason
2021-06-01  1:00         ` Ævar Arnfjörð Bjarmason
2021-06-01 18:14       ` [PATCH 00/31] minimal restart of "config-based-hooks" Emily Shaffer
2021-06-01 20:50         ` Derrick Stolee
2021-06-02  5:42           ` Felipe Contreras
2021-06-02  7:46             ` Ævar Arnfjörð Bjarmason
2021-06-02  9:34           ` Ævar Arnfjörð Bjarmason
2021-06-02  5:30         ` Felipe Contreras
2021-06-02  7:56         ` Ævar Arnfjörð Bjarmason
2021-06-02  9:39           ` Ævar Arnfjörð Bjarmason
2021-06-25 18:14           ` Felipe Contreras
2021-06-14 10:32       ` [PATCH v2 00/30] Minimal " Ævar Arnfjörð Bjarmason
2021-06-14 10:32         ` [PATCH v2 01/30] hook: add 'run' subcommand Ævar Arnfjörð Bjarmason
2021-06-14 21:33           ` Emily Shaffer
2021-06-15  9:36             ` Ævar Arnfjörð Bjarmason
2021-06-18 22:13               ` Emily Shaffer
2021-06-20 19:30                 ` Ævar Arnfjörð Bjarmason
2021-06-21  3:44                   ` Junio C Hamano
2021-06-22  0:00                   ` Emily Shaffer
2021-06-29  1:12                     ` Junio C Hamano
2021-06-25 19:02                 ` Felipe Contreras
2021-06-25 19:08             ` Felipe Contreras
2021-06-14 10:32         ` [PATCH v2 02/30] run-command.h: move find_hook() to hook.h Ævar Arnfjörð Bjarmason
2021-06-14 10:32         ` [PATCH v2 03/30] hook.c: add a hook_exists() wrapper and use it in bugreport.c Ævar Arnfjörð Bjarmason
2021-06-14 10:32         ` [PATCH v2 04/30] gc: use hook library for pre-auto-gc hook Ævar Arnfjörð Bjarmason
2021-06-14 23:57           ` Emily Shaffer
2021-06-14 10:32         ` [PATCH v2 05/30] rebase: teach pre-rebase to use hook.h Ævar Arnfjörð Bjarmason
2021-06-14 10:32         ` [PATCH v2 06/30] am: convert applypatch hooks to use config Ævar Arnfjörð Bjarmason
2021-06-14 10:32         ` [PATCH v2 07/30] hooks: convert 'post-checkout' hook to hook library Ævar Arnfjörð Bjarmason
2021-06-14 10:32         ` [PATCH v2 08/30] merge: use config-based hooks for post-merge hook Ævar Arnfjörð Bjarmason
2021-06-14 10:32         ` [PATCH v2 09/30] git hook run: add an --ignore-missing flag Ævar Arnfjörð Bjarmason
2021-06-14 10:32         ` [PATCH v2 10/30] send-email: use 'git hook run' for 'sendemail-validate' Ævar Arnfjörð Bjarmason
2021-06-14 10:33         ` [PATCH v2 11/30] git-p4: use 'git hook' to run hooks Ævar Arnfjörð Bjarmason
2021-06-14 10:33         ` [PATCH v2 12/30] commit: use hook.h to execute hooks Ævar Arnfjörð Bjarmason
2021-06-14 10:33         ` [PATCH v2 13/30] read-cache: convert post-index-change hook to use config Ævar Arnfjörð Bjarmason
2021-06-25 18:32           ` Felipe Contreras
2021-06-14 10:33         ` [PATCH v2 14/30] receive-pack: convert push-to-checkout hook to hook.h Ævar Arnfjörð Bjarmason
2021-06-14 10:33         ` [PATCH v2 15/30] run-command: remove old run_hook_{le,ve}() hook API Ævar Arnfjörð Bjarmason
2021-06-25 18:34           ` Felipe Contreras
2021-06-14 10:33         ` [PATCH v2 16/30] run-command: allow stdin for run_processes_parallel Ævar Arnfjörð Bjarmason
2021-06-14 10:33         ` [PATCH v2 17/30] hook: support passing stdin to hooks Ævar Arnfjörð Bjarmason
2021-06-14 10:33         ` [PATCH v2 18/30] am: convert 'post-rewrite' hook to hook.h Ævar Arnfjörð Bjarmason
2021-06-14 10:33         ` [PATCH v2 19/30] run-command: add stdin callback for parallelization Ævar Arnfjörð Bjarmason
2021-06-14 10:33         ` [PATCH v2 20/30] hook: provide stdin by string_list or callback Ævar Arnfjörð Bjarmason
2021-06-14 10:33         ` [PATCH v2 21/30] hook: convert 'post-rewrite' hook in sequencer.c to hook.h Ævar Arnfjörð Bjarmason
2021-06-14 10:33         ` [PATCH v2 22/30] transport: convert pre-push hook to use config Ævar Arnfjörð Bjarmason
2021-06-14 10:33         ` [PATCH v2 23/30] reference-transaction: use hook.h to run hooks Ævar Arnfjörð Bjarmason
2021-06-14 10:33         ` [PATCH v2 24/30] run-command: allow capturing of collated output Ævar Arnfjörð Bjarmason
2021-06-14 10:33         ` [PATCH v2 25/30] hooks: allow callers to capture output Ævar Arnfjörð Bjarmason
2021-06-14 10:33         ` [PATCH v2 26/30] receive-pack: convert 'update' hook to hook.h Ævar Arnfjörð Bjarmason
2021-06-14 10:33         ` [PATCH v2 27/30] post-update: use hook.h library Ævar Arnfjörð Bjarmason
2021-06-14 10:33         ` [PATCH v2 28/30] receive-pack: convert receive hooks to hook.h Ævar Arnfjörð Bjarmason
2021-06-14 10:33         ` [PATCH v2 29/30] hooks: fix a TOCTOU in "did we run a hook?" heuristic Ævar Arnfjörð Bjarmason
2021-06-14 10:33         ` [PATCH v2 30/30] hook-list.h: add a generated list of hooks, like config-list.h Ævar Arnfjörð Bjarmason
2021-06-15 10:02           ` Ævar Arnfjörð Bjarmason
2021-06-14 20:22         ` [PATCH v2 00/30] Minimal restart of "config-based-hooks" Emily Shaffer
2021-06-16  0:45           ` Junio C Hamano
2021-06-17 10:22         ` [PATCH 00/27] Base for "config-based-hooks" Ævar Arnfjörð Bjarmason
2021-06-17 10:22           ` [PATCH 01/27] hook: add 'run' subcommand Ævar Arnfjörð Bjarmason
2021-06-17 10:22           ` [PATCH 02/27] gc: use hook library for pre-auto-gc hook Ævar Arnfjörð Bjarmason
2021-07-22 21:58             ` Emily Shaffer
2021-06-17 10:22           ` [PATCH 03/27] rebase: teach pre-rebase to use hook.h Ævar Arnfjörð Bjarmason
2021-06-17 10:22           ` [PATCH 04/27] am: convert applypatch hooks to use config Ævar Arnfjörð Bjarmason
2021-06-17 10:22           ` [PATCH 05/27] hooks: convert 'post-checkout' hook to hook library Ævar Arnfjörð Bjarmason
2021-06-17 10:22           ` [PATCH 06/27] merge: use config-based hooks for post-merge hook Ævar Arnfjörð Bjarmason
2021-06-17 10:22           ` [PATCH 07/27] git hook run: add an --ignore-missing flag Ævar Arnfjörð Bjarmason
2021-07-02 23:47             ` Emily Shaffer
2021-06-17 10:22           ` [PATCH 08/27] send-email: use 'git hook run' for 'sendemail-validate' Ævar Arnfjörð Bjarmason
2021-06-17 10:22           ` [PATCH 09/27] git-p4: use 'git hook' to run hooks Ævar Arnfjörð Bjarmason
2021-06-17 10:22           ` [PATCH 10/27] commit: use hook.h to execute hooks Ævar Arnfjörð Bjarmason
2021-06-17 10:22           ` [PATCH 11/27] read-cache: convert post-index-change hook to use config Ævar Arnfjörð Bjarmason
2021-06-17 10:22           ` [PATCH 12/27] receive-pack: convert push-to-checkout hook to hook.h Ævar Arnfjörð Bjarmason
2021-06-17 10:22           ` [PATCH 13/27] run-command: remove old run_hook_{le,ve}() hook API Ævar Arnfjörð Bjarmason
2021-06-17 10:22           ` [PATCH 14/27] run-command: allow stdin for run_processes_parallel Ævar Arnfjörð Bjarmason
2021-06-17 10:22           ` [PATCH 15/27] hook: support passing stdin to hooks Ævar Arnfjörð Bjarmason
2021-06-17 10:22           ` [PATCH 16/27] am: convert 'post-rewrite' hook to hook.h Ævar Arnfjörð Bjarmason
2021-06-17 10:22           ` [PATCH 17/27] run-command: add stdin callback for parallelization Ævar Arnfjörð Bjarmason
2021-06-17 10:22           ` [PATCH 18/27] hook: provide stdin by string_list or callback Ævar Arnfjörð Bjarmason
2021-06-17 10:22           ` [PATCH 19/27] hook: convert 'post-rewrite' hook in sequencer.c to hook.h Ævar Arnfjörð Bjarmason
2021-06-17 10:22           ` [PATCH 20/27] transport: convert pre-push hook to use config Ævar Arnfjörð Bjarmason
2021-06-17 10:22           ` [PATCH 21/27] reference-transaction: use hook.h to run hooks Ævar Arnfjörð Bjarmason
2021-06-17 10:22           ` [PATCH 22/27] run-command: allow capturing of collated output Ævar Arnfjörð Bjarmason
2021-06-17 10:22           ` [PATCH 23/27] hooks: allow callers to capture output Ævar Arnfjörð Bjarmason
2021-06-17 10:22           ` [PATCH 24/27] receive-pack: convert 'update' hook to hook.h Ævar Arnfjörð Bjarmason
2021-06-17 10:22           ` [PATCH 25/27] post-update: use hook.h library Ævar Arnfjörð Bjarmason
2021-06-17 10:23           ` [PATCH 26/27] receive-pack: convert receive hooks to hook.h Ævar Arnfjörð Bjarmason
2021-06-17 10:23           ` [PATCH 27/27] hooks: fix a TOCTOU in "did we run a hook?" heuristic Ævar Arnfjörð Bjarmason
2021-06-18 22:09             ` Emily Shaffer
2021-07-15 23:25           ` [PATCH 0/9] config-based hooks restarted Emily Shaffer
2021-07-15 23:25             ` [PATCH 1/9] hook: run a list of hooks instead Emily Shaffer
2021-07-15 23:25             ` [PATCH 2/9] hook: allow parallel hook execution Emily Shaffer
2021-07-16  8:36               ` Ævar Arnfjörð Bjarmason
2021-07-22 21:12                 ` Emily Shaffer
2021-07-23  9:30                   ` Ævar Arnfjörð Bjarmason
2021-07-15 23:25             ` [PATCH 3/9] hook: introduce "git hook list" Emily Shaffer
2021-07-16  8:52               ` Ævar Arnfjörð Bjarmason
2021-07-22 22:18                 ` Emily Shaffer
2021-07-23  9:29                   ` Ævar Arnfjörð Bjarmason
2021-07-15 23:25             ` [PATCH 4/9] hook: treat hookdir hook specially Emily Shaffer
2021-07-16  8:58               ` Ævar Arnfjörð Bjarmason
2021-07-22 22:24                 ` Emily Shaffer
2021-07-23  9:26                   ` Ævar Arnfjörð Bjarmason
2021-07-23 17:33                   ` Felipe Contreras
2021-07-23 18:22                     ` Eric Sunshine
2021-07-23 20:02                       ` Felipe Contreras
2021-07-15 23:25             ` [PATCH 5/9] hook: allow running non-native hooks Emily Shaffer
2021-07-15 23:26             ` [PATCH 6/9] hook: include hooks from the config Emily Shaffer
2021-07-16  9:01               ` Ævar Arnfjörð Bjarmason
2021-07-22 22:51                 ` Emily Shaffer
2021-07-23  9:22                   ` Ævar Arnfjörð Bjarmason
2021-07-15 23:26             ` [PATCH 7/9] hook: allow out-of-repo 'git hook' invocations Emily Shaffer
2021-07-16  8:33               ` Ævar Arnfjörð Bjarmason
2021-07-22 23:07                 ` Emily Shaffer
2021-07-23  9:18                   ` Ævar Arnfjörð Bjarmason
2021-07-15 23:26             ` [PATCH 8/9] hook: teach 'hookcmd' config to alias hook scripts Emily Shaffer
2021-07-16  9:13               ` Ævar Arnfjörð Bjarmason
2021-07-22 23:31                 ` Emily Shaffer
2021-07-23  7:41                   ` Ævar Arnfjörð Bjarmason
2021-08-04 20:38                     ` Emily Shaffer
2021-08-05  0:17                       ` Ævar Arnfjörð Bjarmason
2021-08-05 21:45                         ` Emily Shaffer
2021-08-05 22:26                           ` Ævar Arnfjörð Bjarmason
2021-08-06 20:18                             ` Emily Shaffer
2021-08-04 21:49                     ` Jonathan Tan
2021-07-15 23:26             ` [PATCH 9/9] hook: implement hookcmd.<name>.skip Emily Shaffer
2021-07-28 20:39           ` [PATCH 00/27] Base for "config-based-hooks" Emily Shaffer
2021-08-03 19:38           ` [PATCH v4 00/36] Run hooks via "git run hook" & hook library Ævar Arnfjörð Bjarmason
2021-08-03 19:38             ` [PATCH v4 01/36] Makefile: mark "check" target as .PHONY Ævar Arnfjörð Bjarmason
2021-08-20  0:04               ` Emily Shaffer
2021-08-03 19:38             ` [PATCH v4 02/36] Makefile: stop hardcoding {command,config}-list.h Ævar Arnfjörð Bjarmason
2021-08-20  0:03               ` Emily Shaffer
2021-08-24 14:22                 ` Ævar Arnfjörð Bjarmason
2021-08-03 19:38             ` [PATCH v4 03/36] Makefile: remove an out-of-date comment Ævar Arnfjörð Bjarmason
2021-08-20  0:05               ` Emily Shaffer
2021-08-03 19:38             ` [PATCH v4 04/36] hook.[ch]: move find_hook() to this new library Ævar Arnfjörð Bjarmason
2021-08-20  0:08               ` Emily Shaffer
2021-08-03 19:38             ` [PATCH v4 05/36] hook.c: add a hook_exists() wrapper and use it in bugreport.c Ævar Arnfjörð Bjarmason
2021-08-20  0:09               ` Emily Shaffer
2021-08-03 19:38             ` [PATCH v4 06/36] hook.c users: use "hook_exists()" insted of "find_hook()" Ævar Arnfjörð Bjarmason
2021-08-20  0:10               ` Emily Shaffer
2021-08-03 19:38             ` [PATCH v4 07/36] hook-list.h: add a generated list of hooks, like config-list.h Ævar Arnfjörð Bjarmason
2021-08-03 19:38             ` [PATCH v4 08/36] hook: add 'run' subcommand Ævar Arnfjörð Bjarmason
2021-08-04 10:15               ` Ævar Arnfjörð Bjarmason
2021-08-03 19:38             ` [PATCH v4 09/36] gc: use hook library for pre-auto-gc hook Ævar Arnfjörð Bjarmason
2021-08-03 19:38             ` [PATCH v4 10/36] rebase: convert pre-rebase to use hook.h Ævar Arnfjörð Bjarmason
2021-08-03 19:38             ` [PATCH v4 11/36] am: convert applypatch " Ævar Arnfjörð Bjarmason
2021-08-03 19:38             ` [PATCH v4 12/36] hooks: convert 'post-checkout' hook to hook library Ævar Arnfjörð Bjarmason
2021-08-03 19:38             ` [PATCH v4 13/36] merge: convert post-merge to use hook.h Ævar Arnfjörð Bjarmason
2021-08-03 19:38             ` [PATCH v4 14/36] git hook run: add an --ignore-missing flag Ævar Arnfjörð Bjarmason
2021-08-03 19:38             ` [PATCH v4 15/36] send-email: use 'git hook run' for 'sendemail-validate' Ævar Arnfjörð Bjarmason
2021-08-03 19:38             ` [PATCH v4 16/36] git-p4: use 'git hook' to run hooks Ævar Arnfjörð Bjarmason
2021-08-03 19:38             ` [PATCH v4 17/36] commit: convert {pre-commit,prepare-commit-msg} hook to hook.h Ævar Arnfjörð Bjarmason
2021-08-03 19:38             ` [PATCH v4 18/36] read-cache: convert post-index-change to use hook.h Ævar Arnfjörð Bjarmason
2021-08-03 19:38             ` [PATCH v4 19/36] receive-pack: convert push-to-checkout hook to hook.h Ævar Arnfjörð Bjarmason
2021-08-03 19:38             ` [PATCH v4 20/36] run-command: remove old run_hook_{le,ve}() hook API Ævar Arnfjörð Bjarmason
2021-08-03 19:38             ` [PATCH v4 21/36] run-command: allow stdin for run_processes_parallel Ævar Arnfjörð Bjarmason
2021-08-03 19:38             ` [PATCH v4 22/36] hook: support passing stdin to hooks Ævar Arnfjörð Bjarmason
2021-08-03 19:38             ` [PATCH v4 23/36] am: convert 'post-rewrite' hook to hook.h Ævar Arnfjörð Bjarmason
2021-08-03 19:38             ` [PATCH v4 24/36] run-command: add stdin callback for parallelization Ævar Arnfjörð Bjarmason
2021-08-03 19:38             ` [PATCH v4 25/36] hook: provide stdin by string_list or callback Ævar Arnfjörð Bjarmason
2021-08-03 19:38             ` [PATCH v4 26/36] hook: convert 'post-rewrite' hook in sequencer.c to hook.h Ævar Arnfjörð Bjarmason
2021-08-03 19:38             ` [PATCH v4 27/36] transport: convert pre-push hook " Ævar Arnfjörð Bjarmason
2021-08-03 19:38             ` [PATCH v4 28/36] hook tests: test for exact "pre-push" hook input Ævar Arnfjörð Bjarmason
2021-08-20  0:16               ` Emily Shaffer
2021-08-03 19:38             ` [PATCH v4 29/36] hook tests: use a modern style for "pre-push" tests Ævar Arnfjörð Bjarmason
2021-08-20  0:18               ` Emily Shaffer
2021-08-03 19:38             ` [PATCH v4 30/36] reference-transaction: use hook.h to run hooks Ævar Arnfjörð Bjarmason
2021-08-03 19:38             ` [PATCH v4 31/36] run-command: allow capturing of collated output Ævar Arnfjörð Bjarmason
2021-08-03 19:38             ` [PATCH v4 32/36] hooks: allow callers to capture output Ævar Arnfjörð Bjarmason
2021-08-03 19:38             ` [PATCH v4 33/36] receive-pack: convert 'update' hook to hook.h Ævar Arnfjörð Bjarmason
2021-08-03 19:39             ` [PATCH v4 34/36] post-update: use hook.h library Ævar Arnfjörð Bjarmason
2021-08-03 19:39             ` [PATCH v4 35/36] receive-pack: convert receive hooks to hook.h Ævar Arnfjörð Bjarmason
2021-08-03 19:39             ` [PATCH v4 36/36] hooks: fix a TOCTOU in "did we run a hook?" heuristic Ævar Arnfjörð Bjarmason
2021-08-12  0:42             ` [PATCH v2 0/6] config-based hooks restarted Emily Shaffer
2021-08-12  0:42               ` [PATCH v2 1/6] hook: run a list of hooks instead Emily Shaffer
2021-08-12 17:25                 ` Junio C Hamano
2021-08-16 23:38                   ` Emily Shaffer
2021-08-12  0:42               ` [PATCH v2 2/6] hook: allow parallel hook execution Emily Shaffer
2021-08-12 17:51                 ` Junio C Hamano
2021-08-16 23:59                   ` Emily Shaffer
2021-08-12  0:42               ` [PATCH v2 3/6] hook: introduce "git hook list" Emily Shaffer
2021-08-12 18:59                 ` Junio C Hamano
2021-08-17  0:36                   ` Emily Shaffer
2021-08-12  0:42               ` [PATCH v2 4/6] hook: allow running non-native hooks Emily Shaffer
2021-08-12 19:08                 ` Junio C Hamano
2021-08-18 20:51                   ` Emily Shaffer
2021-08-18 21:14                     ` Emily Shaffer
2021-08-18 21:24                       ` Junio C Hamano
2021-08-12  0:42               ` [PATCH v2 5/6] hook: include hooks from the config Emily Shaffer
2021-08-12 20:48                 ` Junio C Hamano
2021-08-19  0:09                   ` Emily Shaffer
2021-08-12  0:42               ` [PATCH v2 6/6] hook: allow out-of-repo 'git hook' invocations Emily Shaffer
2021-08-12  4:47               ` [PATCH v2 0/6] config-based hooks restarted Junio C Hamano
2021-08-12  5:02                 ` Junio C Hamano
2021-08-16 22:31                   ` Emily Shaffer
2021-08-19  3:34               ` [PATCH v3 " Emily Shaffer
2021-08-19  3:34                 ` [PATCH v3 1/6] hook: run a list of hooks instead Emily Shaffer
2021-08-24 14:56                   ` Ævar Arnfjörð Bjarmason
2021-08-26 21:16                     ` Emily Shaffer
2021-08-27 11:15                       ` Ævar Arnfjörð Bjarmason
2021-08-19  3:34                 ` [PATCH v3 2/6] hook: allow parallel hook execution Emily Shaffer
2021-08-24 15:01                   ` Ævar Arnfjörð Bjarmason
2021-08-24 16:13                     ` Eric Sunshine
2021-08-26 22:36                     ` Emily Shaffer
2021-08-19  3:34                 ` [PATCH v3 3/6] hook: introduce "git hook list" Emily Shaffer
2021-08-24 15:08                   ` Ævar Arnfjörð Bjarmason
2021-08-26 21:43                     ` Emily Shaffer
2021-08-24 15:53                   ` Ævar Arnfjörð Bjarmason
2021-08-26 22:38                     ` Emily Shaffer
2021-08-19  3:34                 ` [PATCH v3 4/6] hook: allow running non-native hooks Emily Shaffer
2021-08-24 15:55                   ` Ævar Arnfjörð Bjarmason
2021-08-26 22:50                     ` Emily Shaffer
2021-08-27  0:22                       ` Junio C Hamano
2021-08-19  3:34                 ` [PATCH v3 5/6] hook: include hooks from the config Emily Shaffer
2021-08-19 22:39                   ` Junio C Hamano
2021-08-19 23:43                     ` Emily Shaffer
2021-08-19 23:48                       ` Junio C Hamano
2021-08-24 19:30                   ` Ævar Arnfjörð Bjarmason
2021-08-31 19:05                     ` Emily Shaffer
2021-08-19  3:34                 ` [PATCH v3 6/6] hook: allow out-of-repo 'git hook' invocations Emily Shaffer
2021-08-24 20:12                   ` Ævar Arnfjörð Bjarmason
2021-08-24 20:38                     ` Randall S. Becker
2021-08-24 22:45                       ` Ævar Arnfjörð Bjarmason
2021-08-31 21:09                     ` Emily Shaffer
2021-08-24 20:29                 ` [PATCH v3 0/6] config-based hooks restarted Ævar Arnfjörð Bjarmason
2021-09-02 22:01                   ` Emily Shaffer
2021-09-09 12:41                 ` Ævar Arnfjörð Bjarmason [this message]
2021-09-09 12:41                   ` [PATCH v4 1/5] hook: run a list of hooks instead Ævar Arnfjörð Bjarmason
2021-09-09 12:59                     ` [PATCH v4] fixup! " Ævar Arnfjörð Bjarmason
2021-09-09 12:42                   ` [PATCH v4 2/5] hook: allow parallel hook execution Ævar Arnfjörð Bjarmason
2021-09-09 12:42                   ` [PATCH v4 3/5] hook: introduce "git hook list" Ævar Arnfjörð Bjarmason
2021-09-09 12:42                   ` [PATCH v4 4/5] hook: include hooks from the config Ævar Arnfjörð Bjarmason
2021-09-09 12:42                   ` [PATCH v4 5/5] hook: allow out-of-repo 'git hook' invocations Ævar Arnfjörð Bjarmason
2021-08-19  0:17             ` [PATCH v4 00/36] Run hooks via "git run hook" & hook library Emily Shaffer
2021-08-19 23:40             ` Emily Shaffer
2021-09-02  7:21               ` Ævar Arnfjörð Bjarmason
2021-09-02 13:11             ` [PATCH v5 " Ævar Arnfjörð Bjarmason
2021-09-02 13:11               ` [PATCH v5 01/36] Makefile: mark "check" target as .PHONY Ævar Arnfjörð Bjarmason
2021-09-02 13:11               ` [PATCH v5 02/36] Makefile: stop hardcoding {command,config}-list.h Ævar Arnfjörð Bjarmason
2021-09-02 13:11               ` [PATCH v5 03/36] Makefile: remove an out-of-date comment Ævar Arnfjörð Bjarmason
2021-09-02 13:11               ` [PATCH v5 04/36] hook.[ch]: move find_hook() from run-command.c to hook.c Ævar Arnfjörð Bjarmason
2021-09-02 13:11               ` [PATCH v5 05/36] hook.c: add a hook_exists() wrapper and use it in bugreport.c Ævar Arnfjörð Bjarmason
2021-09-02 13:11               ` [PATCH v5 06/36] hook.c users: use "hook_exists()" instead of "find_hook()" Ævar Arnfjörð Bjarmason
2021-09-02 13:11               ` [PATCH v5 07/36] hook-list.h: add a generated list of hooks, like config-list.h Ævar Arnfjörð Bjarmason
2021-09-02 13:11               ` [PATCH v5 08/36] hook: add 'run' subcommand Ævar Arnfjörð Bjarmason
2021-09-02 13:11               ` [PATCH v5 09/36] gc: use hook library for pre-auto-gc hook Ævar Arnfjörð Bjarmason
2021-09-02 13:11               ` [PATCH v5 10/36] rebase: convert pre-rebase to use hook.h Ævar Arnfjörð Bjarmason
2021-09-02 13:11               ` [PATCH v5 11/36] am: convert applypatch " Ævar Arnfjörð Bjarmason
2021-09-02 13:11               ` [PATCH v5 12/36] hooks: convert 'post-checkout' hook to hook library Ævar Arnfjörð Bjarmason
2021-09-02 13:11               ` [PATCH v5 13/36] merge: convert post-merge to use hook.h Ævar Arnfjörð Bjarmason
2021-09-02 13:11               ` [PATCH v5 14/36] git hook run: add an --ignore-missing flag Ævar Arnfjörð Bjarmason
2021-09-02 13:11               ` [PATCH v5 15/36] send-email: use 'git hook run' for 'sendemail-validate' Ævar Arnfjörð Bjarmason
2021-09-02 13:11               ` [PATCH v5 16/36] git-p4: use 'git hook' to run hooks Ævar Arnfjörð Bjarmason
2021-09-02 13:11               ` [PATCH v5 17/36] commit: convert {pre-commit,prepare-commit-msg} hook to hook.h Ævar Arnfjörð Bjarmason
2021-09-02 13:11               ` [PATCH v5 18/36] read-cache: convert post-index-change to use hook.h Ævar Arnfjörð Bjarmason
2021-09-02 13:11               ` [PATCH v5 19/36] receive-pack: convert push-to-checkout hook to hook.h Ævar Arnfjörð Bjarmason
2021-09-02 13:11               ` [PATCH v5 20/36] run-command: remove old run_hook_{le,ve}() hook API Ævar Arnfjörð Bjarmason
2021-09-02 13:11               ` [PATCH v5 21/36] run-command: allow stdin for run_processes_parallel Ævar Arnfjörð Bjarmason
2021-09-02 13:11               ` [PATCH v5 22/36] hook: support passing stdin to hooks Ævar Arnfjörð Bjarmason
2021-09-02 13:11               ` [PATCH v5 23/36] am: convert 'post-rewrite' hook to hook.h Ævar Arnfjörð Bjarmason
2021-09-02 13:11               ` [PATCH v5 24/36] run-command: add stdin callback for parallelization Ævar Arnfjörð Bjarmason
2021-10-06 11:03                 ` ab/config-based-hooks-N status (was Re: [PATCH v5 24/36] run-command: add stdin callback for parallelization) Ævar Arnfjörð Bjarmason
2021-10-12 12:59                   ` Ævar Arnfjörð Bjarmason
2021-09-02 13:11               ` [PATCH v5 25/36] hook: provide stdin by string_list or callback Ævar Arnfjörð Bjarmason
2021-09-02 13:11               ` [PATCH v5 26/36] hook: convert 'post-rewrite' hook in sequencer.c to hook.h Ævar Arnfjörð Bjarmason
2021-09-02 13:11               ` [PATCH v5 27/36] transport: convert pre-push hook " Ævar Arnfjörð Bjarmason
2021-09-02 13:11               ` [PATCH v5 28/36] hook tests: test for exact "pre-push" hook input Ævar Arnfjörð Bjarmason
2021-09-02 13:11               ` [PATCH v5 29/36] hook tests: use a modern style for "pre-push" tests Ævar Arnfjörð Bjarmason
2021-09-02 13:11               ` [PATCH v5 30/36] reference-transaction: use hook.h to run hooks Ævar Arnfjörð Bjarmason
2021-09-02 13:11               ` [PATCH v5 31/36] run-command: allow capturing of collated output Ævar Arnfjörð Bjarmason
2021-09-02 13:11               ` [PATCH v5 32/36] hooks: allow callers to capture output Ævar Arnfjörð Bjarmason
2021-09-02 13:11               ` [PATCH v5 33/36] receive-pack: convert 'update' hook to hook.h Ævar Arnfjörð Bjarmason
2021-09-02 13:11               ` [PATCH v5 34/36] post-update: use hook.h library Ævar Arnfjörð Bjarmason
2021-09-02 13:11               ` [PATCH v5 35/36] receive-pack: convert receive hooks to hook.h Ævar Arnfjörð Bjarmason
2021-09-02 13:11               ` [PATCH v5 36/36] hooks: fix a TOCTOU in "did we run a hook?" heuristic Ævar Arnfjörð Bjarmason
2021-06-25 18:22         ` [PATCH v2 00/30] Minimal restart of "config-based-hooks" Felipe Contreras

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

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=cover-v4-0.5-00000000000-20210909T122802Z-avarab@gmail.com \
    --to=avarab@gmail.com \
    --cc=emilyshaffer@google.com \
    --cc=felipe.contreras@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=jonathantanmy@google.com \
    --cc=me@ttaylorr.com \
    --cc=peff@peff.net \
    --cc=sandals@crustytoothpaste.net \
    --cc=steadmon@google.com \
    --cc=stolee@gmail.com \
    --cc=sunshine@sunshineco.com \
    /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.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).