git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Ævar Arnfjörð Bjarmason" <avarab@gmail.com>
To: git@vger.kernel.org
Cc: "Junio C Hamano" <gitster@pobox.com>,
	"Emily Shaffer" <emilyshaffer@google.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 00/36] Run hooks via "git run hook" & hook library
Date: Tue,  3 Aug 2021 21:38:26 +0200	[thread overview]
Message-ID: <cover-v4-00.36-00000000000-20210803T191505Z-avarab@gmail.com> (raw)
In-Reply-To: <cover-00.27-0000000000-20210617T101216Z-avarab@gmail.com>

This is a v4 re-roll of the "Base for "config-based-hooks" topic.

It's grown from 27 to 36 patches mainly because I re-folded the two
topics it depended on into it, i.e.:

    https://lore.kernel.org/git/cover-0.3-0000000000-20210629T190137Z-avarab@gmail.com/
    https://lore.kernel.org/git/cover-0.3-0000000000-20210629T183325Z-avarab@gmail.com/

I think those have long since reached a level of stability suitable
for being merged down, but since Junio didn't pick them up
separately[1][2] there wasn't much point in keeping them split-up.

This re-roll mostly addresses Emily's comments on the v3:
https://lore.kernel.org/git/YQHAasrmcbdiCDQF@google.com/

I.e.:

 * I did not change the part where I die on hooks that aren't known to
   git itself. I think it makes sense to keep this topic purely for
   bug-for-bug compatibility with existing behavior, and to flip the
   RUN_SETUP_GENTLY flag in her follow-up feature topic.

 * The (ab)use of the run_processes_parallel() API should be gone. I
   just misunderstood how it worked.

 * The v3 would segfault on a plain "git hook run". I've changed
   builtin/hook.c to use the same pattern for subcommands as
   builtin/commit-graph.c et al. This also makes the usage output more
   consistent.

 * The stub "jobs" member of the struct is now gone, and it's
   hardcoded to 1. Emily's feature topic can add it back (per her
   suggestion).

Other updates:

 * In the base topic the s/Signed-off-by/Reviewed-by/g from René
   change that Junio applied locally has been folded in.

 * Almost all the callers were just "one-shot" callers, I introduced a
   new run_hooks_oneshot() function for those, which gets rid of the
   verbosity around memory management, see e.g. the "builtin/gc.c" in
   the range-diff below. That run_hooks_oneshot() can also take a NULL
   set of options.

 * We'd leak memory from "my_hook.feed_pipe_cb_data" in hook.c, we now
   free() it.

 * Some s/STRING_LIST_INIT_DUP/STRING_LIST_INIT_NODUP &
   strbuf_detach()/ changes in transport.c and reference-transaction
   to avoid needless verbosity around memory management.

 * A new 'hook.c users: use "hook_exists()" insted of "find_hook()"'
   patch in what was previously one of the base topics, makes
   subsequent changes smaller.

1. https://lore.kernel.org/git/87sg00qfbp.fsf@evledraar.gmail.com/
2. https://lore.kernel.org/git/87a6mevkrx.fsf@evledraar.gmail.com/

Emily Shaffer (26):
  hook.c: add a hook_exists() wrapper and use it in bugreport.c
  hook: add 'run' subcommand
  gc: use hook library for pre-auto-gc hook
  rebase: convert pre-rebase to use hook.h
  am: convert applypatch to use hook.h
  hooks: convert 'post-checkout' hook to hook library
  merge: convert post-merge to use hook.h
  send-email: use 'git hook run' for 'sendemail-validate'
  git-p4: use 'git hook' to run hooks
  commit: convert {pre-commit,prepare-commit-msg} hook to hook.h
  read-cache: convert post-index-change to use hook.h
  receive-pack: convert push-to-checkout hook to hook.h
  run-command: remove old run_hook_{le,ve}() hook API
  run-command: allow stdin for run_processes_parallel
  hook: support passing stdin to hooks
  am: convert 'post-rewrite' hook to hook.h
  run-command: add stdin callback for parallelization
  hook: provide stdin by string_list or callback
  hook: convert 'post-rewrite' hook in sequencer.c to hook.h
  transport: convert pre-push hook to hook.h
  reference-transaction: use hook.h to run hooks
  run-command: allow capturing of collated output
  hooks: allow callers to capture output
  receive-pack: convert 'update' hook to hook.h
  post-update: use hook.h library
  receive-pack: convert receive hooks to hook.h

Ævar Arnfjörð Bjarmason (10):
  Makefile: mark "check" target as .PHONY
  Makefile: stop hardcoding {command,config}-list.h
  Makefile: remove an out-of-date comment
  hook.[ch]: move find_hook() to this new library
  hook.c users: use "hook_exists()" insted of "find_hook()"
  hook-list.h: add a generated list of hooks, like config-list.h
  git hook run: add an --ignore-missing flag
  hook tests: test for exact "pre-push" hook input
  hook tests: use a modern style for "pre-push" tests
  hooks: fix a TOCTOU in "did we run a hook?" heuristic

 .gitignore                          |   2 +
 Documentation/git-hook.txt          |  51 +++++
 Documentation/githooks.txt          |   4 +
 Makefile                            |  26 ++-
 builtin.h                           |   1 +
 builtin/am.c                        |  29 +--
 builtin/bugreport.c                 |  46 +----
 builtin/checkout.c                  |  14 +-
 builtin/clone.c                     |   6 +-
 builtin/commit.c                    |  19 +-
 builtin/fetch.c                     |   1 +
 builtin/gc.c                        |   3 +-
 builtin/hook.c                      |  92 +++++++++
 builtin/merge.c                     |  21 +-
 builtin/rebase.c                    |   6 +-
 builtin/receive-pack.c              | 285 +++++++++++++---------------
 builtin/submodule--helper.c         |   2 +-
 builtin/worktree.c                  |  29 ++-
 command-list.txt                    |   1 +
 commit.c                            |  16 +-
 commit.h                            |   3 +-
 compat/vcbuild/README               |   2 +-
 config.mak.uname                    |   6 +-
 contrib/buildsystems/CMakeLists.txt |   7 +
 generate-hooklist.sh                |  18 ++
 git-p4.py                           |  72 +------
 git-send-email.perl                 |  20 +-
 git.c                               |   1 +
 hook.c                              | 246 ++++++++++++++++++++++++
 hook.h                              | 126 ++++++++++++
 read-cache.c                        |  11 +-
 refs.c                              |  41 ++--
 reset.c                             |  14 +-
 run-command.c                       | 157 +++++++--------
 run-command.h                       |  55 +++---
 sequencer.c                         |  86 ++++-----
 submodule.c                         |   1 +
 t/helper/test-run-command.c         |  46 ++++-
 t/t0061-run-command.sh              |  37 ++++
 t/t1800-hook.sh                     | 156 +++++++++++++++
 t/t5571-pre-push-hook.sh            |  94 +++++----
 t/t9001-send-email.sh               |   4 +-
 transport.c                         |  57 ++----
 43 files changed, 1303 insertions(+), 611 deletions(-)
 create mode 100644 Documentation/git-hook.txt
 create mode 100644 builtin/hook.c
 create mode 100755 generate-hooklist.sh
 create mode 100644 hook.c
 create mode 100644 hook.h
 create mode 100755 t/t1800-hook.sh

