git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Emily Shaffer <emilyshaffer@google.com>
To: git@vger.kernel.org
Cc: "Emily Shaffer" <emilyshaffer@google.com>,
	"Jeff King" <peff@peff.net>, "Junio C Hamano" <gitster@pobox.com>,
	"James Ramsay" <james@jramsay.com.au>,
	"Jonathan Nieder" <jrnieder@gmail.com>,
	"brian m. carlson" <sandals@crustytoothpaste.net>,
	"Ævar Arnfjörð Bjarmason" <avarab@gmail.com>,
	"Phillip Wood" <phillip.wood123@gmail.com>,
	"Josh Steadmon" <steadmon@google.com>,
	"Johannes Schindelin" <Johannes.Schindelin@gmx.de>,
	"Jonathan Tan" <jonathantanmy@google.com>
Subject: [PATCH v9 00/37] propose config-based hooks
Date: Wed, 26 May 2021 17:08:19 -0700	[thread overview]
Message-ID: <20210527000856.695702-1-emilyshaffer@google.com> (raw)
In-Reply-To: <20210311021037.3001235-1-emilyshaffer@google.com>

After much delay and $DAYJOB, here is v9.

- Addressed nits in reviews on v8
- sendemail-validate hook becomes non-parallelized; updated to use
  Ævar's updated system_or_die() function
- changed strbuf to char* in hooks_list
  - Attempted to do so in run_command's stdout callback, but this made
    length protection difficult, so stuck with strbuf there.
- test_i18ncmp -> test_cmp
- Stop doing i18n lego in run_hooks()
- Checked that run_hooks_opt_init() is always separated by a space from
  variable decl blocks
- Checked for early returns which may skip run_hooks_opt_clear(); this
  resulted in minimizing the scope of run_hooks_opt in most places
- Got rid of native-hooks.txt. It was a nice idea, but not attached to a
  large and slow series like this one.
- In traces, log the name of the hook (e.g. "pre-commit") instead of the
  name of the executable (e.g. "/home/emily/check-for-debug-strings");
  the executable name is tracelogged as part of argv anyways, and we
  want to be able to tell which hook was responsible for invoking the
  executable in question.

Thanks.
 - Emily

Emily Shaffer (37):
  doc: propose hooks managed by the config
  hook: introduce git-hook subcommand
  hook: include hookdir hook in list
  hook: teach hook.runHookDir
  hook: implement hookcmd.<name>.skip
  parse-options: parse into strvec
  hook: add 'run' subcommand
  hook: introduce hook_exists()
  hook: support passing stdin to hooks
  run-command: allow stdin for run_processes_parallel
  hook: allow parallel hook execution
  hook: allow specifying working directory for hooks
  run-command: add stdin callback for parallelization
  hook: provide stdin by string_list or callback
  run-command: allow capturing of collated output
  hooks: allow callers to capture output
  commit: use config-based hooks
  am: convert applypatch hooks to use config
  merge: use config-based hooks for post-merge hook
  gc: use hook library for pre-auto-gc hook
  rebase: teach pre-rebase to use hook.h
  read-cache: convert post-index-change hook to use config
  receive-pack: convert push-to-checkout hook to hook.h
  git-p4: use 'git hook' to run hooks
  hooks: convert 'post-checkout' hook to hook library
  hook: convert 'post-rewrite' hook to config
  transport: convert pre-push hook to use config
  reference-transaction: look for hooks in config
  receive-pack: convert 'update' hook to hook.h
  proc-receive: acquire hook list from hook.h
  post-update: use hook.h library
  receive-pack: convert receive hooks to hook.h
  bugreport: use hook_exists instead of find_hook
  git-send-email: use 'git hook run' for 'sendemail-validate'
  run-command: stop thinking about hooks
  doc: clarify fsmonitor-watchman specification
  docs: link githooks and git-hook manpages

 .gitignore                                    |   1 +
 Documentation/Makefile                        |   1 +
 Documentation/config/hook.txt                 |  27 +
 Documentation/git-hook.txt                    | 162 ++++++
 Documentation/githooks.txt                    |  77 ++-
 Documentation/technical/api-parse-options.txt |   7 +
 .../technical/config-based-hooks.txt          | 369 +++++++++++++
 Makefile                                      |   2 +
 builtin.h                                     |   1 +
 builtin/am.c                                  |  39 +-
 builtin/bugreport.c                           |   4 +-
 builtin/checkout.c                            |  19 +-
 builtin/clone.c                               |   8 +-
 builtin/commit.c                              |  11 +-
 builtin/fetch.c                               |   1 +
 builtin/gc.c                                  |   9 +-
 builtin/hook.c                                | 190 +++++++
 builtin/merge.c                               |  15 +-
 builtin/rebase.c                              |  10 +-
 builtin/receive-pack.c                        | 326 ++++++------
 builtin/submodule--helper.c                   |   2 +-
 builtin/worktree.c                            |  32 +-
 command-list.txt                              |   1 +
 commit.c                                      |  22 +-
 commit.h                                      |   3 +-
 git-p4.py                                     |  67 +--
 git-send-email.perl                           |  26 +-
 git.c                                         |   1 +
 hook.c                                        | 483 ++++++++++++++++++
 hook.h                                        | 139 +++++
 parse-options-cb.c                            |  16 +
 parse-options.h                               |   4 +
 read-cache.c                                  |  13 +-
 refs.c                                        |  43 +-
 reset.c                                       |  17 +-
 run-command.c                                 | 156 +++---
 run-command.h                                 |  55 +-
 sequencer.c                                   |  92 ++--
 submodule.c                                   |   1 +
 t/helper/test-parse-options.c                 |   6 +
 t/helper/test-run-command.c                   |  46 +-
 t/t0040-parse-options.sh                      |  27 +
 t/t0061-run-command.sh                        |  37 ++
 t/t1360-config-based-hooks.sh                 | 329 ++++++++++++
 t/t1416-ref-transaction-hooks.sh              |  12 +-
 t/t5411/test-0015-too-many-hooks-error.sh     |  47 ++
 ...3-pre-commit-and-pre-merge-commit-hooks.sh |  17 +-
 t/t9001-send-email.sh                         |  13 +-
 transport.c                                   |  58 +--
 49 files changed, 2505 insertions(+), 539 deletions(-)
 create mode 100644 Documentation/config/hook.txt
 create mode 100644 Documentation/git-hook.txt
 create mode 100644 Documentation/technical/config-based-hooks.txt
 create mode 100644 builtin/hook.c
 create mode 100644 hook.c
 create mode 100644 hook.h
 create mode 100755 t/t1360-config-based-hooks.sh
 create mode 100644 t/t5411/test-0015-too-many-hooks-error.sh



 1:  85b99369f1 !  1:  d2b7ee8317 doc: propose hooks managed by the config
    @@ Commit message
     
         Signed-off-by: Emily Shaffer <emilyshaffer@google.com>
     
    +
    + ## Notes ##
    +    Since v6, checked for inconsistencies with implementation and added lots of
    +    caveats about whether 'git hook add' and 'git hook edit' will ever materialize.
    +
    +    Hopefully this reflects reality now; please review accordingly.
    +
    +    Since v6, checked for inconsistencies with implementation and added lots of
    +    caveats about whether 'git hook add' and 'git hook edit' will ever materialize.
    +
    +    Hopefully this reflects reality now; please review accordingly.
    +
    +    Since v4, addressed comments from Jonathan Tan about wording. However, I have
    +    not addressed AEvar's comments or done a full re-review of this document.
    +    I wanted to get the rest of the series out for initial review first.
    +
    +     - Emily
    +
    +    Since v4, addressed comments from Jonathan Tan about wording.
    +
      ## Documentation/Makefile ##
     @@ Documentation/Makefile: SP_ARTICLES += $(API_DOCS)
      TECH_DOCS += MyFirstContribution
 2:  1d19f1477c <  -:  ---------- hook: scaffolding for git-hook subcommand
 3:  c125c63880 !  2:  112a809f02 hook: add list command
    @@ Metadata
     Author: Emily Shaffer <emilyshaffer@google.com>
     
      ## Commit message ##
    -    hook: add list command
    +    hook: introduce git-hook subcommand
     
    -    Teach 'git hook list <hookname>', which checks the known configs in
    +    Add a new subcommand, git-hook, which will be used to ease config-based
    +    hook management. This command will handle parsing configs to compose a
    +    list of hooks to run for a given event, as well as adding or modifying
    +    hook configs in an interactive fashion.
    +
    +    Start with 'git hook list <hookname>', which checks the known configs in
         order to create an ordered list of hooks to run on a given hook event.
     
         Multiple commands can be specified for a given hook by providing
    @@ Commit message
     
         Signed-off-by: Emily Shaffer <emilyshaffer@google.com>
     
    +
    + ## Notes ##
    +    Since v4, mainly changed to RUN_SETUP_GENTLY so that 'git hook list' can
    +    be executed outside of a repo.
    +
    + ## .gitignore ##
    +@@
    + /git-grep
    + /git-hash-object
    + /git-help
    ++/git-hook
    + /git-http-backend
    + /git-http-fetch
    + /git-http-push
    +
      ## Documentation/config/hook.txt (new) ##
     @@
     +hook.<command>.command::
    @@ Documentation/config/hook.txt (new)
     +	as a command. This can be an executable on your device or a oneliner for
     +	your shell. See linkgit:git-hook[1].
     
    - ## Documentation/git-hook.txt ##
    -@@ Documentation/git-hook.txt: git-hook - Manage configured hooks
    - SYNOPSIS
    - --------
    - [verse]
    --'git hook'
    + ## Documentation/git-hook.txt (new) ##
    +@@
    ++git-hook(1)
    ++===========
    ++
    ++NAME
    ++----
    ++git-hook - Manage configured hooks
    ++
    ++SYNOPSIS
    ++--------
    ++[verse]
     +'git hook' list <hook-name>
    - 
    - DESCRIPTION
    - -----------
    --A placeholder command. Later, you will be able to list, add, and modify hooks
    --with this command.
    ++
    ++DESCRIPTION
    ++-----------
     +You can list configured hooks with this command. Later, you will be able to run,
     +add, and modify hooks with this command.
     +
    @@ Documentation/git-hook.txt: git-hook - Manage configured hooks
     +CONFIGURATION
     +-------------
     +include::config/hook.txt[]
    - 
    - GIT
    - ---
    ++
    ++GIT
    ++---
    ++Part of the linkgit:git[1] suite
     
      ## Makefile ##
     @@ Makefile: LIB_OBJS += hash-lookup.o
    @@ Makefile: LIB_OBJS += hash-lookup.o
      LIB_OBJS += ident.o
      LIB_OBJS += json-writer.o
      LIB_OBJS += kwset.o
    +@@ Makefile: BUILTIN_OBJS += builtin/get-tar-commit-id.o
    + BUILTIN_OBJS += builtin/grep.o
    + BUILTIN_OBJS += builtin/hash-object.o
    + BUILTIN_OBJS += builtin/help.o
    ++BUILTIN_OBJS += builtin/hook.o
    + BUILTIN_OBJS += builtin/index-pack.o
    + BUILTIN_OBJS += builtin/init-db.o
    + BUILTIN_OBJS += builtin/interpret-trailers.o
     
    - ## builtin/hook.c ##
    + ## builtin.h ##
    +@@ builtin.h: int cmd_get_tar_commit_id(int argc, const char **argv, const char *prefix);
    + int cmd_grep(int argc, const char **argv, const char *prefix);
    + int cmd_hash_object(int argc, const char **argv, const char *prefix);
    + int cmd_help(int argc, const char **argv, const char *prefix);
    ++int cmd_hook(int argc, const char **argv, const char *prefix);
    + int cmd_index_pack(int argc, const char **argv, const char *prefix);
    + int cmd_init_db(int argc, const char **argv, const char *prefix);
    + int cmd_interpret_trailers(int argc, const char **argv, const char *prefix);
    +
    + ## builtin/hook.c (new) ##
     @@
    - #include "cache.h"
    --
    - #include "builtin.h"
    ++#include "cache.h"
    ++#include "builtin.h"
     +#include "config.h"
     +#include "hook.h"
    - #include "parse-options.h"
    ++#include "parse-options.h"
     +#include "strbuf.h"
    - 
    - static const char * const builtin_hook_usage[] = {
    --	N_("git hook"),
    ++
    ++static const char * const builtin_hook_usage[] = {
     +	N_("git hook list <hookname>"),
    - 	NULL
    - };
    - 
    --int cmd_hook(int argc, const char **argv, const char *prefix)
    ++	NULL
    ++};
    ++
     +static int list(int argc, const char **argv, const char *prefix)
    - {
    --	struct option builtin_hook_options[] = {
    ++{
     +	struct list_head *head, *pos;
    -+	struct strbuf hookname = STRBUF_INIT;
    ++	const char *hookname = NULL;
     +
     +	struct option list_options[] = {
    - 		OPT_END(),
    - 	};
    - 
    --	argc = parse_options(argc, argv, prefix, builtin_hook_options,
    ++		OPT_END(),
    ++	};
    ++
     +	argc = parse_options(argc, argv, prefix, list_options,
    - 			     builtin_hook_usage, 0);
    - 
    ++			     builtin_hook_usage, 0);
    ++
     +	if (argc < 1) {
     +		usage_msg_opt(_("You must specify a hook event name to list."),
     +			      builtin_hook_usage, list_options);
     +	}
     +
    -+	strbuf_addstr(&hookname, argv[0]);
    ++	hookname = argv[0];
     +
    -+	head = hook_list(&hookname);
    ++	head = hook_list(hookname);
     +
     +	if (list_empty(head)) {
     +		printf(_("no commands configured for hook '%s'\n"),
    -+		       hookname.buf);
    -+		strbuf_release(&hookname);
    ++		       hookname);
     +		return 0;
     +	}
     +
    @@ builtin/hook.c
     +	}
     +
     +	clear_hook_list(head);
    -+	strbuf_release(&hookname);
     +
    - 	return 0;
    - }
    ++	return 0;
    ++}
     +
     +int cmd_hook(int argc, const char **argv, const char *prefix)
     +{
    @@ builtin/hook.c
     +	usage_with_options(builtin_hook_usage, builtin_hook_options);
     +}
     
    + ## command-list.txt ##
    +@@ command-list.txt: git-grep                                mainporcelain           info
    + git-gui                                 mainporcelain
    + git-hash-object                         plumbingmanipulators
    + git-help                                ancillaryinterrogators          complete
    ++git-hook                                mainporcelain
    + git-http-backend                        synchingrepositories
    + git-http-fetch                          synchelpers
    + git-http-push                           synchelpers
    +
    + ## git.c ##
    +@@ git.c: static struct cmd_struct commands[] = {
    + 	{ "grep", cmd_grep, RUN_SETUP_GENTLY },
    + 	{ "hash-object", cmd_hash_object },
    + 	{ "help", cmd_help },
    ++	{ "hook", cmd_hook, RUN_SETUP_GENTLY },
    + 	{ "index-pack", cmd_index_pack, RUN_SETUP_GENTLY | NO_PARSEOPT },
    + 	{ "init", cmd_init_db },
    + 	{ "init-db", cmd_init_db },
    +
      ## hook.c (new) ##
     @@
     +#include "cache.h"
    @@ hook.c (new)
     +	return 0;
     +}
     +
    -+struct list_head* hook_list(const struct strbuf* hookname)
    ++struct list_head* hook_list(const char* hookname)
     +{
     +	struct strbuf hook_key = STRBUF_INIT;
     +	struct list_head *hook_head = xmalloc(sizeof(struct list_head));
    @@ hook.c (new)
     +	if (!hookname)
     +		return NULL;
     +
    -+	strbuf_addf(&hook_key, "hook.%s.command", hookname->buf);
    ++	strbuf_addf(&hook_key, "hook.%s.command", hookname);
     +
     +	git_config(hook_config_lookup, &cb_data);
     +
    @@ hook.h (new)
     + * Provides a linked list of 'struct hook' detailing commands which should run
     + * in response to the 'hookname' event, in execution order.
     + */
    -+struct list_head* hook_list(const struct strbuf *hookname);
    ++struct list_head* hook_list(const char *hookname);
     +
     +/* Free memory associated with a 'struct hook' */
     +void free_hook(struct hook *ptr);
     +/* Empties the list at 'head', calling 'free_hook()' on each entry */
     +void clear_hook_list(struct list_head *head);
     
    - ## t/t1360-config-based-hooks.sh ##
    -@@ t/t1360-config-based-hooks.sh: test_description='config-managed multihooks, including git-hook command'
    - 
    - . ./test-lib.sh
    - 
    --test_expect_success 'git hook command does not crash' '
    --	git hook
    + ## t/t1360-config-based-hooks.sh (new) ##
    +@@
    ++#!/bin/bash
    ++
    ++test_description='config-managed multihooks, including git-hook command'
    ++
    ++. ./test-lib.sh
    ++
     +ROOT=
     +if test_have_prereq MINGW
     +then
    @@ t/t1360-config-based-hooks.sh: test_description='config-managed multihooks, incl
     +
     +	git hook list pre-commit >actual &&
     +	test_cmp expected actual
    - '
    - 
    - test_done
    ++'
    ++
    ++test_done
 4:  0b8cd46ff9 !  3:  3114306368 hook: include hookdir hook in list
    @@ builtin/hook.c: static int list(int argc, const char **argv, const char *prefix)
      	list_for_each(pos, head) {
      		struct hook *item = list_entry(pos, struct hook, list);
     -		if (item)
    +-			printf("%s: %s\n",
    +-			       config_scope_name(item->origin),
     +		item = list_entry(pos, struct hook, list);
     +		if (item) {
    -+			/* Don't translate 'hookdir' - it matches the config */
    - 			printf("%s: %s\n",
    --			       config_scope_name(item->origin),
    ++			/*
    ++			 * TRANSLATORS: "<config scope>: <path>". Both fields
    ++			 * should be left untranslated; config scope matches the
    ++			 * output of 'git config --show-scope'. Marked for
    ++			 * translation to provide better RTL support later.
    ++			 */
    ++			printf(_("%s: %s\n"),
     +			       (item->from_hookdir
     +				? "hookdir"
     +				: config_scope_name(item->origin)),
    @@ hook.c: static void append_or_move_hook(struct list_head *head, const char *comm
      	}
      
      	/* re-set the scope so we show where an override was specified */
    -@@ hook.c: struct list_head* hook_list(const struct strbuf* hookname)
    +@@ hook.c: struct list_head* hook_list(const char* hookname)
      
      	git_config(hook_config_lookup, &cb_data);
      
     +	if (have_git_dir()) {
    -+		const char *legacy_hook_path = find_hook(hookname->buf);
    ++		const char *legacy_hook_path = find_hook(hookname);
     +
     +		/* Unconditionally add legacy hook, but annotate it. */
     +		if (legacy_hook_path) {
 5:  05c503fbe1 !  4:  681013c32a hook: teach hook.runHookDir
    @@ Commit message
         list'. Later on, though, we will pay attention to this enum when running
         the hooks.
     
    +
    + ## Notes ##
    +    Since v7, tidied up the behavior of the HOOK_UNKNOWN flag and added a test to
    +    enforce it - now it matches the design doc much better.
    +
    +    Also, thanks Jonathan Tan for pointing out that the commit message made no sense
    +    and was targeted for a different change. Rewrote the commit message now.
    +
    +    Plus, added HOOK_ERROR flag per Junio and Jonathan Nieder.
    +
    +    Newly split into its own commit since v4, and taking place much sooner.
    +
    +    An unfortunate side effect of adding this support *before* the
    +    hook.runHookDir support is that the labels on the list are not clear -
    +    because we aren't yet flagging which hooks are from the hookdir versus
    +    the config. I suppose we could move the addition of that field to the
    +    struct hook up to this patch, but it didn't make a lot of sense to me to
    +    do it just for cosmetic purposes.
    +
    +    Since v7, tidied up the behavior of the HOOK_UNKNOWN flag and added a test to
    +    enforce it - now it matches the design doc much better.
    +
    +    Also, thanks Jonathan Tan for pointing out that the commit message made no sense
    +    and was targeted for a different change. Rewrote the commit message now.
    +
    +    Newly split into its own commit since v4, and taking place much sooner.
    +
    +    An unfortunate side effect of adding this support *before* the
    +    hook.runHookDir support is that the labels on the list are not clear -
    +    because we aren't yet flagging which hooks are from the hookdir versus
    +    the config. I suppose we could move the addition of that field to the
    +    struct hook up to this patch, but it didn't make a lot of sense to me to
    +    do it just for cosmetic purposes.
    +
      ## Documentation/config/hook.txt ##
     @@ Documentation/config/hook.txt: hookcmd.<name>.command::
      	A command to execute during a hook for which <name> has been specified
    @@ builtin/hook.c: static const char * const builtin_hook_usage[] = {
      static int list(int argc, const char **argv, const char *prefix)
      {
      	struct list_head *head, *pos;
    - 	struct strbuf hookname = STRBUF_INIT;
    + 	const char *hookname = NULL;
     +	struct strbuf hookdir_annotation = STRBUF_INIT;
      
      	struct option list_options[] = {
      		OPT_END(),
     @@ builtin/hook.c: static int list(int argc, const char **argv, const char *prefix)
    - 		return 0;
    - 	}
    - 
    -+	switch (should_run_hookdir) {
    -+		case HOOKDIR_NO:
    -+			strbuf_addstr(&hookdir_annotation, _(" (will not run)"));
    -+			break;
    -+		case HOOKDIR_ERROR:
    -+			strbuf_addstr(&hookdir_annotation, _(" (will error and not run)"));
    -+			break;
    -+		case HOOKDIR_INTERACTIVE:
    -+			strbuf_addstr(&hookdir_annotation, _(" (will prompt)"));
    -+			break;
    -+		case HOOKDIR_WARN:
    -+			strbuf_addstr(&hookdir_annotation, _(" (will warn but run)"));
    -+			break;
    -+		case HOOKDIR_YES:
    -+		/*
    -+		 * The default behavior should agree with
    -+		 * hook.c:configured_hookdir_opt(). HOOKDIR_UNKNOWN should just
    -+		 * do the default behavior.
    -+		 */
    -+		case HOOKDIR_UNKNOWN:
    -+		default:
    -+			break;
    -+	}
    -+
    - 	list_for_each(pos, head) {
      		struct hook *item = list_entry(pos, struct hook, list);
      		item = list_entry(pos, struct hook, list);
      		if (item) {
    - 			/* Don't translate 'hookdir' - it matches the config */
    --			printf("%s: %s\n",
    -+			printf("%s: %s%s\n",
    - 			       (item->from_hookdir
    - 				? "hookdir"
    - 				: config_scope_name(item->origin)),
    +-			/*
    +-			 * TRANSLATORS: "<config scope>: <path>". Both fields
    +-			 * should be left untranslated; config scope matches the
    +-			 * output of 'git config --show-scope'. Marked for
    +-			 * translation to provide better RTL support later.
    +-			 */
    +-			printf(_("%s: %s\n"),
    +-			       (item->from_hookdir
    +-				? "hookdir"
    +-				: config_scope_name(item->origin)),
     -			       item->command.buf);
    -+			       item->command.buf,
    -+			       (item->from_hookdir
    -+				? hookdir_annotation.buf
    -+				: ""));
    ++			if (item->from_hookdir) {
    ++				/*
    ++				 * TRANSLATORS: do not translate 'hookdir' as
    ++				 * it matches the config setting.
    ++				 */
    ++				switch (should_run_hookdir) {
    ++				case HOOKDIR_NO:
    ++					printf(_("hookdir: %s (will not run)\n"),
    ++					       item->command.buf);
    ++					break;
    ++				case HOOKDIR_ERROR:
    ++					printf(_("hookdir: %s (will error and not run)\n"),
    ++					       item->command.buf);
    ++					break;
    ++				case HOOKDIR_INTERACTIVE:
    ++					printf(_("hookdir: %s (will prompt)\n"),
    ++					       item->command.buf);
    ++					break;
    ++				case HOOKDIR_WARN:
    ++					printf(_("hookdir: %s (will warn but run)\n"),
    ++					       item->command.buf);
    ++					break;
    ++				case HOOKDIR_YES:
    ++				/*
    ++				 * The default behavior should agree with
    ++				 * hook.c:configured_hookdir_opt(). HOOKDIR_UNKNOWN should just
    ++				 * do the default behavior.
    ++				 */
    ++				case HOOKDIR_UNKNOWN:
    ++				default:
    ++					printf(_("hookdir: %s\n"),
    ++						 item->command.buf);
    ++					break;
    ++				}
    ++			} else {
    ++				/*
    ++				 * TRANSLATORS: "<config scope>: <path>". Both fields
    ++				 * should be left untranslated; config scope matches the
    ++				 * output of 'git config --show-scope'. Marked for
    ++				 * translation to provide better RTL support later.
    ++				 */
    ++				printf(_("%s: %s\n"),
    ++					config_scope_name(item->origin),
    ++					item->command.buf);
    ++			}
      		}
      	}
      
      	clear_hook_list(head);
     +	strbuf_release(&hookdir_annotation);
    - 	strbuf_release(&hookname);
      
      	return 0;
    -@@ builtin/hook.c: static int list(int argc, const char **argv, const char *prefix)
    + }
      
      int cmd_hook(int argc, const char **argv, const char *prefix)
      {
    @@ builtin/hook.c: static int list(int argc, const char **argv, const char *prefix)
     +		else if (!strcmp(run_hookdir, "interactive"))
     +			should_run_hookdir = HOOKDIR_INTERACTIVE;
     +		else
    ++			/*
    ++			 * TRANSLATORS: leave "yes/warn/interactive/no"
    ++			 * untranslated; the strings are compared literally.
    ++			 */
     +			die(_("'%s' is not a valid option for --run-hookdir "
     +			      "(yes, warn, interactive, no)"), run_hookdir);
     +	else
    @@ hook.c: static int hook_config_lookup(const char *key, const char *value, void *
     +	return HOOKDIR_UNKNOWN;
     +}
     +
    - struct list_head* hook_list(const struct strbuf* hookname)
    + struct list_head* hook_list(const char* hookname)
      {
      	struct strbuf hook_key = STRBUF_INIT;
     
      ## hook.h ##
     @@ hook.h: struct hook {
       */
    - struct list_head* hook_list(const struct strbuf *hookname);
    + struct list_head* hook_list(const char *hookname);
      
     +enum hookdir_opt
     +{
    @@ hook.h: struct hook {
     + * command line arguments.
     + */
     +enum hookdir_opt configured_hookdir_opt(void);
    ++
    ++/*
    ++ * Provides the hookdir_opt specified in the config without consulting any
    ++ * command line arguments.
    ++ */
    ++enum hookdir_opt configured_hookdir_opt(void);
     +
      /* Free memory associated with a 'struct hook' */
      void free_hook(struct hook *ptr);
    @@ t/t1360-config-based-hooks.sh: test_expect_success 'git hook list shows hooks fr
     +
     +	git hook list pre-commit >actual &&
     +	# the hookdir annotation is translated
    -+	test_i18ncmp expected actual
    ++	test_cmp expected actual
     +'
     +
     +test_expect_success 'hook.runHookDir = error is respected by list' '
    @@ t/t1360-config-based-hooks.sh: test_expect_success 'git hook list shows hooks fr
     +
     +	git hook list pre-commit >actual &&
     +	# the hookdir annotation is translated
    -+	test_i18ncmp expected actual
    ++	test_cmp expected actual
     +'
     +
     +test_expect_success 'hook.runHookDir = warn is respected by list' '
    @@ t/t1360-config-based-hooks.sh: test_expect_success 'git hook list shows hooks fr
     +
     +	git hook list pre-commit >actual &&
     +	# the hookdir annotation is translated
    -+	test_i18ncmp expected actual
    ++	test_cmp expected actual
     +'
     +
     +
    @@ t/t1360-config-based-hooks.sh: test_expect_success 'git hook list shows hooks fr
     +
     +	git hook list pre-commit >actual &&
     +	# the hookdir annotation is translated
    -+	test_i18ncmp expected actual
    ++	test_cmp expected actual
     +'
     +
     +test_expect_success 'hook.runHookDir is tolerant to unknown values' '
    @@ t/t1360-config-based-hooks.sh: test_expect_success 'git hook list shows hooks fr
     +
     +	git hook list pre-commit >actual &&
     +	# the hookdir annotation is translated
    -+	test_i18ncmp expected actual
    ++	test_cmp expected actual
     +'
     +
      test_done
 6:  e86025853a !  5:  0a4b9f27b3 hook: implement hookcmd.<name>.skip
    @@ hook.c: static int hook_config_lookup(const char *key, const char *value, void *
     
      ## t/t1360-config-based-hooks.sh ##
     @@ t/t1360-config-based-hooks.sh: test_expect_success 'hook.runHookDir = warn is respected by list' '
    - 	test_i18ncmp expected actual
    + 	test_cmp expected actual
      '
      
     +test_expect_success 'git hook list removes skipped hookcmd' '
    @@ t/t1360-config-based-hooks.sh: test_expect_success 'hook.runHookDir = warn is re
     +	EOF
     +
     +	git hook list pre-commit >actual &&
    -+	test_i18ncmp expected actual
    ++	test_cmp expected actual
     +'
     +
     +test_expect_success 'git hook list ignores skip referring to unused hookcmd' '
    @@ t/t1360-config-based-hooks.sh: test_expect_success 'hook.runHookDir = warn is re
     +	EOF
     +
     +	git hook list pre-commit >actual &&
    -+	test_i18ncmp expected actual
    ++	test_cmp expected actual
     +'
     +
     +test_expect_success 'git hook list removes skipped inlined hook' '
 7:  6e10593d75 !  6:  2ad4f44d08 parse-options: parse into strvec
    @@ Commit message
     
         Signed-off-by: Emily Shaffer <emilyshaffer@google.com>
     
    +
    + ## Notes ##
    +    Since v7, updated the reference doc to make the intended usage for OPT_STRVEC
    +    more clear.
    +
    +    Since v4, fixed one or two more places where I missed the argv_array->strvec
    +    rename.
    +
      ## Documentation/technical/api-parse-options.txt ##
     @@ Documentation/technical/api-parse-options.txt: There are some macros to easily define options:
      	The string argument is stored as an element in `string_list`.
    @@ parse-options.h: int parse_opt_commits(const struct option *, const char *, int)
      int parse_opt_noop_cb(const struct option *, const char *, int);
      enum parse_opt_result parse_opt_unknown_cb(struct parse_opt_ctx_t *ctx,
      					   const struct option *,
    +
    + ## t/helper/test-parse-options.c ##
    +@@
    + #include "cache.h"
    + #include "parse-options.h"
    + #include "string-list.h"
    ++#include "strvec.h"
    + #include "trace2.h"
    + 
    + static int boolean = 0;
    +@@ t/helper/test-parse-options.c: static char *string = NULL;
    + static char *file = NULL;
    + static int ambiguous;
    + static struct string_list list = STRING_LIST_INIT_NODUP;
    ++static struct strvec vector = STRVEC_INIT;
    + 
    + static struct {
    + 	int called;
    +@@ t/helper/test-parse-options.c: int cmd__parse_options(int argc, const char **argv)
    + 		OPT_STRING('o', NULL, &string, "str", "get another string"),
    + 		OPT_NOOP_NOARG(0, "obsolete"),
    + 		OPT_STRING_LIST(0, "list", &list, "str", "add str to list"),
    ++		OPT_STRVEC(0, "vector", &vector, "str", "add str to strvec"),
    + 		OPT_GROUP("Magic arguments"),
    + 		OPT_ARGUMENT("quux", NULL, "means --quux"),
    + 		OPT_NUMBER_CALLBACK(&integer, "set integer to NUM",
    +@@ t/helper/test-parse-options.c: int cmd__parse_options(int argc, const char **argv)
    + 	for (i = 0; i < list.nr; i++)
    + 		show(&expect, &ret, "list: %s", list.items[i].string);
    + 
    ++	for (i = 0; i < vector.nr; i++)
    ++		show(&expect, &ret, "vector: %s", vector.v[i]);
    ++
    + 	for (i = 0; i < argc; i++)
    + 		show(&expect, &ret, "arg %02d: %s", i, argv[i]);
    + 
    +
    + ## t/t0040-parse-options.sh ##
    +@@ t/t0040-parse-options.sh: String options
    +     --st <st>             get another string (pervert ordering)
    +     -o <str>              get another string
    +     --list <str>          add str to list
    ++    --vector <str>        add str to strvec
    + 
    + Magic arguments
    +     --quux                means --quux
    +@@ t/t0040-parse-options.sh: test_expect_success '--no-list resets list' '
    + 	test_cmp expect output
    + '
    + 
    ++cat >expect <<\EOF
    ++boolean: 0
    ++integer: 0
    ++magnitude: 0
    ++timestamp: 0
    ++string: (not set)
    ++abbrev: 7
    ++verbose: -1
    ++quiet: 0
    ++dry run: no
    ++file: (not set)
    ++vector: foo
    ++vector: bar
    ++vector: baz
    ++EOF
    ++test_expect_success '--vector keeps list of strings' '
    ++	test-tool parse-options --vector foo --vector=bar --vector=baz >output &&
    ++	test_cmp expect output
    ++'
    ++
    ++test_expect_success '--no-vector resets list' '
    ++	test-tool parse-options --vector=other --vector=irrelevant --vector=options \
    ++		--no-vector --vector=foo --vector=bar --vector=baz >output &&
    ++	test_cmp expect output
    ++'
    ++
    + test_expect_success 'multiple quiet levels' '
    + 	test-tool parse-options --expect="quiet: 3" -q -q -q
    + '
 8:  0dc9284057 !  7:  27dd8e3edf hook: add 'run' subcommand
    @@ Commit message
     
         Signed-off-by: Emily Shaffer <emilyshaffer@google.com>
     
    +
    + ## Notes ##
    +    Since v7, added support for "error" hook.runHookDir setting.
    +
    +    Since v4, updated the docs, and did less local application of single
    +    quotes. In order for hookdir hooks to run successfully with a space in
    +    the path, though, they must not be run with 'sh -c'. So we can treat the
    +    hookdir hooks specially, and warn users via doc about special
    +    considerations for configured hooks with spaces in their path.
    +
      ## Documentation/git-hook.txt ##
     @@ Documentation/git-hook.txt: SYNOPSIS
      --------
    @@ hook.c
      
      void free_hook(struct hook *ptr)
      {
    +-	if (ptr) {
    ++	if (ptr)
    + 		strbuf_release(&ptr->command);
    +-		free(ptr);
    +-	}
    ++	free(ptr);
    + }
    + 
    + static struct hook * find_hook_by_command(struct list_head *head, const char *command)
     @@ hook.c: enum hookdir_opt configured_hookdir_opt(void)
      	return HOOKDIR_UNKNOWN;
      }
    @@ hook.c: enum hookdir_opt configured_hookdir_opt(void)
     +
     +	switch (cfg)
     +	{
    -+		case HOOKDIR_ERROR:
    -+			fprintf(stderr, _("Skipping legacy hook at '%s'\n"),
    -+				path);
    -+			/* FALLTHROUGH */
    -+		case HOOKDIR_NO:
    -+			return 0;
    -+		case HOOKDIR_WARN:
    -+			fprintf(stderr, _("Running legacy hook at '%s'\n"),
    -+				path);
    -+			return 1;
    -+		case HOOKDIR_INTERACTIVE:
    -+			do {
    -+				/*
    -+				 * TRANSLATORS: Make sure to include [Y] and [n]
    -+				 * in your translation. Only English input is
    -+				 * accepted. Default option is "yes".
    -+				 */
    -+				fprintf(stderr, _("Run '%s'? [Yn] "), path);
    -+				git_read_line_interactively(&prompt);
    -+				strbuf_tolower(&prompt);
    -+				if (starts_with(prompt.buf, "n")) {
    -+					strbuf_release(&prompt);
    -+					return 0;
    -+				} else if (starts_with(prompt.buf, "y")) {
    -+					strbuf_release(&prompt);
    -+					return 1;
    -+				}
    -+				/* otherwise, we didn't understand the input */
    -+			} while (prompt.len); /* an empty reply means "Yes" */
    -+			strbuf_release(&prompt);
    -+			return 1;
    -+		/*
    -+		 * HOOKDIR_UNKNOWN should match the default behavior, but let's
    -+		 * give a heads up to the user.
    -+		 */
    -+		case HOOKDIR_UNKNOWN:
    -+			fprintf(stderr,
    -+				_("Unrecognized value for 'hook.runHookDir'. "
    -+				  "Is there a typo? "));
    -+			/* FALLTHROUGH */
    -+		case HOOKDIR_YES:
    -+		default:
    -+			return 1;
    ++	case HOOKDIR_ERROR:
    ++		fprintf(stderr, _("Skipping legacy hook at '%s'\n"),
    ++			path);
    ++		/* FALLTHROUGH */
    ++	case HOOKDIR_NO:
    ++		return 0;
    ++	case HOOKDIR_WARN:
    ++		fprintf(stderr, _("Running legacy hook at '%s'\n"),
    ++			path);
    ++		return 1;
    ++	case HOOKDIR_INTERACTIVE:
    ++		do {
    ++			/*
    ++			 * TRANSLATORS: Make sure to include [Y] and [n]
    ++			 * in your translation. Only English input is
    ++			 * accepted. Default option is "yes".
    ++			 */
    ++			fprintf(stderr, _("Run '%s'? [Y/n] "), path);
    ++			git_read_line_interactively(&prompt);
    ++			/*
    ++			 * In case of prompt = '' - that is, user hit enter,
    ++			 * saying "yes I want the default" - strncasecmp will
    ++			 * return 0 regardless. So list the default first.
    ++			 *
    ++			 * Case insensitively, accept "y", "ye", or "yes" as
    ++			 * "yes"; accept "n" or "no" as "no".
    ++			 */
    ++			if (!strncasecmp(prompt.buf, "yes", prompt.len)) {
    ++				strbuf_release(&prompt);
    ++				return 1;
    ++			} else if (!strncasecmp(prompt.buf, "no", prompt.len)) {
    ++				strbuf_release(&prompt);
    ++				return 0;
    ++			}
    ++			/* otherwise, we didn't understand the input */
    ++		} while (prompt.len); /* an empty reply means default (yes) */
    ++		return 1;
    ++	/*
    ++	 * HOOKDIR_UNKNOWN should match the default behavior, but let's
    ++	 * give a heads up to the user.
    ++	 */
    ++	case HOOKDIR_UNKNOWN:
    ++		fprintf(stderr,
    ++			_("Unrecognized value for 'hook.runHookDir'. "
    ++			  "Is there a typo? "));
    ++		/* FALLTHROUGH */
    ++	case HOOKDIR_YES:
    ++	default:
    ++		return 1;
     +	}
     +}
     +
    - struct list_head* hook_list(const struct strbuf* hookname)
    + struct list_head* hook_list(const char* hookname)
      {
      	struct strbuf hook_key = STRBUF_INIT;
    -@@ hook.c: struct list_head* hook_list(const struct strbuf* hookname)
    +@@ hook.c: struct list_head* hook_list(const char* hookname)
      	strbuf_release(&hook_key);
      	return hook_head;
      }
    @@ hook.c: struct list_head* hook_list(const struct strbuf* hookname)
     +	strvec_clear(&o->args);
     +}
     +
    -+static void prepare_hook_cp(struct hook *hook, struct run_hooks_opt *options,
    ++static void prepare_hook_cp(const char *hookname, struct hook *hook,
    ++			    struct run_hooks_opt *options,
     +			    struct child_process *cp)
     +{
     +	if (!hook)
    @@ hook.c: struct list_head* hook_list(const struct strbuf* hookname)
     +	cp->no_stdin = 1;
     +	cp->env = options->env.v;
     +	cp->stdout_to_stderr = 1;
    -+	cp->trace2_hook_name = hook->command.buf;
    ++	cp->trace2_hook_name = hookname;
     +
     +	/*
     +	 * Commands from the config could be oneliners, but we know
    @@ hook.c: struct list_head* hook_list(const struct strbuf* hookname)
     +
     +int run_hooks(const char *hookname, struct run_hooks_opt *options)
     +{
    -+	struct strbuf hookname_str = STRBUF_INIT;
     +	struct list_head *to_run, *pos = NULL, *tmp = NULL;
     +	int rc = 0;
     +
     +	if (!options)
     +		BUG("a struct run_hooks_opt must be provided to run_hooks");
     +
    -+	strbuf_addstr(&hookname_str, hookname);
    -+
    -+	to_run = hook_list(&hookname_str);
    ++	to_run = hook_list(hookname);
     +
     +	list_for_each_safe(pos, tmp, to_run) {
     +		struct child_process hook_proc = CHILD_PROCESS_INIT;
    @@ hook.c: struct list_head* hook_list(const struct strbuf* hookname)
     +		    !should_include_hookdir(hook->command.buf, options->run_hookdir))
     +			continue;
     +
    -+		prepare_hook_cp(hook, options, &hook_proc);
    ++		prepare_hook_cp(hookname, hook, options, &hook_proc);
     +
     +		rc |= run_command(&hook_proc);
     +	}
    @@ hook.h: enum hookdir_opt
     +void run_hooks_opt_init(struct run_hooks_opt *o);
     +void run_hooks_opt_clear(struct run_hooks_opt *o);
     +
    -+/*
    + /*
    +- * Provides the hookdir_opt specified in the config without consulting any
    +- * command line arguments.
     + * Runs all hooks associated to the 'hookname' event in order. Each hook will be
     + * passed 'env' and 'args'.
    -+ */
    +  */
    +-enum hookdir_opt configured_hookdir_opt(void);
     +int run_hooks(const char *hookname, struct run_hooks_opt *options);
    -+
    + 
      /* Free memory associated with a 'struct hook' */
      void free_hook(struct hook *ptr);
    - /* Empties the list at 'head', calling 'free_hook()' on each entry */
     
      ## t/t1360-config-based-hooks.sh ##
     @@ t/t1360-config-based-hooks.sh: test_expect_success 'hook.runHookDir = no is respected by list' '
      
      	git hook list pre-commit >actual &&
      	# the hookdir annotation is translated
    --	test_i18ncmp expected actual
    -+	test_i18ncmp expected actual &&
    +-	test_cmp expected actual
    ++	test_cmp expected actual &&
     +
     +	git hook run pre-commit 2>actual &&
     +	test_must_be_empty actual
    @@ t/t1360-config-based-hooks.sh: test_expect_success 'hook.runHookDir = error is r
      
      	git hook list pre-commit >actual &&
      	# the hookdir annotation is translated
    -+	test_i18ncmp expected actual &&
    ++	test_cmp expected actual &&
     +
     +	cat >expected <<-EOF &&
     +	Skipping legacy hook at '\''$(pwd)/.git/hooks/pre-commit'\''
     +	EOF
     +
     +	git hook run pre-commit 2>actual &&
    - 	test_i18ncmp expected actual
    + 	test_cmp expected actual
      '
      
     @@ t/t1360-config-based-hooks.sh: test_expect_success 'hook.runHookDir = warn is respected by list' '
      
      	git hook list pre-commit >actual &&
      	# the hookdir annotation is translated
    -+	test_i18ncmp expected actual &&
    ++	test_cmp expected actual &&
     +
     +	cat >expected <<-EOF &&
     +	Running legacy hook at '\''$(pwd)/.git/hooks/pre-commit'\''
    @@ t/t1360-config-based-hooks.sh: test_expect_success 'hook.runHookDir = warn is re
     +	EOF
     +
     +	git hook run pre-commit 2>actual &&
    - 	test_i18ncmp expected actual
    + 	test_cmp expected actual
      '
      
     @@ t/t1360-config-based-hooks.sh: test_expect_success 'git hook list removes skipped inlined hook' '
    @@ t/t1360-config-based-hooks.sh: test_expect_success 'hook.runHookDir = interactiv
      
      	git hook list pre-commit >actual &&
      	# the hookdir annotation is translated
    --	test_i18ncmp expected actual
    -+	test_i18ncmp expected actual &&
    ++	test_cmp expected actual &&
     +
     +	test_write_lines n | git hook run pre-commit 2>actual &&
     +	! grep "Legacy Hook" actual &&
    @@ t/t1360-config-based-hooks.sh: test_expect_success 'hook.runHookDir = interactiv
     +	test_cmp expected actual
     +'
     +
    ++test_expect_success 'git hook run can pass args and env vars' '
    ++	write_script sample-hook.sh <<-\EOF &&
    ++	echo $1
    ++	echo $2
    ++	echo $TEST_ENV_1
    ++	echo $TEST_ENV_2
    ++	EOF
    ++
    ++	test_config hook.pre-commit.command "\"$(pwd)/sample-hook.sh\"" &&
    ++
    ++	cat >expected <<-EOF &&
    ++	arg1
    ++	arg2
    ++	env1
    ++	env2
    ++	EOF
    ++
    ++	git hook run --arg arg1 \
    ++		--env TEST_ENV_1=env1 \
    ++		-a arg2 \
    ++		-e TEST_ENV_2=env2 \
    ++		pre-commit 2>actual &&
    ++
    + 	test_cmp expected actual
    + '
    + 
     +test_expect_success 'hookdir hook included in git hook run' '
     +	setup_hookdir &&
     +
    @@ t/t1360-config-based-hooks.sh: test_expect_success 'hook.runHookDir = interactiv
     +	setup_hooks &&
     +
     +	nongit test_must_fail git hook run pre-commit
    - '
    - 
    ++'
    ++
      test_expect_success 'hook.runHookDir is tolerant to unknown values' '
    + 	setup_hookdir &&
    + 
 9:  92c67ed9da !  8:  46975c11c8 hook: introduce hook_exists()
    @@ hook.c: void run_hooks_opt_init(struct run_hooks_opt *o)
      	strvec_clear(&o->env);
     
      ## hook.h ##
    -@@ hook.h: struct list_head* hook_list(const struct strbuf *hookname);
    +@@ hook.h: struct list_head* hook_list(const char *hookname);
      
      enum hookdir_opt
      {
10:  9b3bb0b655 !  9:  e11f9e28a3 hook: support passing stdin to hooks
    @@ hook.c: void run_hooks_opt_init(struct run_hooks_opt *o)
      	o->run_hookdir = configured_hookdir_opt();
      }
      
    -@@ hook.c: static void prepare_hook_cp(struct hook *hook, struct run_hooks_opt *options,
    +@@ hook.c: static void prepare_hook_cp(const char *hookname, struct hook *hook,
      	if (!hook)
      		return;
      
    @@ hook.c: static void prepare_hook_cp(struct hook *hook, struct run_hooks_opt *opt
     +
      	cp->env = options->env.v;
      	cp->stdout_to_stderr = 1;
    - 	cp->trace2_hook_name = hook->command.buf;
    + 	cp->trace2_hook_name = hookname;
     
      ## hook.h ##
     @@ hook.h: struct run_hooks_opt
    @@ hook.h: int hook_exists(const char *hookname, enum hookdir_opt should_run_hookdi
     
      ## t/t1360-config-based-hooks.sh ##
     @@ t/t1360-config-based-hooks.sh: test_expect_success 'hook.runHookDir is tolerant to unknown values' '
    - 	test_i18ncmp expected actual
    + 	test_cmp expected actual
      '
      
     +test_expect_success 'stdin to multiple hooks' '
11:  9933985e78 = 10:  3ceb4156fd run-command: allow stdin for run_processes_parallel
12:  43caafe656 ! 11:  93a47f5242 hook: allow parallel hook execution
    @@ Commit message
     
         Signed-off-by: Emily Shaffer <emilyshaffer@google.com>
     
    +
    + ## Notes ##
    +    Per AEvar's request - parallel hook execution on day zero.
    +
    +    In most ways run_processes_parallel() worked great for me - but it didn't
    +    have great support for hooks where we pipe to and from. I had to add this
    +    support later in the series.
    +
    +    Since I modified an existing and in-use library I'd appreciate a keen look on
    +    these patches.
    +
    +     - Emily
    +
      ## Documentation/config/hook.txt ##
     @@ Documentation/config/hook.txt: hook.runHookDir::
      	Controls how hooks contained in your hookdir are executed. Can be any of
    @@ hook.c: enum hookdir_opt configured_hookdir_opt(void)
      static int should_include_hookdir(const char *path, enum hookdir_opt cfg)
      {
      	struct strbuf prompt = STRBUF_INIT;
    -@@ hook.c: struct list_head* hook_list(const struct strbuf* hookname)
    +@@ hook.c: struct list_head* hook_list(const char* hookname)
      	return hook_head;
      }
      
    @@ hook.c: void run_hooks_opt_clear(struct run_hooks_opt *o)
      	strvec_clear(&o->args);
      }
      
    --static void prepare_hook_cp(struct hook *hook, struct run_hooks_opt *options,
    +-static void prepare_hook_cp(const char *hookname, struct hook *hook,
    +-			    struct run_hooks_opt *options,
     -			    struct child_process *cp)
     +static int pick_next_hook(struct child_process *cp,
     +			  struct strbuf *out,
    @@ hook.c: void run_hooks_opt_clear(struct run_hooks_opt *o)
     -	cp->env = options->env.v;
     +	cp->env = hook_cb->options->env.v;
      	cp->stdout_to_stderr = 1;
    - 	cp->trace2_hook_name = hook->command.buf;
    +-	cp->trace2_hook_name = hookname;
    ++	cp->trace2_hook_name = hook_cb->hookname;
      
    -@@ hook.c: static void prepare_hook_cp(struct hook *hook, struct run_hooks_opt *options,
    + 	/*
    + 	 * Commands from the config could be oneliners, but we know
    +@@ hook.c: static void prepare_hook_cp(const char *hookname, struct hook *hook,
      	 * add passed-in argv, without expanding - let the user get back
      	 * exactly what they put in
      	 */
    @@ hook.c: static void prepare_hook_cp(struct hook *hook, struct run_hooks_opt *opt
      
      int run_hooks(const char *hookname, struct run_hooks_opt *options)
      {
    - 	struct strbuf hookname_str = STRBUF_INIT;
      	struct list_head *to_run, *pos = NULL, *tmp = NULL;
     -	int rc = 0;
    -+	struct hook_cb_data cb_data = { 0, NULL, NULL, options };
    ++	struct hook_cb_data cb_data = { 0, hookname, NULL, NULL, options };
      
      	if (!options)
      		BUG("a struct run_hooks_opt must be provided to run_hooks");
     @@ hook.c: int run_hooks(const char *hookname, struct run_hooks_opt *options)
    - 	to_run = hook_list(&hookname_str);
    + 	to_run = hook_list(hookname);
      
      	list_for_each_safe(pos, tmp, to_run) {
     -		struct child_process hook_proc = CHILD_PROCESS_INIT;
    @@ hook.c: int run_hooks(const char *hookname, struct run_hooks_opt *options)
     +	if (list_empty(to_run))
     +		return 0;
      
    --		prepare_hook_cp(hook, options, &hook_proc);
    +-		prepare_hook_cp(hookname, hook, options, &hook_proc);
     +	cb_data.head = to_run;
     +	cb_data.run_me = list_entry(to_run->next, struct hook, list);
      
    @@ hook.h: struct run_hooks_opt
     + */
     +struct hook_cb_data {
     +	int rc;
    ++	const char *hookname;
     +	struct list_head *head;
     +	struct hook *run_me;
     +	struct run_hooks_opt *options;
13:  2e189a7566 ! 12:  7f8c886d3f hook: allow specifying working directory for hooks
    @@ Commit message
     
         Signed-off-by: Emily Shaffer <emilyshaffer@google.com>
     
    +
    + ## Notes ##
    +    Needed later for "post-checkout" conversion.
    +
      ## hook.c ##
     @@ hook.c: void run_hooks_opt_init_sync(struct run_hooks_opt *o)
      	o->path_to_stdin = NULL;
    @@ hook.c: void run_hooks_opt_init_sync(struct run_hooks_opt *o)
     @@ hook.c: static int pick_next_hook(struct child_process *cp,
      	cp->env = hook_cb->options->env.v;
      	cp->stdout_to_stderr = 1;
    - 	cp->trace2_hook_name = hook->command.buf;
    + 	cp->trace2_hook_name = hook_cb->hookname;
     +	cp->dir = hook_cb->options->dir;
      
      	/*
14:  07899ad346 = 13:  8930baa9db run-command: add stdin callback for parallelization
15:  d3f18e433f ! 14:  d0f362591a hook: provide stdin by string_list or callback
    @@ Commit message
         Signed-off-by: Emily Shaffer <emilyshaffer@google.com>
     
      ## hook.c ##
    -@@ hook.c: void free_hook(struct hook *ptr)
    +@@
    + 
    + void free_hook(struct hook *ptr)
      {
    - 	if (ptr) {
    +-	if (ptr)
    ++	if (ptr) {
      		strbuf_release(&ptr->command);
     +		free(ptr->feed_pipe_cb_data);
    - 		free(ptr);
    - 	}
    ++	}
    + 	free(ptr);
      }
    + 
     @@ hook.c: static void append_or_move_hook(struct list_head *head, const char *command)
      		strbuf_init(&to_add->command, 0);
      		strbuf_addstr(&to_add->command, command);
    @@ hook.c: int run_hooks(const char *hookname, struct run_hooks_opt *options)
     +	if (options->path_to_stdin && options->feed_pipe)
     +		BUG("choose only one method to populate stdin");
     +
    - 	strbuf_addstr(&hookname_str, hookname);
    + 	to_run = hook_list(hookname);
      
    - 	to_run = hook_list(&hookname_str);
    + 	list_for_each_safe(pos, tmp, to_run) {
     @@ hook.c: int run_hooks(const char *hookname, struct run_hooks_opt *options)
      	run_processes_parallel_tr2(options->jobs,
      				   pick_next_hook,
16:  417c3f054e ! 15:  83bbb405a5 run-command: allow capturing of collated output
    @@ Commit message
     
         Signed-off-by: Emily Shaffer <emilyshaffer@google.com>
     
    +
    + ## Notes ##
    +    Originally when writing this patch I attempted to use a pipe in memory -
    +    but managing its lifetime was actually pretty tricky, and I found I could
    +    achieve the same thing with less code by doing it this way. Critique welcome,
    +    including "no, you really need to do it with a pipe".
    +
      ## builtin/fetch.c ##
     @@ builtin/fetch.c: static int fetch_multiple(struct string_list *list, int max_children)
      		result = run_processes_parallel_tr2(max_children,
17:  c0f3471bd1 ! 16:  73ed5de54c hooks: allow callers to capture output
    @@ Commit message
     
         Signed-off-by: Emily Shaffer <emilyshaffer@google.com>
     
    +
    + ## Notes ##
    +    You can see this in practice in the conversions for some of the push hooks,
    +    like 'receive-pack'.
    +
      ## hook.c ##
     @@ hook.c: void run_hooks_opt_init_sync(struct run_hooks_opt *o)
      	o->dir = NULL;
18:  13446e4273 = 17:  900c4d8963 commit: use config-based hooks
19:  9380c43180 ! 18:  a562120e22 am: convert applypatch hooks to use config
    @@ builtin/am.c: static void am_destroy(const struct am_state *state)
      {
      	int ret;
     +	struct run_hooks_opt opt;
    ++
     +	run_hooks_opt_init_sync(&opt);
      
      	assert(state->msg);
    @@ builtin/am.c: static void do_commit(const struct am_state *state)
      	const char *reflog_msg, *author, *committer = NULL;
      	struct strbuf sb = STRBUF_INIT;
     +	struct run_hooks_opt hook_opt;
    ++
     +	run_hooks_opt_init_async(&hook_opt);
      
     -	if (run_hook_le(NULL, "pre-applypatch", NULL))
    -+	if (run_hooks("pre-applypatch", &hook_opt))
    ++	if (run_hooks("pre-applypatch", &hook_opt)) {
    ++		run_hooks_opt_clear(&hook_opt);
      		exit(1);
    ++	}
    ++
    ++	run_hooks_opt_clear(&hook_opt);
      
      	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_opt_init_async(&hook_opt);
     +	run_hooks("post-applypatch", &hook_opt);
      
     +	run_hooks_opt_clear(&hook_opt);
20:  316a605606 ! 19:  e841ed4384 merge: use config-based hooks for post-merge hook
    @@ builtin/merge.c: static void finish(struct commit *head_commit,
      	struct strbuf reflog_message = STRBUF_INIT;
     +	struct run_hooks_opt opt;
      	const struct object_id *head = &head_commit->object.oid;
    -+	run_hooks_opt_init_async(&opt);
      
      	if (!msg)
    - 		strbuf_addstr(&reflog_message, getenv("GIT_REFLOG_ACTION"));
     @@ 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);
    ++	run_hooks_opt_init_async(&opt);
     +	strvec_push(&opt.args, squash ? "1" : "0");
     +	run_hooks("post-merge", &opt);
     +	run_hooks_opt_clear(&opt);
21:  a5132f14b3 ! 20:  7e99398f7d gc: use hook library for pre-auto-gc hook
    @@ 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_async(&hook_opt);
    ++
      	/*
      	 * Setting gc.auto to 0 or negative can disable the
      	 * automatic gc.
    @@ builtin/gc.c: static int need_to_gc(void)
      		return 0;
      
     -	if (run_hook_le(NULL, "pre-auto-gc", NULL))
    -+	if (run_hooks("pre-auto-gc", &hook_opt))
    ++	run_hooks_opt_init_async(&hook_opt);
    ++	if (run_hooks("pre-auto-gc", &hook_opt)) {
    ++		run_hooks_opt_clear(&hook_opt);
      		return 0;
    ++	}
    ++	run_hooks_opt_clear(&hook_opt);
      	return 1;
      }
    + 
22:  01f1331cc9 ! 21:  5423217ef2 rebase: teach pre-rebase to use hook.h
    @@ builtin/rebase.c: int cmd_rebase(int argc, const char **argv, const char *prefix
      	struct option builtin_rebase_options[] = {
      		OPT_STRING(0, "onto", &options.onto_name,
      			   N_("revision"),
    -@@ builtin/rebase.c: int cmd_rebase(int argc, const char **argv, const char *prefix)
    - 	};
    - 	int i;
    - 
    -+	run_hooks_opt_init_async(&hook_opt);
    -+
    - 	if (argc == 2 && !strcmp(argv[1], "-h"))
    - 		usage_with_options(builtin_rebase_usage,
    - 				   builtin_rebase_options);
     @@ builtin/rebase.c: int cmd_rebase(int argc, const char **argv, const char *prefix)
      	}
      
      	/* If a hook exists, give it a chance to interrupt*/
    ++	run_hooks_opt_init_async(&hook_opt);
     +	strvec_pushl(&hook_opt.args, options.upstream_arg, argc ? argv[0] : NULL, NULL);
      	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("pre-rebase", &hook_opt)) {
    ++		run_hooks_opt_clear(&hook_opt);
      		die(_("The pre-rebase hook refused to rebase."));
    ++	}
    ++	run_hooks_opt_clear(&hook_opt);
      
      	if (options.flags & REBASE_DIFFSTAT) {
    -@@ builtin/rebase.c: int cmd_rebase(int argc, const char **argv, const char *prefix)
    - 	ret = !!run_specific_rebase(&options, action);
    - 
    - cleanup:
    -+	run_hooks_opt_clear(&hook_opt);
    - 	strbuf_release(&buf);
    - 	strbuf_release(&revisions);
    - 	free(options.head_name);
    + 		struct diff_options opts;
23:  85a7721adc ! 22:  1c0c5ad129 read-cache: convert post-index-change hook to use config
    @@ Documentation/githooks.txt: and "0" meaning they were not.
     
      ## read-cache.c ##
     @@
    - #include "fsmonitor.h"
      #include "thread-utils.h"
      #include "progress.h"
    + #include "sparse-index.h"
     +#include "hook.h"
    ++>>>>>>> 9524a9d29d (read-cache: convert post-index-change hook to use config)
      
      /* Mask for the name length in ce_flags in the on-disk index */
      
     @@ read-cache.c: static int do_write_locked_index(struct index_state *istate, struct lock_file *l
    - 				 unsigned flags)
      {
      	int ret;
    + 	int was_full = !istate->sparse_index;
     +	struct run_hooks_opt hook_opt;
    -+	run_hooks_opt_init_async(&hook_opt);
      
    - 	/*
    - 	 * TODO trace2: replace "the_repository" with the actual repo instance
    + 	ret = convert_to_sparse(istate);
    + 
     @@ read-cache.c: static int do_write_locked_index(struct index_state *istate, struct lock_file *l
      	else
      		ret = close_lock_file_gently(lock);
    @@ read-cache.c: static int do_write_locked_index(struct index_state *istate, struc
     -	run_hook_le(NULL, "post-index-change",
     -			istate->updated_workdir ? "1" : "0",
     -			istate->updated_skipworktree ? "1" : "0", NULL);
    ++	run_hooks_opt_init_async(&hook_opt);
     +	strvec_pushl(&hook_opt.args,
     +		     istate->updated_workdir ? "1" : "0",
     +		     istate->updated_skipworktree ? "1" : "0",
24:  21ec3e1a9d ! 23:  1193e856e6 receive-pack: convert push-to-checkout hook to hook.h
    @@ builtin/receive-pack.c: static const char *push_to_checkout(unsigned char *hash,
      				    const char *work_tree)
      {
     +	struct run_hooks_opt opt;
    ++
     +	run_hooks_opt_init_sync(&opt);
     +
      	strvec_pushf(env, "GIT_WORK_TREE=%s", absolute_path(work_tree));
25:  e0405e96ad ! 24:  1817b6851b git-p4: use 'git hook' to run hooks
    @@ Commit message
     
         Signed-off-by: Emily Shaffer <emilyshaffer@google.com>
     
    +
    + ## Notes ##
    +    Maybe there is a better way to do this - I had a hard time getting this to run
    +    locally, and Python is not my forte, so if anybody has a better approach I'd
    +    love to just take that patch instead :)
    +
    +    Since v6, removed the developer debug print statements.... :X
    +
    +    Maybe there is a better way to do this - I had a hard time getting this to run
    +    locally, and Python is not my forte, so if anybody has a better approach I'd
    +    love to just take that patch instead :)
    +
      ## git-p4.py ##
     @@ git-p4.py: def decode_path(path):
      
26:  c52578e078 ! 25:  b3a354e4a8 hooks: convert 'post-checkout' hook to hook library
    @@ builtin/checkout.c: struct branch_info {
      			      int changed)
      {
     -	return run_hook_le(NULL, "post-checkout",
    --			   oid_to_hex(old_commit ? &old_commit->object.oid : &null_oid),
    --			   oid_to_hex(new_commit ? &new_commit->object.oid : &null_oid),
    +-			   oid_to_hex(old_commit ? &old_commit->object.oid : null_oid()),
    +-			   oid_to_hex(new_commit ? &new_commit->object.oid : null_oid()),
     -			   changed ? "1" : "0", NULL);
     +	struct run_hooks_opt opt;
     +	int rc;
    @@ builtin/checkout.c: struct branch_info {
      	   a commit exists. */
     -
     +	strvec_pushl(&opt.args,
    -+		     oid_to_hex(old_commit ? &old_commit->object.oid : &null_oid),
    -+		     oid_to_hex(new_commit ? &new_commit->object.oid : &null_oid),
    ++		     oid_to_hex(old_commit ? &old_commit->object.oid : null_oid()),
    ++		     oid_to_hex(new_commit ? &new_commit->object.oid : null_oid()),
     +		     changed ? "1" : "0",
     +		     NULL);
     +	rc = run_hooks("post-checkout", &opt);
    @@ builtin/clone.c: static int checkout(int submodule_progress)
      	struct tree_desc t;
      	int err = 0;
     +	struct run_hooks_opt hook_opt;
    -+	run_hooks_opt_init_sync(&hook_opt);
      
      	if (option_no_checkout)
      		return 0;
    @@ builtin/clone.c: static int checkout(int submodule_progress)
      	if (write_locked_index(&the_index, &lock_file, COMMIT_LOCK))
      		die(_("unable to write new index file"));
      
    --	err |= run_hook_le(NULL, "post-checkout", oid_to_hex(&null_oid),
    +-	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);
    ++	run_hooks_opt_init_sync(&hook_opt);
    ++	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);
      
    @@ builtin/worktree.c: static int add_worktree(const char *path, const char *refnam
     -			cp.argv = NULL;
     -			cp.trace2_hook_name = "post-checkout";
     -			strvec_pushl(&cp.args, absolute_path(hook),
    --				     oid_to_hex(&null_oid),
    +-				     oid_to_hex(null_oid()),
     -				     oid_to_hex(&commit->object.oid),
     -				     "1", NULL);
     -			ret = run_command(&cp);
     -		}
     +		struct run_hooks_opt opt;
    ++
     +		run_hooks_opt_init_sync(&opt);
     +
     +		strvec_pushl(&opt.env, "GIT_DIR", "GIT_WORK_TREE", NULL);
     +		strvec_pushl(&opt.args,
    -+			     oid_to_hex(&null_oid),
    ++			     oid_to_hex(null_oid()),
     +			     oid_to_hex(&commit->object.oid),
     +			     "1",
     +			     NULL);
    @@ builtin/worktree.c: static int add_worktree(const char *path, const char *refnam
      
      	strvec_clear(&child_env);
     
    + ## read-cache.c ##
    +@@
    + #include "progress.h"
    + #include "sparse-index.h"
    + #include "hook.h"
    +->>>>>>> 9524a9d29d (read-cache: convert post-index-change hook to use config)
    + 
    + /* Mask for the name length in ce_flags in the on-disk index */
    + 
    +
      ## reset.c ##
     @@
      #include "tree-walk.h"
    @@ reset.c: int reset_head(struct repository *r, struct object_id *oid, const char
      	}
     -	if (run_hook)
     -		run_hook_le(NULL, "post-checkout",
    --			    oid_to_hex(orig ? orig : &null_oid),
    +-			    oid_to_hex(orig ? orig : null_oid()),
     -			    oid_to_hex(oid), "1", NULL);
     +	if (run_hook) {
     +		struct run_hooks_opt opt;
    ++
     +		run_hooks_opt_init_sync(&opt);
     +		strvec_pushl(&opt.args,
    -+			     oid_to_hex(orig ? orig : &null_oid),
    ++			     oid_to_hex(orig ? orig : null_oid()),
     +			     oid_to_hex(oid),
     +			     "1",
     +			     NULL);
27:  316cb6f584 ! 26:  692352f9aa hook: convert 'post-rewrite' hook to config
    @@ builtin/am.c: static int run_applypatch_msg_hook(struct am_state *state)
     -	const char *hook = find_hook("post-rewrite");
     +	struct run_hooks_opt opt;
      	int ret;
    -+	run_hooks_opt_init_async(&opt);
      
     -	if (!hook)
     -		return 0;
    --
    ++	run_hooks_opt_init_async(&opt);
    + 
     -	strvec_push(&cp.args, hook);
     -	strvec_push(&cp.args, "rebase");
    --
    --	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");
      
    --	ret = run_command(&cp);
    +-	cp.in = xopen(am_path(state, "rewritten"), O_RDONLY);
    +-	cp.stdout_to_stderr = 1;
    +-	cp.trace2_hook_name = "post-rewrite";
     +	ret = run_hooks("post-rewrite", &opt);
      
    +-	ret = run_command(&cp);
    +-
     -	close(cp.in);
     +	run_hooks_opt_clear(&opt);
      	return ret;
    @@ sequencer.c: int update_head_with_reflog(const struct commit *old_head,
     +	struct string_list to_stdin = STRING_LIST_INIT_DUP;
      	int code;
     -	struct strbuf sb = STRBUF_INIT;
    -+	run_hooks_opt_init_async(&opt);
      
     -	argv[0] = find_hook("post-rewrite");
     -	if (!argv[0])
     -		return 0;
    -+	strvec_push(&opt.args, "amend");
    ++	run_hooks_opt_init_async(&opt);
      
     -	argv[1] = "amend";
     -	argv[2] = NULL;
    @@ sequencer.c: int update_head_with_reflog(const struct commit *old_head,
     -	strbuf_release(&sb);
     -	sigchain_pop(SIGPIPE);
     -	return finish_command(&proc);
    ++	strvec_push(&opt.args, "amend");
    ++
     +	strbuf_addf(&tmp,
     +		    "%s %s",
     +		    oid_to_hex(oldoid),
    @@ sequencer.c: static int pick_commits(struct repository *r,
     -			strvec_push(&child.args, "--for-rewrite=rebase");
     +			struct child_process notes_cp = CHILD_PROCESS_INIT;
     +			struct run_hooks_opt hook_opt;
    ++
     +			run_hooks_opt_init_async(&hook_opt);
     +
     +			notes_cp.in = open(rebase_path_rewritten_list(), O_RDONLY);
28:  0ab776068d = 27:  964011dfdd transport: convert pre-push hook to use config
29:  601dada804 ! 28:  c04822add9 reference-transaction: look for hooks in config
    @@ t/t1416-ref-transaction-hooks.sh: test_expect_success 'interleaving hook calls s
      	EOF
      
      	git push ./target-repo.git PRE POST &&
    +
    + ## transport.c ##
    +@@ transport.c: static int run_pre_push_hook(struct transport *transport,
    + 	struct strbuf tmp = STRBUF_INIT;
    + 	struct ref *r;
    + 	struct string_list to_stdin = STRING_LIST_INIT_DUP;
    ++
    + 	run_hooks_opt_init_async(&opt);
    + 
    + 	strvec_push(&opt.args, transport->remote->name);
30:  d60f2b146e ! 29:  ddc6f56bec receive-pack: convert 'update' hook to hook.h
    @@ builtin/receive-pack.c: static int run_receive_hook(struct command *commands,
      	return status;
      }
      
    --static int run_update_hook(struct command *cmd)
     +static void hook_output_to_sideband(struct strbuf *output, void *cb_data)
    - {
    --	const char *argv[5];
    --	struct child_process proc = CHILD_PROCESS_INIT;
    --	int code;
    ++{
     +	int keepalive_active = 0;
    - 
    --	argv[0] = find_hook("update");
    --	if (!argv[0])
    --		return 0;
    ++
     +	if (keepalive_in_sec <= 0)
     +		use_keepalive = KEEPALIVE_NEVER;
     +	if (use_keepalive == KEEPALIVE_ALWAYS)
     +		keepalive_active = 1;
    - 
    --	argv[1] = cmd->ref_name;
    --	argv[2] = oid_to_hex(&cmd->old_oid);
    --	argv[3] = oid_to_hex(&cmd->new_oid);
    --	argv[4] = NULL;
    ++
     +	/* send a keepalive if there is no data to write */
     +	if (keepalive_active && !output->len) {
     +		static const char buf[] = "0005\1";
     +		write_or_die(1, buf, sizeof(buf) - 1);
     +		return;
     +	}
    - 
    --	proc.no_stdin = 1;
    --	proc.stdout_to_stderr = 1;
    --	proc.err = use_sideband ? -1 : 0;
    --	proc.argv = argv;
    --	proc.trace2_hook_name = "update";
    ++
     +	if (use_keepalive == KEEPALIVE_AFTER_NUL && !keepalive_active) {
     +		const char *first_null = memchr(output->buf, '\0', output->len);
     +		if (first_null) {
    @@ builtin/receive-pack.c: static int run_receive_hook(struct command *commands,
     +	send_sideband(1, 2, output->buf, output->len, use_sideband);
     +}
     +
    -+static int run_update_hook(struct command *cmd)
    -+{
    + static int run_update_hook(struct command *cmd)
    + {
    +-	const char *argv[5];
    +-	struct child_process proc = CHILD_PROCESS_INIT;
     +	struct run_hooks_opt opt;
    -+	int code;
    + 	int code;
    + 
    +-	argv[0] = find_hook("update");
    +-	if (!argv[0])
    +-		return 0;
     +	run_hooks_opt_init_async(&opt);
    -+
    + 
    +-	argv[1] = cmd->ref_name;
    +-	argv[2] = oid_to_hex(&cmd->old_oid);
    +-	argv[3] = oid_to_hex(&cmd->new_oid);
    +-	argv[4] = NULL;
     +	strvec_pushl(&opt.args,
     +		     cmd->ref_name,
     +		     oid_to_hex(&cmd->old_oid),
     +		     oid_to_hex(&cmd->new_oid),
     +		     NULL);
      
    +-	proc.no_stdin = 1;
    +-	proc.stdout_to_stderr = 1;
    +-	proc.err = use_sideband ? -1 : 0;
    +-	proc.argv = argv;
    +-	proc.trace2_hook_name = "update";
    +-
     -	code = start_command(&proc);
     -	if (code)
     -		return code;
31:  1e6898670b ! 30:  e1e810869f proc-receive: acquire hook list from hook.h
    @@ builtin/receive-pack.c: static int run_proc_receive_hook(struct command *command
      
     -	argv[0] = find_hook("proc-receive");
     -	if (!argv[0]) {
    -+	struct strbuf hookname = STRBUF_INIT;
     +	struct hook *proc_receive = NULL;
     +	struct list_head *pos, *hooks;
     +
    -+	strbuf_addstr(&hookname, "proc-receive");
    -+	hooks = hook_list(&hookname);
    ++	hooks = hook_list("proc-receive");
     +
     +	list_for_each(pos, hooks) {
     +		if (proc_receive) {
32:  012e3a7a79 ! 31:  b8be5a2288 post-update: use hook.h library
    @@ builtin/receive-pack.c: static const char *update(struct command *cmd, struct sh
      	struct command *cmd;
     -	struct child_process proc = CHILD_PROCESS_INIT;
     -	const char *hook;
    --
    ++	struct run_hooks_opt opt;
    + 
     -	hook = find_hook("post-update");
     -	if (!hook)
     -		return;
    -+	struct run_hooks_opt opt;
     +	run_hooks_opt_init_async(&opt);
      
      	for (cmd = commands; cmd; cmd = cmd->next) {
33:  2740bcda6d = 32:  1cc1384eae receive-pack: convert receive hooks to hook.h
34:  f201f3af5f = 33:  1bb9a3810c bugreport: use hook_exists instead of find_hook
35:  0956a94cc7 ! 34:  3db7bf3b0d git-send-email: use 'git hook run' for 'sendemail-validate'
    @@ git-send-email.perl: sub unique_email_list {
      	my ($fn, $xfer_encoding) = @_;
      
     -	if ($repo) {
    --		my $validate_hook = catfile(catdir($repo->repo_path(), 'hooks'),
    +-		my $validate_hook = catfile($repo->hooks_path(),
     -					    'sendemail-validate');
     -		my $hook_error;
     -		if (-x $validate_hook) {
    @@ git-send-email.perl: sub unique_email_list {
     -			chdir($repo->wc_path() or $repo->repo_path())
     -				or die("chdir: $!");
     -			local $ENV{"GIT_DIR"} = $repo->repo_path();
    --			$hook_error = "rejected by sendemail-validate hook"
    --				if system($validate_hook, $target);
    +-			$hook_error = system_or_msg([$validate_hook, $target]);
     -			chdir($cwd_save) or die("chdir: $!");
     -		}
    --		return $hook_error if $hook_error;
    +-		if ($hook_error) {
    +-			die sprintf(__("fatal: %s: rejected by sendemail-validate hook\n" .
    +-				       "%s\n" .
    +-				       "warning: no patches were sent\n"), $fn, $hook_error);
    +-		}
     -	}
     +	my $target = abs_path($fn);
    -+	return "rejected by sendemail-validate hook"
    -+		if system(("git", "hook", "run", "sendemail-validate", "-a",
    -+				$target));
    ++
    ++	system_or_die(["git", "hook", "run", "sendemail-validate", "-j1", "-a", $target],
    ++		sprintf(__("fatal: %s: rejected by sendemail-validate hook\n" .
    ++			   "warning: no patches were sent\n"),
    ++		        $fn));
      
      	# Any long lines will be automatically fixed if we use a suitable transfer
      	# encoding.
     
      ## t/t9001-send-email.sh ##
    +@@ t/t9001-send-email.sh: test_expect_success $PREREQ "--validate respects relative core.hooksPath path" '
    + 	test_path_is_file my-hooks.ran &&
    + 	cat >expect <<-EOF &&
    + 	fatal: longline.patch: rejected by sendemail-validate hook
    +-	fatal: command '"'"'$PWD/my-hooks/sendemail-validate'"'"' died with exit code 1
    + 	warning: no patches were sent
    + 	EOF
    + 	test_cmp expect actual
    +@@ t/t9001-send-email.sh: test_expect_success $PREREQ "--validate respects absolute core.hooksPath path" '
    + 	test_path_is_file my-hooks.ran &&
    + 	cat >expect <<-EOF &&
    + 	fatal: longline.patch: rejected by sendemail-validate hook
    +-	fatal: command '"'"'$PWD/my-hooks/sendemail-validate'"'"' died with exit code 1
    + 	warning: no patches were sent
    + 	EOF
    + 	test_cmp expect actual
     @@ t/t9001-send-email.sh: test_expect_success $PREREQ 'invoke hook' '
      	mkdir -p .git/hooks &&
      
36:  7f05b25392 ! 35:  d2a477d9e3 run-command: stop thinking about hooks
    @@ hook.c: static int should_include_hookdir(const char *path, enum hookdir_opt cfg
     +}
     +
     +
    - struct list_head* hook_list(const struct strbuf* hookname)
    + struct list_head* hook_list(const char* hookname)
      {
      	struct strbuf hook_key = STRBUF_INIT;
    -@@ hook.c: struct list_head* hook_list(const struct strbuf* hookname)
    +@@ hook.c: struct list_head* hook_list(const char* hookname)
      	git_config(hook_config_lookup, &cb_data);
      
      	if (have_git_dir()) {
    --		const char *legacy_hook_path = find_hook(hookname->buf);
    -+		const char *legacy_hook_path = find_legacy_hook(hookname->buf);
    +-		const char *legacy_hook_path = find_hook(hookname);
    ++		const char *legacy_hook_path = find_legacy_hook(hookname);
      
      		/* Unconditionally add legacy hook, but annotate it. */
      		if (legacy_hook_path) {
37:  e9b1f847f2 <  -:  ---------- docs: unify githooks and git-hook manpages
 -:  ---------- > 36:  62a3e3b419 doc: clarify fsmonitor-watchman specification
 -:  ---------- > 37:  5c864de1aa docs: link githooks and git-hook manpages

-- 
2.31.1.818.g46aad6cb9e-goog


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

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

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

  git send-email \
    --in-reply-to=20210527000856.695702-1-emilyshaffer@google.com \
    --to=emilyshaffer@google.com \
    --cc=Johannes.Schindelin@gmx.de \
    --cc=avarab@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=james@jramsay.com.au \
    --cc=jonathantanmy@google.com \
    --cc=jrnieder@gmail.com \
    --cc=peff@peff.net \
    --cc=phillip.wood123@gmail.com \
    --cc=sandals@crustytoothpaste.net \
    --cc=steadmon@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

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

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