Range-diff against v3:
 1:  27c94247f87 =  1:  81fe1ed90d5 Makefile: mark "check" target as .PHONY
 2:  6e164edb0b0 !  2:  0f749530777 Makefile: stop hardcoding {command,config}-list.h
    @@ Commit message
         added in 029bac01a8 (Makefile: add {program,xdiff,test,git,fuzz}-objs
         & objects targets, 2021-02-23).
     
    +    A subsequent commit will add a new generated hook-list.h. By doing
    +    this refactoring we'll only need to add the new file to the
    +    GENERATED_H variable, not EXCEPT_HDRS, the vcbuild/README etc.
    +
         I have not tested the Windows-specific change in config.mak.uname
         being made here, but we use other variables from the Makefile in the
         same block, and the GENERATED_H is fully defined before we include
         config.mak.uname.
     
         Hardcoding command-list.h there seems to have been a case of
    -    copy/paste programming in dce7d29551 (msvc: support building Git using
    -    MS Visual C++, 2019-06-25). The config-list.h was added later in
    -    709df95b78 (help: move list_config_help to builtin/help, 2020-04-16).
    +    copy/paste programming in 976aaedca0 (msvc: add a Makefile target to
    +    pre-generate the Visual Studio solution, 2019-07-29). The
    +    config-list.h was added later in 709df95b78 (help: move
    +    list_config_help to builtin/help, 2020-04-16).
     
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
 3:  ddae86802e2 !  3:  644b31fe281 Makefile: remove an out-of-date comment
    @@ Commit message
         The rest of it was also somewhere between inaccurate and outdated,
         since as of b8ba629264 (Makefile: fold MISC_H into LIB_H, 2012-06-20)
         it's not followed by a list of header files, that got moved earlier in
    -    the file into LIB_H in b8ba629264 (Makefile: fold MISC_H into LIB_H,
    -    2012-06-20).
    +    the file into LIB_H in 60d24dd255 (Makefile: fold XDIFF_H and VCSSVN_H
    +    into LIB_H, 2012-07-06).
     
         Let's just remove it entirely, to the extent that we have anything
         useful to say here the comment on the
    @@ Makefile: ifneq ($(dep_files_present),)
     -# Dependencies on automatically generated headers such as command-list.h
     -# should _not_ be included here, since they are necessary even when
     -# building an object for the first time.
    - 
    +-
      $(OBJECTS): $(LIB_H) $(GENERATED_H)
      endif
    + 
 4:  58c37e4f06e =  4:  89c4d44b0c3 hook.[ch]: move find_hook() to this new library
 5:  0cf7e078ef4 =  5:  3514e0c0251 hook.c: add a hook_exists() wrapper and use it in bugreport.c
 -:  ----------- >  6:  d5ef40f77dc hook.c users: use "hook_exists()" insted of "find_hook()"
 6:  f343fc7ae66 !  7:  4cfd72722c1 hook-list.h: add a generated list of hooks, like config-list.h
    @@ Commit message
          - 976aaedca0 (msvc: add a Makefile target to pre-generate the Visual
            Studio solution, 2019-07-29)
     
    +    The LC_ALL=C is needed because at least in my locale the dash ("-") is
    +    ignored for the purposes of sorting, which results in a different
    +    order. I'm not aware of anything in git that has a hard dependency on
    +    the order, but e.g. the bugreport output would end up using whatever
    +    locale was in effect when git was compiled.
    +
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
    +    Helped-by: René Scharfe <l.s.r@web.de>
     
      ## .gitignore ##
     @@
    @@ Makefile: command-list.h: $(wildcard Documentation/git*.txt)
      		$(patsubst %,--exclude-program %,$(EXCLUDED_PROGRAMS)) \
      		command-list.txt >$@+ && mv $@+ $@
      
    -+hook-list.h: generate-hooklist.sh
    -+hook-list.h: Documentation/githooks.txt
    ++hook-list.h: generate-hooklist.sh Documentation/githooks.txt
     +	$(QUIET_GEN)$(SHELL_PATH) ./generate-hooklist.sh \
     +		>$@+ && mv $@+ $@
     +
    @@ contrib/buildsystems/CMakeLists.txt: if(NOT EXISTS ${CMAKE_BINARY_DIR}/config-li
      ## generate-hooklist.sh (new) ##
     @@
     +#!/bin/sh
    ++#
    ++# Usage: ./generate-hooklist.sh >hook-list.h
     +
    -+echo "/* Automatically generated by generate-hooklist.sh */"
    ++cat <<EOF
    ++/* Automatically generated by generate-hooklist.sh */
     +
    -+print_hook_list () {
    -+	cat <<EOF
     +static const char *hook_name_list[] = {
     +EOF
    -+	perl -ne '
    -+		chomp;
    -+		@l[$.] = $_;
    -+		push @h => $l[$. - 1] if /^~~~+$/s;
    -+		END {
    -+			print qq[\t"$_",\n] for sort @h;
    -+		}
    -+	' <Documentation/githooks.txt
    -+	cat <<EOF
    ++
    ++sed -n -e '/^~~~~*$/ {x; s/^.*$/	"&",/; p;}; x' \
    ++	<Documentation/githooks.txt |
    ++	LC_ALL=C sort
    ++
    ++cat <<EOF
     +	NULL,
     +};
     +EOF
    -+}
    -+
    -+echo
    -+print_hook_list
     
      ## hook.c ##
     @@
 7:  cf4b06bfdf8 !  8:  7cb4a4cb69e hook: add 'run' subcommand
    @@ Commit message
         let's start with the bare minimum required to support our simplest
         hooks.
     
    +    In terms of implementation the usage_with_options() and "goto usage"
    +    pattern here mirrors that of
    +    builtin/{commit-graph,multi-pack-index}.c.
    +
         Signed-off-by: Emily Shaffer <emilyshaffer@google.com>
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
    @@ builtin/hook.c (new)
     +#include "strbuf.h"
     +#include "strvec.h"
     +
    ++#define BUILTIN_HOOK_RUN_USAGE \
    ++	N_("git hook run <hook-name> [-- <hook-args>]")
    ++
     +static const char * const builtin_hook_usage[] = {
    -+	N_("git hook <command> [...]"),
    -+	N_("git hook run <hook-name> [-- <hook-args>]"),
    ++	BUILTIN_HOOK_RUN_USAGE,
     +	NULL
     +};
     +
     +static const char * const builtin_hook_run_usage[] = {
    -+	N_("git hook run <hook-name> [-- <hook-args>]"),
    ++	BUILTIN_HOOK_RUN_USAGE,
     +	NULL
     +};
     +
    @@ builtin/hook.c (new)
     +{
     +	int i;
     +	struct run_hooks_opt opt = RUN_HOOKS_OPT_INIT;
    -+	int rc = 0;
     +	const char *hook_name;
     +	const char *hook_path;
    -+
     +	struct option run_options[] = {
     +		OPT_END(),
     +	};
    ++	int ret;
     +
     +	argc = parse_options(argc, argv, prefix, run_options,
     +			     builtin_hook_run_usage,
    -+			     PARSE_OPT_KEEP_UNKNOWN | PARSE_OPT_KEEP_DASHDASH);
    -+
    -+	if (argc > 1) {
    -+		if (strcmp(argv[1], "--") &&
    -+		    strcmp(argv[1], "--end-of-options"))
    -+			/* Having a -- for "run" is mandatory */
    -+			usage_with_options(builtin_hook_usage, run_options);
    -+		/* Add our arguments, start after -- */
    -+		for (i = 2 ; i < argc; i++)
    -+			strvec_push(&opt.args, argv[i]);
    -+	}
    ++			     PARSE_OPT_KEEP_DASHDASH);
     +
    -+	/* Need to take into account core.hooksPath */
    -+	git_config(git_default_config, NULL);
    ++	if (!argc)
    ++		goto usage;
     +
     +	/*
    -+	 * We are not using run_hooks() because we'd like to detect
    -+	 * missing hooks. Let's find it ourselves and call
    -+	 * run_found_hooks() instead.
    ++	 * Having a -- for "run" when providing <hook-args> is
    ++	 * mandatory.
     +	 */
    ++	if (argc > 1 && strcmp(argv[1], "--") &&
    ++	    strcmp(argv[1], "--end-of-options"))
    ++		goto usage;
    ++
    ++	/* Add our arguments, start after -- */
    ++	for (i = 2 ; i < argc; i++)
    ++		strvec_push(&opt.args, argv[i]);
    ++
    ++	/* Need to take into account core.hooksPath */
    ++	git_config(git_default_config, NULL);
    ++
     +	hook_name = argv[0];
     +	hook_path = find_hook(hook_name);
     +	if (!hook_path) {
     +		error("cannot find a hook named %s", hook_name);
     +		return 1;
     +	}
    -+	rc = run_found_hooks(hook_name, hook_path, &opt);
     +
    ++	ret = run_hooks(hook_name, hook_path, &opt);
     +	run_hooks_opt_clear(&opt);
    -+
    -+	return rc;
    ++	return ret;
    ++usage:
    ++	usage_with_options(builtin_hook_run_usage, run_options);
     +}
     +
     +int cmd_hook(int argc, const char **argv, const char *prefix)
    @@ builtin/hook.c (new)
     +	struct option builtin_hook_options[] = {
     +		OPT_END(),
     +	};
    ++
     +	argc = parse_options(argc, argv, NULL, builtin_hook_options,
     +			     builtin_hook_usage, PARSE_OPT_STOP_AT_NON_OPTION);
     +	if (!argc)
    -+		usage_with_options(builtin_hook_usage, builtin_hook_options);
    ++		goto usage;
     +
     +	if (!strcmp(argv[0], "run"))
     +		return run(argc, argv, prefix);
    -+	else
    -+		usage_with_options(builtin_hook_usage, builtin_hook_options);
    ++
    ++usage:
    ++	usage_with_options(builtin_hook_usage, builtin_hook_options);
     +}
     
      ## command-list.txt ##
    @@ hook.c: int hook_exists(const char *name)
     +	struct hook_cb_data *hook_cb = pp_cb;
     +	struct hook *run_me = hook_cb->run_me;
     +
    ++	if (!run_me)
    ++		return 0;
    ++
     +	cp->no_stdin = 1;
     +	cp->env = hook_cb->options->env.v;
     +	cp->stdout_to_stderr = 1;
    @@ hook.c: int hook_exists(const char *name)
     +	/* Provide context for errors if necessary */
     +	*pp_task_cb = run_me;
     +
    ++	/*
    ++	 * This pick_next_hook() will be called again, we're only
    ++	 * running one hook, so indicate that no more work will be
    ++	 * done.
    ++	 */
    ++	hook_cb->run_me = NULL;
    ++
     +	return 1;
     +}
     +
    @@ hook.c: int hook_exists(const char *name)
     +
     +	hook_cb->rc |= result;
     +
    -+	return 1;
    ++	return 0;
     +}
     +
    -+int run_found_hooks(const char *hook_name, const char *hook_path,
    -+		    struct run_hooks_opt *options)
    ++int run_hooks(const char *hook_name, const char *hook_path,
    ++	      struct run_hooks_opt *options)
     +{
     +	struct hook my_hook = {
     +		.hook_path = hook_path,
    @@ hook.c: int hook_exists(const char *name)
     +		.hook_name = hook_name,
     +		.options = options,
     +	};
    -+	cb_data.run_me = &my_hook;
    ++	int jobs = 1;
    ++
    ++	if (!options)
    ++		BUG("a struct run_hooks_opt must be provided to run_hooks");
     +
    -+	if (options->jobs != 1)
    -+		BUG("we do not handle %d or any other != 1 job number yet", options->jobs);
    ++	cb_data.run_me = &my_hook;
     +
    -+	run_processes_parallel_tr2(options->jobs,
    ++	run_processes_parallel_tr2(jobs,
     +				   pick_next_hook,
     +				   notify_start_failure,
     +				   notify_hook_finished,
    @@ hook.c: int hook_exists(const char *name)
     +				   hook_name);
     +
     +	return cb_data.rc;
    -+}
    -+
    -+int run_hooks(const char *hook_name, struct run_hooks_opt *options)
    -+{
    -+	const char *hook_path;
    -+	int ret;
    -+	if (!options)
    -+		BUG("a struct run_hooks_opt must be provided to run_hooks");
    -+
    -+	hook_path = find_hook(hook_name);
    -+
    -+	/*
    -+	 * If you need to act on a missing hook, use run_found_hooks()
    -+	 * instead
    -+	 */
    -+	if (!hook_path)
    -+		return 0;
    -+
    -+	ret = run_found_hooks(hook_name, hook_path, options);
    -+	return ret;
     +}
     
      ## hook.h ##
    @@ hook.h: const char *find_hook(const char *name);
     +
     +	/* Args to be passed to each hook */
     +	struct strvec args;
    -+
    -+	/*
    -+	 * Number of threads to parallelize across, currently a stub,
    -+	 * we use the parallel API for future-proofing, but we always
    -+	 * have one hook of a given name, so this is always an
    -+	 * implicit 1 for now.
    -+	 */
    -+	int jobs;
     +};
     +
     +#define RUN_HOOKS_OPT_INIT { \
    -+	.jobs = 1, \
     +	.env = STRVEC_INIT, \
     +	.args = STRVEC_INIT, \
     +}
     +
    ++/*
    ++ * Callback provided to feed_pipe_fn and consume_sideband_fn.
    ++ */
     +struct hook_cb_data {
     +	/* rc reflects the cumulative failure state */
     +	int rc;
    @@ hook.h: const char *find_hook(const char *name);
     +
     +void run_hooks_opt_clear(struct run_hooks_opt *o);
     +
    -+/*
    -+ * Calls find_hook(hookname) and runs the hooks (if any) with
    -+ * run_found_hooks().
    -+ */
    -+int run_hooks(const char *hook_name, struct run_hooks_opt *options);
    -+
    -+/*
    -+ * Takes an already resolved hook and runs it. Internally the simpler
    -+ * run_hooks() will call this.
    ++/**
    ++ * Takes an already resolved hook found via find_hook() and runs
    ++ * it. Does not call run_hooks_opt_clear() for you.
     + */
    -+int run_found_hooks(const char *hookname, const char *hook_path,
    -+		    struct run_hooks_opt *options);
    ++int run_hooks(const char *hookname, const char *hook_path,
    ++	      struct run_hooks_opt *options);
      #endif
     
      ## t/t1800-hook.sh (new) ##
    @@ t/t1800-hook.sh (new)
     +
     +test_expect_success 'git hook usage' '
     +	test_expect_code 129 git hook &&
    -+	test_expect_code 129 git hook -h &&
    -+	test_expect_code 129 git hook run -h
    ++	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 &&
    ++	grep "unknown option" err
     +'
     +
     +test_expect_success 'setup GIT_TEST_FAKE_HOOKS=true to permit "test-hook" and "does-not-exist" names"' '
 8:  7209f73f281 !  9:  2b8500aa675 gc: use hook library for pre-auto-gc hook
    @@ Metadata
      ## Commit message ##
         gc: use hook library for pre-auto-gc hook
     
    -    Using the hook.h library instead of the run-command.h library to run
    -    pre-auto-gc means that those hooks can be set up in config files, as
    -    well as in the hookdir. pre-auto-gc is called only from builtin/gc.c.
    +    Move the pre-auto-gc hook away from run-command.h to and over to the
    +    new hook.h library.
    +
    +    To do this introduce a simple run_hooks_oneshot() wrapper, we'll be
    +    using it extensively for these simple cases of wanting to run a single
    +    hook under a given name, and having it free the memory we allocate for
    +    us.
     
         Signed-off-by: Emily Shaffer <emilyshaffer@google.com>
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
    @@ builtin/gc.c
      
      #define FAILED_RUN "failed to run %s"
      
    -@@ builtin/gc.c: static void add_repack_incremental_option(void)
    - 
    - static int need_to_gc(void)
    - {
    -+	struct run_hooks_opt hook_opt = RUN_HOOKS_OPT_INIT;
    -+
    - 	/*
    - 	 * Setting gc.auto to 0 or negative can disable the
    - 	 * automatic gc.
     @@ builtin/gc.c: static int need_to_gc(void)
      	else
      		return 0;
      
     -	if (run_hook_le(NULL, "pre-auto-gc", NULL))
    -+	if (run_hooks("pre-auto-gc", &hook_opt)) {
    -+		run_hooks_opt_clear(&hook_opt);
    ++	if (run_hooks_oneshot("pre-auto-gc", NULL))
      		return 0;
    -+	}
    -+	run_hooks_opt_clear(&hook_opt);
      	return 1;
      }
    +
    + ## hook.c ##
    +@@ hook.c: int run_hooks(const char *hook_name, const char *hook_path,
      
    + 	return cb_data.rc;
    + }
    ++
    ++int run_hooks_oneshot(const char *hook_name, struct run_hooks_opt *options)
    ++{
    ++	const char *hook_path;
    ++	int ret;
    ++	struct run_hooks_opt hook_opt_scratch = RUN_HOOKS_OPT_INIT;
    ++
    ++	if (!options)
    ++		options = &hook_opt_scratch;
    ++
    ++	hook_path = find_hook(hook_name);
    ++	if (!hook_path) {
    ++		ret = 0;
    ++		goto cleanup;
    ++	}
    ++
    ++	ret = run_hooks(hook_name, hook_path, options);
    ++cleanup:
    ++	run_hooks_opt_clear(options);
    ++	return ret;
    ++}
    +
    + ## hook.h ##
    +@@ 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.
    ++ *
    ++ * 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);
    ++
    ++/**
    ++ * Calls find_hook() on your "hook_name" and runs the hooks (if any)
    ++ * with run_hooks().
    ++ *
    ++ * If "options" is provided calls run_hooks_opt_clear() on it for
    ++ * you. If "options" is NULL a scratch one will be provided for you
    ++ * before calling run_hooks().
    ++ */
    ++int run_hooks_oneshot(const char *hook_name, struct run_hooks_opt *options);
    ++
    + #endif
 9:  e9a1e7cf61e ! 10:  3ee55d2c10f rebase: teach pre-rebase to use hook.h
    @@ Metadata
     Author: Emily Shaffer <emilyshaffer@google.com>
     
      ## Commit message ##
    -    rebase: teach pre-rebase to use hook.h
    +    rebase: convert pre-rebase to use hook.h
     
         Move the pre-rebase hook away from run-command.h to and over to the
         new hook.h library.
    @@ builtin/rebase.c: int cmd_rebase(int argc, const char **argv, const char *prefix
      	if (!ok_to_skip_pre_rebase &&
     -	    run_hook_le(NULL, "pre-rebase", options.upstream_arg,
     -			argc ? argv[0] : NULL, NULL))
    -+	    run_hooks("pre-rebase", &hook_opt)) {
    -+		run_hooks_opt_clear(&hook_opt);
    ++	    run_hooks_oneshot("pre-rebase", &hook_opt))
      		die(_("The pre-rebase hook refused to rebase."));
    -+	}
    -+	run_hooks_opt_clear(&hook_opt);
      
      	if (options.flags & REBASE_DIFFSTAT) {
    - 		struct diff_options opts;
10:  1d087269303 ! 11:  050f20d14f0 am: convert applypatch hooks to use config
    @@ Metadata
     Author: Emily Shaffer <emilyshaffer@google.com>
     
      ## Commit message ##
    -    am: convert applypatch hooks to use config
    +    am: convert applypatch to use hook.h
     
         Teach pre-applypatch, post-applypatch, and applypatch-msg to use the
         hook.h library instead of the run-command.h library.
    @@ builtin/am.c: static void am_destroy(const struct am_state *state)
      	assert(state->msg);
     -	ret = run_hook_le(NULL, "applypatch-msg", am_path(state, "final-commit"), NULL);
     +	strvec_push(&opt.args, am_path(state, "final-commit"));
    -+	ret = run_hooks("applypatch-msg", &opt);
    -+	run_hooks_opt_clear(&opt);
    ++	ret = run_hooks_oneshot("applypatch-msg", &opt);
      
      	if (!ret) {
      		FREE_AND_NULL(state->msg);
     @@ builtin/am.c: static void do_commit(const struct am_state *state)
    - 	struct commit_list *parents = NULL;
      	const char *reflog_msg, *author, *committer = NULL;
      	struct strbuf sb = STRBUF_INIT;
    -+	struct run_hooks_opt hook_opt_pre = RUN_HOOKS_OPT_INIT;
    -+	struct run_hooks_opt hook_opt_post = RUN_HOOKS_OPT_INIT;
      
     -	if (run_hook_le(NULL, "pre-applypatch", NULL))
    -+	if (run_hooks("pre-applypatch", &hook_opt_pre)) {
    -+		run_hooks_opt_clear(&hook_opt_pre);
    ++	if (run_hooks_oneshot("pre-applypatch", NULL))
      		exit(1);
    -+	}
      
      	if (write_cache_as_tree(&tree, 0, NULL))
    - 		die(_("git write-tree failed to write a tree"));
     @@ builtin/am.c: static void do_commit(const struct am_state *state)
      		fclose(fp);
      	}
      
     -	run_hook_le(NULL, "post-applypatch", NULL);
    -+	run_hooks("post-applypatch", &hook_opt_post);
    ++	run_hooks_oneshot("post-applypatch", NULL);
      
    -+	run_hooks_opt_clear(&hook_opt_pre);
    -+	run_hooks_opt_clear(&hook_opt_post);
      	strbuf_release(&sb);
      }
    - 
11:  32eec5dc2f0 ! 12:  ac875d284da hooks: convert 'post-checkout' hook to hook library
    @@ builtin/checkout.c: struct branch_info {
     -			   oid_to_hex(new_commit ? &new_commit->object.oid : null_oid()),
     -			   changed ? "1" : "0", NULL);
     +	struct run_hooks_opt opt = RUN_HOOKS_OPT_INIT;
    -+	int rc;
     +
      	/* "new_commit" can be NULL when checking out from the index before
      	   a commit exists. */
    @@ builtin/checkout.c: struct branch_info {
     +		     oid_to_hex(new_commit ? &new_commit->object.oid : null_oid()),
     +		     changed ? "1" : "0",
     +		     NULL);
    -+	rc = run_hooks("post-checkout", &opt);
    -+	run_hooks_opt_clear(&opt);
    -+	return rc;
    ++	return run_hooks_oneshot("post-checkout", &opt);
      }
      
      static int update_some(const struct object_id *oid, struct strbuf *base,
    @@ builtin/clone.c: static int checkout(int submodule_progress)
     -	err |= run_hook_le(NULL, "post-checkout", oid_to_hex(null_oid()),
     -			   oid_to_hex(&oid), "1", NULL);
     +	strvec_pushl(&hook_opt.args, oid_to_hex(null_oid()), oid_to_hex(&oid), "1", NULL);
    -+	err |= run_hooks("post-checkout", &hook_opt);
    -+	run_hooks_opt_clear(&hook_opt);
    ++	err |= run_hooks_oneshot("post-checkout", &hook_opt);
      
      	if (!err && (option_recurse_submodules.nr > 0)) {
      		struct strvec args = STRVEC_INIT;
    @@ builtin/worktree.c: static int add_worktree(const char *path, const char *refnam
     +		opt.dir = path;
     +		opt.absolute_path = 1;
     +
    -+		ret = run_hooks("post-checkout", &opt);
    -+
    -+		run_hooks_opt_clear(&opt);
    ++		ret = run_hooks_oneshot("post-checkout", &opt);
      	}
      
      	strvec_clear(&child_env);
    @@ hook.c: static int pick_next_hook(struct child_process *cp,
      	/* add command */
      	strvec_push(&cp->args, run_me->hook_path);
     @@ hook.c: static int notify_hook_finished(int result,
    - int run_found_hooks(const char *hook_name, const char *hook_path,
    - 		    struct run_hooks_opt *options)
    + int run_hooks(const char *hook_name, const char *hook_path,
    + 	      struct run_hooks_opt *options)
      {
     +	struct strbuf abs_path = STRBUF_INIT;
      	struct hook my_hook = {
      		.hook_path = hook_path,
      	};
    -@@ hook.c: int run_found_hooks(const char *hook_name, const char *hook_path,
    - 		.hook_name = hook_name,
    - 		.options = options,
    - 	};
    +@@ hook.c: int run_hooks(const char *hook_name, const char *hook_path,
    + 	if (!options)
    + 		BUG("a struct run_hooks_opt must be provided to run_hooks");
    + 
     +	if (options->absolute_path) {
     +		strbuf_add_absolute_path(&abs_path, hook_path);
     +		my_hook.hook_path = abs_path.buf;
     +	}
      	cb_data.run_me = &my_hook;
      
    - 	if (options->jobs != 1)
    -@@ hook.c: int run_found_hooks(const char *hook_name, const char *hook_path,
    - 				   &cb_data,
    + 	run_processes_parallel_tr2(jobs,
    +@@ hook.c: int run_hooks(const char *hook_name, const char *hook_path,
      				   "hook",
      				   hook_name);
    + 
     +	if (options->absolute_path)
     +		strbuf_release(&abs_path);
    - 
    ++
      	return cb_data.rc;
      }
    + 
     
      ## hook.h ##
     @@ hook.h: struct run_hooks_opt
    - 	 * implicit 1 for now.
    - 	 */
    - 	int jobs;
    + 
    + 	/* Args to be passed to each hook */
    + 	struct strvec args;
     +
     +	/* Resolve and run the "absolute_path(hook)" instead of
     +	 * "hook". Used for "git worktree" hooks
    @@ hook.h: struct run_hooks_opt
     +
     +	/* Path to initial working directory for subprocess */
     +	const char *dir;
    -+
      };
      
      #define RUN_HOOKS_OPT_INIT { \
     
      ## read-cache.c ##
     @@
    - #include "progress.h"
      #include "sparse-index.h"
      #include "csum-file.h"
    + #include "promisor-remote.h"
     +#include "hook.h"
      
      /* Mask for the name length in ce_flags in the on-disk index */
    @@ reset.c: int reset_head(struct repository *r, struct object_id *oid, const char
     +			     oid_to_hex(oid),
     +			     "1",
     +			     NULL);
    -+		run_hooks("post-checkout", &opt);
    -+		run_hooks_opt_clear(&opt);
    ++		run_hooks_oneshot("post-checkout", &opt);
     +	}
      
      leave_reset_head:
12:  e9fa3f67593 ! 13:  69763bc2255 merge: use config-based hooks for post-merge hook
    @@ Metadata
     Author: Emily Shaffer <emilyshaffer@google.com>
     
      ## Commit message ##
    -    merge: use config-based hooks for post-merge hook
    +    merge: convert post-merge to use hook.h
     
    -    Teach post-merge to use the hook.h library instead of the run-command.h
    -    library to run hooks. This means that post-merge hooks can come from the
    -    config as well as from the hookdir. post-merge is invoked only from
    -    builtin/merge.c.
    +    Teach post-merge to use the hook.h library instead of the
    +    run-command.h library to run hooks.
     
         Signed-off-by: Emily Shaffer <emilyshaffer@google.com>
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
    @@ builtin/merge.c: static void finish(struct commit *head_commit,
      	/* Run a post-merge hook */
     -	run_hook_le(NULL, "post-merge", squash ? "1" : "0", NULL);
     +	strvec_push(&opt.args, squash ? "1" : "0");
    -+	run_hooks("post-merge", &opt);
    -+	run_hooks_opt_clear(&opt);
    ++	run_hooks_oneshot("post-merge", &opt);
      
      	apply_autostash(git_path_merge_autostash(the_repository));
      	strbuf_release(&reflog_message);
    -@@ builtin/merge.c: static void prepare_to_commit(struct commit_list *remoteheads)
    - 	 * and write it out as a tree.  We must do this before we invoke
    - 	 * the editor and after we invoke run_status above.
    - 	 */
    --	if (find_hook("pre-merge-commit"))
    -+	if (hook_exists("pre-merge-commit"))
    - 		discard_cache();
    - 	read_cache_from(index_file);
    - 	strbuf_addbuf(&msg, &merge_msg);
13:  12347d901bb ! 14:  2ca1ca1b8e4 git hook run: add an --ignore-missing flag
    @@ Documentation/git-hook.txt: optional `--` (or `--end-of-options`, see linkgit:gi
      linkgit:githooks[5]
     
      ## builtin/hook.c ##
    +@@
    + #include "strvec.h"
    + 
    + #define BUILTIN_HOOK_RUN_USAGE \
    +-	N_("git hook run <hook-name> [-- <hook-args>]")
    ++	N_("git hook run [--ignore-missing] <hook-name> [-- <hook-args>]")
    + 
    + static const char * const builtin_hook_usage[] = {
    + 	BUILTIN_HOOK_RUN_USAGE,
     @@ builtin/hook.c: static int run(int argc, const char **argv, const char *prefix)
    + {
      	int i;
      	struct run_hooks_opt opt = RUN_HOOKS_OPT_INIT;
    - 	int rc = 0;
     +	int ignore_missing = 0;
      	const char *hook_name;
      	const char *hook_path;
    - 
      	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")),
      		OPT_END(),
      	};
    - 
    + 	int ret;
     @@ builtin/hook.c: static int run(int argc, const char **argv, const char *prefix)
    - 	/*
    - 	 * We are not using run_hooks() because we'd like to detect
    - 	 * missing hooks. Let's find it ourselves and call
    --	 * run_found_hooks() instead.
    -+	 * run_found_hooks() instead...
    - 	 */
    + 	git_config(git_default_config, NULL);
    + 
      	hook_name = argv[0];
    ++	if (ignore_missing)
    ++		return run_hooks_oneshot(hook_name, &opt);
      	hook_path = find_hook(hook_name);
      	if (!hook_path) {
    -+		/* ... act like run_hooks() under --ignore-missing */
    -+		if (ignore_missing)
    -+			return 0;
      		error("cannot find a hook named %s", hook_name);
    - 		return 1;
    - 	}
     
      ## t/t1800-hook.sh ##
     @@ t/t1800-hook.sh: test_expect_success 'git hook run: nonexistent hook' '
      	test_cmp stderr.expect stderr.actual
      '
      
    --test_expect_success 'git hook run: basic' '
     +test_expect_success 'git hook run: nonexistent hook with --ignore-missing' '
     +	git hook run --ignore-missing does-not-exist 2>stderr.actual &&
     +	test_must_be_empty stderr.actual
     +'
     +
    -+test_expect_success 'git hook run -- basic' '
    + test_expect_success 'git hook run: basic' '
      	write_script .git/hooks/test-hook <<-EOF &&
      	echo Test hook
    - 	EOF
14:  71d209b4077 ! 15:  5b66b04bec7 send-email: use 'git hook run' for 'sendemail-validate'
    @@ git-send-email.perl: sub validate_patch {
      	if ($repo) {
     +		my $hook_name = 'sendemail-validate';
      		my $hooks_path = $repo->command_oneline('rev-parse', '--git-path', 'hooks');
    --		my $validate_hook = catfile($hooks_path,
    + 		require File::Spec;
    +-		my $validate_hook = File::Spec->catfile($hooks_path,
     -					    'sendemail-validate');
    -+		my $validate_hook = catfile($hooks_path, $hook_name);
    ++		my $validate_hook = File::Spec->catfile($hooks_path, $hook_name);
      		my $hook_error;
      		if (-x $validate_hook) {
    - 			my $target = abs_path($fn);
    + 			require Cwd;
     @@ git-send-email.perl: sub validate_patch {
      			chdir($repo->wc_path() or $repo->repo_path())
      				or die("chdir: $!");
15:  246a82b55b2 = 16:  14a37a43db2 git-p4: use 'git hook' to run hooks
16:  e3f8482d803 ! 17:  ad5d0e0e7de commit: use hook.h to execute hooks
    @@ Metadata
     Author: Emily Shaffer <emilyshaffer@google.com>
     
      ## Commit message ##
    -    commit: use hook.h to execute hooks
    +    commit: convert {pre-commit,prepare-commit-msg} hook to hook.h
     
    -    Teach run_commit_hook() to call hook.h instead of run-command.h. This
    -    covers 'pre-commit', 'commit-msg', and
    -    'prepare-commit-msg'.
    -
    -    Additionally, ask the hook library - not run-command - whether any
    -    hooks will be run, as it's possible hooks may exist in the config but
    -    not the hookdir.
    -
    -    Because all but 'post-commit' hooks are expected to make some state
    -    change, force all but 'post-commit' hook to run in series. 'post-commit'
    -    "is meant primarily for notification, and cannot affect the outcome of
    -    `git commit`," so it is fine to run in parallel.
    +    Move these hooks hook away from run-command.h to and over to the new
    +    hook.h library.
     
         Signed-off-by: Emily Shaffer <emilyshaffer@google.com>
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
    - ## builtin/commit.c ##
    -@@ builtin/commit.c: static int prepare_to_commit(const char *index_file, const char *prefix,
    - 		return 0;
    - 	}
    - 
    --	if (!no_verify && find_hook("pre-commit")) {
    -+	if (!no_verify && hook_exists("pre-commit")) {
    - 		/*
    - 		 * Re-read the index as pre-commit hook could have updated it,
    - 		 * and write it out as a tree.  We must do this before we invoke
    -
      ## commit.c ##
     @@
      #include "commit-reach.h"
    @@ commit.c: size_t ignore_non_trailer(const char *buf, size_t len)
     -	struct strvec hook_env = STRVEC_INIT;
     +	struct run_hooks_opt opt = RUN_HOOKS_OPT_INIT;
      	va_list args;
    +-	int ret;
     +	const char *arg;
    - 	int ret;
    --
    + 
     -	strvec_pushf(&hook_env, "GIT_INDEX_FILE=%s", index_file);
     +	strvec_pushf(&opt.env, "GIT_INDEX_FILE=%s", index_file);
      
    @@ commit.c: size_t ignore_non_trailer(const char *buf, size_t len)
     +		strvec_push(&opt.args, arg);
      	va_end(args);
     -	strvec_clear(&hook_env);
    -+
    -+	ret = run_hooks(name, &opt);
    -+	run_hooks_opt_clear(&opt);
      
    - 	return ret;
    +-	return ret;
    ++	return run_hooks_oneshot(name, &opt);
      }
    -
    - ## sequencer.c ##
    -@@ sequencer.c: static int try_to_commit(struct repository *r,
    - 		}
    - 	}
    - 
    --	if (find_hook("prepare-commit-msg")) {
    -+	if (hook_exists("prepare-commit-msg")) {
    - 		res = run_prepare_commit_msg_hook(r, msg, hook_commit);
    - 		if (res)
    - 			goto out;
17:  6ed61071c5e ! 18:  3d3a33e2674 read-cache: convert post-index-change hook to use config
    @@ Metadata
     Author: Emily Shaffer <emilyshaffer@google.com>
     
      ## Commit message ##
    -    read-cache: convert post-index-change hook to use config
    +    read-cache: convert post-index-change to use hook.h
     
    -    By using hook.h instead of run-command.h to run, post-index-change hooks
    -    can now be specified in the config in addition to the hookdir.
    -    post-index-change is not run anywhere besides in read-cache.c.
    +    Move the post-index-change hook away from run-command.h to and over to
    +    the new hook.h library.
     
         This removes the last direct user of run_hook_ve(), so we can make the
         function static now. It'll be removed entirely soon.
    @@ read-cache.c: static int do_write_locked_index(struct index_state *istate, struc
     +		     istate->updated_workdir ? "1" : "0",
     +		     istate->updated_skipworktree ? "1" : "0",
     +		     NULL);
    -+	run_hooks("post-index-change", &hook_opt);
    -+	run_hooks_opt_clear(&hook_opt);
    ++	run_hooks_oneshot("post-index-change", &hook_opt);
     +
      	istate->updated_workdir = 0;
      	istate->updated_skipworktree = 0;
18:  e4ef3f4548a ! 19:  893f8666301 receive-pack: convert push-to-checkout hook to hook.h
    @@ Metadata
      ## Commit message ##
         receive-pack: convert push-to-checkout hook to hook.h
     
    -    By using hook.h instead of run-command.h to invoke push-to-checkout,
    -    hooks can now be specified in the config as well as in the hookdir.
    -    push-to-checkout is not called anywhere but in builtin/receive-pack.c.
    +    Move the push-to-checkout hook away from run-command.h to and over to
    +    the new hook.h library.
     
         Signed-off-by: Emily Shaffer <emilyshaffer@google.com>
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
    @@ builtin/receive-pack.c: static const char *push_to_checkout(unsigned char *hash,
     -			hash_to_hex(hash), NULL))
     +	strvec_pushv(&opt.env, env->v);
     +	strvec_push(&opt.args, hash_to_hex(hash));
    -+	if (run_hooks(push_to_checkout_hook, &opt)) {
    -+		run_hooks_opt_clear(&opt);
    ++	if (run_hooks_oneshot(push_to_checkout_hook, &opt))
      		return "push-to-checkout hook declined";
    --	else
    -+	} else {
    -+		run_hooks_opt_clear(&opt);
    - 		return NULL;
    -+	}
    - }
    - 
    - static const char *update_worktree(unsigned char *sha1, const struct worktree *worktree)
    -@@ builtin/receive-pack.c: static const char *update_worktree(unsigned char *sha1, const struct worktree *w
    - 
    - 	strvec_pushf(&env, "GIT_DIR=%s", absolute_path(git_dir));
    - 
    --	if (!find_hook(push_to_checkout_hook))
    -+	if (!hook_exists(push_to_checkout_hook))
    - 		retval = push_to_deploy(sha1, &env, work_tree);
      	else
    - 		retval = push_to_checkout(sha1, &env, work_tree);
    + 		return NULL;
19:  e3dda367ec9 = 20:  070433deba5 run-command: remove old run_hook_{le,ve}() hook API
20:  477d75bf579 = 21:  1028e0c1667 run-command: allow stdin for run_processes_parallel
21:  b7c0ee9719a ! 22:  639e59e9ed0 hook: support passing stdin to hooks
    @@ Documentation/git-hook.txt: what those are.
     
      ## builtin/hook.c ##
     @@
    + #include "strvec.h"
      
    - static const char * const builtin_hook_usage[] = {
    - 	N_("git hook <command> [...]"),
    --	N_("git hook run <hook-name> [-- <hook-args>]"),
    -+	N_("git hook run [<args>] <hook-name> [-- <hook-args>]"),
    - 	NULL
    - };
    - 
    - static const char * const builtin_hook_run_usage[] = {
    - 	N_("git hook run <hook-name> [-- <hook-args>]"),
    -+	N_("git hook run [--to-stdin=<path>] <hook-name> [-- <hook-args>]"),
    - 	NULL
    - };
    + #define BUILTIN_HOOK_RUN_USAGE \
    +-	N_("git hook run [--ignore-missing] <hook-name> [-- <hook-args>]")
    ++	N_("git hook run [--ignore-missing] [--to-stdin=<path>] <hook-name> [-- <hook-args>]")
      
    + static const char * const builtin_hook_usage[] = {
    + 	BUILTIN_HOOK_RUN_USAGE,
     @@ builtin/hook.c: static int run(int argc, const char **argv, const char *prefix)
      	struct option run_options[] = {
      		OPT_BOOL(0, "ignore-missing", &ignore_missing,
    @@ builtin/hook.c: static int run(int argc, const char **argv, const char *prefix)
     +			   N_("file to read into hooks' stdin")),
      		OPT_END(),
      	};
    - 
    + 	int ret;
     
      ## hook.c ##
     @@ hook.c: static int pick_next_hook(struct child_process *cp,
    - 	struct hook_cb_data *hook_cb = pp_cb;
    - 	struct hook *run_me = hook_cb->run_me;
    + 	if (!run_me)
    + 		return 0;
      
     -	cp->no_stdin = 1;
    -+
     +	/* reopen the file for stdin; run_command closes it. */
     +	if (hook_cb->options->path_to_stdin) {
     +		cp->no_stdin = 0;
    @@ hook.c: static int pick_next_hook(struct child_process *cp,
     
      ## hook.h ##
     @@ hook.h: struct run_hooks_opt
    + 
      	/* Path to initial working directory for subprocess */
      	const char *dir;
    - 
    ++
     +	/* Path to file which should be piped to stdin for each hook */
     +	const char *path_to_stdin;
      };
22:  4035069a98c ! 23:  7d1925cca48 am: convert 'post-rewrite' hook to hook.h
    @@ builtin/am.c: static int run_applypatch_msg_hook(struct am_state *state)
      {
     -	struct child_process cp = CHILD_PROCESS_INIT;
     -	const char *hook = find_hook("post-rewrite");
    -+	struct run_hooks_opt opt = RUN_HOOKS_OPT_INIT;
    - 	int ret;
    - 
    +-	int ret;
    +-
     -	if (!hook)
     -		return 0;
     -
    @@ builtin/am.c: static int run_applypatch_msg_hook(struct am_state *state)
     -	cp.in = xopen(am_path(state, "rewritten"), O_RDONLY);
     -	cp.stdout_to_stderr = 1;
     -	cp.trace2_hook_name = "post-rewrite";
    -+	strvec_push(&opt.args, "rebase");
    -+	opt.path_to_stdin = am_path(state, "rewritten");
    ++	struct run_hooks_opt opt = RUN_HOOKS_OPT_INIT;
      
     -	ret = run_command(&cp);
    -+	ret = run_hooks("post-rewrite", &opt);
    ++	strvec_push(&opt.args, "rebase");
    ++	opt.path_to_stdin = am_path(state, "rewritten");
      
     -	close(cp.in);
    -+	run_hooks_opt_clear(&opt);
    - 	return ret;
    +-	return ret;
    ++	return run_hooks_oneshot("post-rewrite", &opt);
      }
      
    + /**
23:  c847a19581a ! 24:  0c24221b522 run-command: add stdin callback for parallelization
    @@ builtin/submodule--helper.c: static int update_submodules(struct submodule_updat
      
     
      ## hook.c ##
    -@@ hook.c: int run_found_hooks(const char *hook_name, const char *hook_path,
    - 	run_processes_parallel_tr2(options->jobs,
    +@@ hook.c: int run_hooks(const char *hook_name, const char *hook_path,
    + 	run_processes_parallel_tr2(jobs,
      				   pick_next_hook,
      				   notify_start_failure,
     +				   NULL,
    @@ run-command.h: typedef int (*task_finished_fn)(int result,
     +			       feed_pipe_fn, task_finished_fn, void *pp_cb,
      			       const char *tr2_category, const char *tr2_label);
      
    - #endif
    + /**
     
      ## submodule.c ##
     @@ submodule.c: int fetch_populated_submodules(struct repository *r,
24:  da46c859c1c ! 25:  05d1085f7eb hook: provide stdin by string_list or callback
    @@ hook.c: static int pick_next_hook(struct child_process *cp,
      	} else {
      		cp->no_stdin = 1;
      	}
    -@@ hook.c: int run_found_hooks(const char *hook_name, const char *hook_path,
    - 	run_processes_parallel_tr2(options->jobs,
    +@@ hook.c: int run_hooks(const char *hook_name, const char *hook_path,
    + 	run_processes_parallel_tr2(jobs,
      				   pick_next_hook,
      				   notify_start_failure,
     -				   NULL,
    @@ hook.c: int run_found_hooks(const char *hook_name, const char *hook_path,
      				   notify_hook_finished,
      				   &cb_data,
      				   "hook",
    -@@ hook.c: int run_hooks(const char *hook_name, struct run_hooks_opt *options)
    +@@ hook.c: int run_hooks(const char *hook_name, const char *hook_path,
    + 
    + 	if (options->absolute_path)
    + 		strbuf_release(&abs_path);
    ++	free(my_hook.feed_pipe_cb_data);
    + 
    + 	return cb_data.rc;
    + }
    +@@ hook.c: int run_hooks_oneshot(const char *hook_name, struct run_hooks_opt *options)
      	if (!options)
    - 		BUG("a struct run_hooks_opt must be provided to run_hooks");
    + 		options = &hook_opt_scratch;
      
     +	if (options->path_to_stdin && options->feed_pipe)
     +		BUG("choose only one method to populate stdin");
     +
      	hook_path = find_hook(hook_name);
    - 
    - 	/*
    + 	if (!hook_path) {
    + 		ret = 0;
     
      ## hook.h ##
     @@ hook.h: int hook_exists(const char *hookname);
    @@ hook.h: struct run_hooks_opt
     + */
     +int pipe_from_string_list(struct strbuf *pipe, void *pp_cb, void *pp_task_cb);
     +
    - struct hook_cb_data {
    - 	/* rc reflects the cumulative failure state */
    - 	int rc;
    + /*
    +  * Callback provided to feed_pipe_fn and consume_sideband_fn.
    +  */
25:  7343be28ef4 ! 26:  4b7175af2e5 hook: convert 'post-rewrite' hook in sequencer.c to hook.h
    @@ sequencer.c: int update_head_with_reflog(const struct commit *old_head,
     +	opt.feed_pipe = pipe_from_string_list;
     +	opt.feed_pipe_ctx = &to_stdin;
     +
    -+	code = run_hooks("post-rewrite", &opt);
    ++	code = run_hooks_oneshot("post-rewrite", &opt);
     +
    -+	run_hooks_opt_clear(&opt);
     +	strbuf_release(&tmp);
     +	string_list_clear(&to_stdin, 0);
     +	return code;
    @@ sequencer.c: static int pick_commits(struct repository *r,
     +
     +			hook_opt.path_to_stdin = rebase_path_rewritten_list();
     +			strvec_push(&hook_opt.args, "rebase");
    -+			run_hooks("post-rewrite", &hook_opt);
    -+			run_hooks_opt_clear(&hook_opt);
    ++			run_hooks_oneshot("post-rewrite", &hook_opt);
      		}
      		apply_autostash(rebase_path_autostash());
      
26:  85bf13a0835 ! 27:  3f24e056410 transport: convert pre-push hook to use config
    @@ Metadata
     Author: Emily Shaffer <emilyshaffer@google.com>
     
      ## Commit message ##
    -    transport: convert pre-push hook to use config
    +    transport: convert pre-push hook to hook.h
     
    -    By using the hook.h:run_hooks API, pre-push hooks can be specified in
    -    the config as well as in the hookdir.
    +    Move the pre-push hook away from run-command.h to and over to the new
    +    hook.h library.
     
         Signed-off-by: Emily Shaffer <emilyshaffer@google.com>
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
    @@ transport.c: static void die_with_unpushed_submodules(struct string_list *needs_
     -	int ret = 0, x;
     +	int ret = 0;
     +	struct run_hooks_opt opt = RUN_HOOKS_OPT_INIT;
    -+	struct strbuf tmp = STRBUF_INIT;
      	struct ref *r;
     -	struct child_process proc = CHILD_PROCESS_INIT;
     -	struct strbuf buf;
    @@ transport.c: static void die_with_unpushed_submodules(struct string_list *needs_
     -		finish_command(&proc);
     -		return -1;
     -	}
    --
    --	sigchain_push(SIGPIPE, SIG_IGN);
    -+	struct string_list to_stdin = STRING_LIST_INIT_DUP;
    ++	struct string_list to_stdin = STRING_LIST_INIT_NODUP;
      
    +-	sigchain_push(SIGPIPE, SIG_IGN);
    +-
     -	strbuf_init(&buf, 256);
     +	strvec_push(&opt.args, transport->remote->name);
     +	strvec_push(&opt.args, transport->url);
      
      	for (r = remote_refs; r; r = r->next) {
    ++		struct strbuf buf = STRBUF_INIT;
    ++
      		if (!r->peer_ref) continue;
    -@@ transport.c: static int run_pre_push_hook(struct transport *transport,
    + 		if (r->status == REF_STATUS_REJECT_NONFASTFORWARD) continue;
    + 		if (r->status == REF_STATUS_REJECT_STALE) continue;
      		if (r->status == REF_STATUS_REJECT_REMOTE_UPDATED) continue;
      		if (r->status == REF_STATUS_UPTODATE) continue;
      
     -		strbuf_reset(&buf);
     -		strbuf_addf( &buf, "%s %s %s %s\n",
    -+		strbuf_reset(&tmp);
    -+		strbuf_addf(&tmp, "%s %s %s %s",
    ++		strbuf_addf(&buf, "%s %s %s %s",
      			 r->peer_ref->name, oid_to_hex(&r->new_oid),
      			 r->name, oid_to_hex(&r->old_oid));
     -
    @@ transport.c: static int run_pre_push_hook(struct transport *transport,
     -				ret = -1;
     -			break;
     -		}
    -+		string_list_append(&to_stdin, tmp.buf);
    ++		string_list_append(&to_stdin, strbuf_detach(&buf, NULL));
      	}
      
     -	strbuf_release(&buf);
    @@ transport.c: static int run_pre_push_hook(struct transport *transport,
     -	x = finish_command(&proc);
     -	if (!ret)
     -		ret = x;
    -+	ret = run_hooks("pre-push", &opt);
    -+	run_hooks_opt_clear(&opt);
    -+	strbuf_release(&tmp);
    ++	ret = run_hooks_oneshot("pre-push", &opt);
    ++	to_stdin.strdup_strings = 1;
     +	string_list_clear(&to_stdin, 0);
      
      	return ret;
 -:  ----------- > 28:  ecf75f33233 hook tests: test for exact "pre-push" hook input
 -:  ----------- > 29:  2c961be94b4 hook tests: use a modern style for "pre-push" tests
27:  331014bad17 ! 30:  1ce456f9d9d reference-transaction: use hook.h to run hooks
    @@ refs.c: int ref_update_reject_duplicates(struct string_list *refnames,
      				const char *state)
      {
     -	struct child_process proc = CHILD_PROCESS_INIT;
    - 	struct strbuf buf = STRBUF_INIT;
    +-	struct strbuf buf = STRBUF_INIT;
     -	const char *hook;
     +	struct run_hooks_opt opt = RUN_HOOKS_OPT_INIT;
    -+	struct string_list to_stdin = STRING_LIST_INIT_DUP;
    ++	struct string_list to_stdin = STRING_LIST_INIT_NODUP;
      	int ret = 0, i;
    -+	char o[GIT_MAX_HEXSZ + 1], n[GIT_MAX_HEXSZ + 1];
      
     -	hook = find_hook("reference-transaction");
     -	if (!hook)
    -+	if (!hook_exists("reference-transaction"))
    - 		return ret;
    - 
    +-		return ret;
    +-
     -	strvec_pushl(&proc.args, hook, state, NULL);
     -	proc.in = -1;
     -	proc.stdout_to_stderr = 1;
    @@ refs.c: int ref_update_reject_duplicates(struct string_list *refnames,
     -
     -	ret = start_command(&proc);
     -	if (ret)
    --		return ret;
    --
    ++	if (!hook_exists("reference-transaction"))
    + 		return ret;
    + 
     -	sigchain_push(SIGPIPE, SIG_IGN);
     +	strvec_push(&opt.args, state);
      
      	for (i = 0; i < transaction->nr; i++) {
      		struct ref_update *update = transaction->updates[i];
    -+		oid_to_hex_r(o, &update->old_oid);
    -+		oid_to_hex_r(n, &update->new_oid);
    ++		struct strbuf buf = STRBUF_INIT;
      
    - 		strbuf_reset(&buf);
    +-		strbuf_reset(&buf);
     -		strbuf_addf(&buf, "%s %s %s\n",
    --			    oid_to_hex(&update->old_oid),
    --			    oid_to_hex(&update->new_oid),
    --			    update->refname);
    ++		strbuf_addf(&buf, "%s %s %s",
    + 			    oid_to_hex(&update->old_oid),
    + 			    oid_to_hex(&update->new_oid),
    + 			    update->refname);
     -
     -		if (write_in_full(proc.in, buf.buf, buf.len) < 0) {
     -			if (errno != EPIPE)
     -				ret = -1;
     -			break;
     -		}
    -+		strbuf_addf(&buf, "%s %s %s", o, n, update->refname);
    -+		string_list_append(&to_stdin, buf.buf);
    ++		string_list_append(&to_stdin, strbuf_detach(&buf, NULL));
      	}
      
     -	close(proc.in);
     -	sigchain_pop(SIGPIPE);
    +-	strbuf_release(&buf);
     +	opt.feed_pipe = pipe_from_string_list;
     +	opt.feed_pipe_ctx = &to_stdin;
     +
    -+	ret = run_hooks("reference-transaction", &opt);
    -+	run_hooks_opt_clear(&opt);
    - 	strbuf_release(&buf);
    ++	ret = run_hooks_oneshot("reference-transaction", &opt);
    ++	to_stdin.strdup_strings = 1;
     +	string_list_clear(&to_stdin, 0);
      
     -	ret |= finish_command(&proc);
28:  f7f56d0a3bb ! 31:  6e5f1f5bd3a run-command: allow capturing of collated output
    @@ builtin/submodule--helper.c: static int update_submodules(struct submodule_updat
      
     
      ## hook.c ##
    -@@ hook.c: int run_found_hooks(const char *hook_name, const char *hook_path,
    +@@ hook.c: int run_hooks(const char *hook_name, const char *hook_path,
      				   pick_next_hook,
      				   notify_start_failure,
      				   options->feed_pipe,
    @@ run-command.h: int run_processes_parallel(int n,
     +			       task_finished_fn, void *pp_cb,
      			       const char *tr2_category, const char *tr2_label);
      
    - #endif
    + /**
     
      ## submodule.c ##
     @@ submodule.c: int fetch_populated_submodules(struct repository *r,
29:  7f7fcc06885 ! 32:  0b6e9c6d07a hooks: allow callers to capture output
    @@ Commit message
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
      ## hook.c ##
    -@@ hook.c: int run_found_hooks(const char *hook_name, const char *hook_path,
    +@@ hook.c: int run_hooks(const char *hook_name, const char *hook_path,
      				   pick_next_hook,
      				   notify_start_failure,
      				   options->feed_pipe,
    @@ hook.c: int run_found_hooks(const char *hook_name, const char *hook_path,
      				   notify_hook_finished,
      				   &cb_data,
      				   "hook",
    + 				   hook_name);
    + 
    ++
    + 	if (options->absolute_path)
    + 		strbuf_release(&abs_path);
    + 	free(my_hook.feed_pipe_cb_data);
     
      ## hook.h ##
     @@ hook.h: struct run_hooks_opt
30:  e74d49e5593 ! 33:  dcf63634338 receive-pack: convert 'update' hook to hook.h
    @@ builtin/receive-pack.c: static int run_receive_hook(struct command *commands,
     +static int run_update_hook(struct command *cmd)
     +{
     +	struct run_hooks_opt opt = RUN_HOOKS_OPT_INIT;
    -+	int code;
     +
     +	strvec_pushl(&opt.args,
     +		     cmd->ref_name,
    @@ builtin/receive-pack.c: static int run_receive_hook(struct command *commands,
     -	return finish_command(&proc);
     +		opt.consume_sideband = hook_output_to_sideband;
     +
    -+	code = run_hooks("update", &opt);
    -+	run_hooks_opt_clear(&opt);
    -+	return code;
    ++	return run_hooks_oneshot("update", &opt);
      }
      
      static struct command *find_command_by_refname(struct command *list,
31:  0bdc4878ac8 ! 34:  f352a485e59 post-update: use hook.h library
    @@ builtin/receive-pack.c: static const char *update(struct command *cmd, struct sh
     -			copy_to_sideband(proc.err, -1, NULL);
     -		finish_command(&proc);
     -	}
    -+	run_hooks("post-update", &opt);
    -+	run_hooks_opt_clear(&opt);
    ++	run_hooks_oneshot("post-update", &opt);
      }
      
      static void check_aliased_update_internal(struct command *cmd,
32:  db70b59b3bd ! 35:  ceef2f3e804 receive-pack: convert receive hooks to hook.h
    @@ builtin/receive-pack.c: static void hook_output_to_sideband(struct strbuf *outpu
     +{
     +	struct run_hooks_opt opt = RUN_HOOKS_OPT_INIT;
     +	struct receive_hook_feed_context ctx;
    -+	int rc;
     +	struct command *iter = commands;
     +
     +	/* if there are no valid commands, don't invoke the hook at all. */
    @@ builtin/receive-pack.c: static void hook_output_to_sideband(struct strbuf *outpu
     +	if (!iter)
     +		return 0;
     +
    -+	/* pre-receive hooks should run in series as the hook updates refs */
    -+	if (!strcmp(hook_name, "pre-receive"))
    -+		opt.jobs = 1;
    -+
     +	if (push_options) {
     +		int i;
     +		for (i = 0; i < push_options->nr; i++)
    @@ builtin/receive-pack.c: static void hook_output_to_sideband(struct strbuf *outpu
     +	opt.feed_pipe = feed_receive_hook_cb;
     +	opt.feed_pipe_ctx = &ctx;
     +
    -+	rc = run_hooks(hook_name, &opt);
    -+	run_hooks_opt_clear(&opt);
    -+	return rc;
    ++	return run_hooks_oneshot(hook_name, &opt);
     +}
     +
      static int run_update_hook(struct command *cmd)
33:  d86fedf041c ! 36:  b71d7628b40 hooks: fix a TOCTOU in "did we run a hook?" heuristic
    @@ hook.c: static int notify_hook_finished(int result,
     +	if (hook_cb->invoked_hook)
     +		*hook_cb->invoked_hook = 1;
     +
    - 	return 1;
    + 	return 0;
      }
      
    -@@ hook.c: int run_found_hooks(const char *hook_name, const char *hook_path,
    +@@ hook.c: int run_hooks(const char *hook_name, const char *hook_path,
      		.rc = 0,
      		.hook_name = hook_name,
      		.options = options,
     +		.invoked_hook = options->invoked_hook,
      	};
    - 	if (options->absolute_path) {
    - 		strbuf_add_absolute_path(&abs_path, hook_path);
    + 	int jobs = 1;
    + 
     
      ## hook.h ##
     @@ hook.h: struct run_hooks_opt
-- 
2.33.0.rc0.595.ge31e012651d


  parent reply	other threads:[~2021-08-03 19:39 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           ` Ævar Arnfjörð Bjarmason [this message]
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                 ` [PATCH v4 0/5] " Ævar Arnfjörð Bjarmason
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

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

  git send-email \
    --in-reply-to=cover-v4-00.36-00000000000-20210803T191505Z-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.
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 NNTP newsgroup(s).