git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: "Ævar Arnfjörð Bjarmason" <avarab@gmail.com>
To: git@vger.kernel.org
Cc: "Junio C Hamano" <gitster@pobox.com>,
	"Phillip Wood" <phillip.wood123@gmail.com>,
	"René Scharfe" <l.s.r@web.de>,
	"Emily Shaffer" <emilyshaffer@google.com>,
	"Bagas Sanjaya" <bagasdotme@gmail.com>,
	"Ævar Arnfjörð Bjarmason" <avarab@gmail.com>
Subject: [PATCH v4 00/17] hook.[ch]: new library to run hooks + simple hook conversion
Date: Mon,  1 Nov 2021 19:56:05 +0100	[thread overview]
Message-ID: <cover-v4-00.17-00000000000-20211101T184938Z-avarab@gmail.com> (raw)
In-Reply-To: <cover-v3-00.13-00000000000-20211019T231647Z-avarab@gmail.com>

Part 2 of the greater configurable hook saga, starting by converting
some existing simple hooks to the new hook.[ch] library and "git hook
run" utility. See [1] for the last iteration.

This re-roll should address Junio's comments on v3, i.e. there's now a
run_hooks_l() API similar to run_hook_le(). I also simplified the
callers of run_hooks(), which is now called run_hooks_opt().

Since no callers needed anything but a one-shot call the memory public
memory management API is gone, that'll eventually be needed for a "git
hook list" with configurable hooks, but let's introduce those API bits
then, not now.

This grew to 17 patches from 13 due to splitting up some commints for
ease of review, the overall diffstat got smaller. I picked a function
with the same width as the old function, so many of the diffs are
now simply a s/run_hook_le(NULL, /run_hooks_l(/.

1. https://lore.kernel.org/git/cover-v3-00.13-00000000000-20211019T231647Z-avarab@gmail.com/

Emily Shaffer (14):
  hook: add 'run' subcommand
  gc: use hook library for pre-auto-gc hook
  am: convert {pre,post}-applypatch to use hook.h
  rebase: convert pre-rebase to use hook.h
  am: convert applypatch-msg to use hook.h
  merge: convert post-merge to use hook.h
  hooks: convert non-worktree 'post-checkout' hook to hook library
  hooks: convert worktree 'post-checkout' hook to hook library
  send-email: use 'git hook run' for 'sendemail-validate'
  git-p4: use 'git hook' to run hooks
  commit: convert {pre-commit,prepare-commit-msg} hook to hook.h
  read-cache: convert post-index-change to use hook.h
  receive-pack: convert push-to-checkout hook to hook.h
  run-command: remove old run_hook_{le,ve}() hook API

Ævar Arnfjörð Bjarmason (3):
  hook API: add a run_hooks() wrapper
  hook API: add a run_hooks_l() wrapper
  git hook run: add an --ignore-missing flag

 .gitignore                 |   1 +
 Documentation/git-hook.txt |  45 +++++++++++++
 Documentation/githooks.txt |   4 ++
 Makefile                   |   1 +
 builtin.h                  |   1 +
 builtin/am.c               |   6 +-
 builtin/checkout.c         |   3 +-
 builtin/clone.c            |   3 +-
 builtin/gc.c               |   3 +-
 builtin/hook.c             |  84 +++++++++++++++++++++++
 builtin/merge.c            |   2 +-
 builtin/rebase.c           |   3 +-
 builtin/receive-pack.c     |   7 +-
 builtin/worktree.c         |  27 +++-----
 command-list.txt           |   1 +
 commit.c                   |  15 +++--
 git-p4.py                  |  70 ++-----------------
 git-send-email.perl        |  22 +++---
 git.c                      |   1 +
 hook.c                     | 131 ++++++++++++++++++++++++++++++++++++
 hook.h                     |  57 ++++++++++++++++
 read-cache.c               |   3 +-
 reset.c                    |   3 +-
 run-command.c              |  32 ---------
 run-command.h              |  17 -----
 t/t1800-hook.sh            | 134 +++++++++++++++++++++++++++++++++++++
 t/t9001-send-email.sh      |   4 +-
 27 files changed, 522 insertions(+), 158 deletions(-)
 create mode 100644 Documentation/git-hook.txt
 create mode 100644 builtin/hook.c
 create mode 100755 t/t1800-hook.sh

Range-diff against v3:
 1:  02fd699e699 !  1:  d97d6734961 hook: add 'run' subcommand
    @@ Commit message
         builtin/{commit-graph,multi-pack-index}.c.
     
         Some of the implementation here, such as a function being named
    -    run_hooks() when it's tasked with running one hook, to using the
    +    run_hooks_opt() when it's tasked with running one hook, to using the
         run_processes_parallel_tr2() API to run with jobs=1 is somewhere
         between a bit odd and and an overkill for the current features of this
         "hook run" command and the hook.[ch] API.
    @@ builtin/hook.c (new)
     +	int i;
     +	struct run_hooks_opt opt = RUN_HOOKS_OPT_INIT;
     +	const char *hook_name;
    -+	const char *hook_path;
     +	struct option run_options[] = {
     +		OPT_END(),
     +	};
    @@ builtin/hook.c (new)
     +	git_config(git_default_config, NULL);
     +
     +	hook_name = argv[0];
    -+	hook_path = find_hook(hook_name);
    -+	if (!hook_path) {
    -+		error("cannot find a hook named %s", hook_name);
    -+		return 1;
    -+	}
    -+
    -+	ret = run_hooks(hook_name, hook_path, &opt);
    -+	run_hooks_opt_clear(&opt);
    ++	opt.error_if_missing = 1;
    ++	ret = run_hooks_opt(hook_name, &opt);
    ++	if (ret < 0) /* error() return */
    ++		ret = 1;
     +	return ret;
     +usage:
     +	usage_with_options(builtin_hook_run_usage, run_options);
    @@ hook.c: int hook_exists(const char *name)
      	return !!find_hook(name);
      }
     +
    -+void run_hooks_opt_clear(struct run_hooks_opt *o)
    -+{
    -+	strvec_clear(&o->env);
    -+	strvec_clear(&o->args);
    -+}
    -+
     +static int pick_next_hook(struct child_process *cp,
     +			  struct strbuf *out,
     +			  void *pp_cb,
    @@ hook.c: int hook_exists(const char *name)
     +	return 0;
     +}
     +
    -+int run_hooks(const char *hook_name, const char *hook_path,
    -+	      struct run_hooks_opt *options)
    ++static void run_hooks_opt_clear(struct run_hooks_opt *options)
    ++{
    ++	strvec_clear(&options->env);
    ++	strvec_clear(&options->args);
    ++}
    ++
    ++int run_hooks_opt(const char *hook_name, struct run_hooks_opt *options)
     +{
     +	struct hook_cb_data cb_data = {
     +		.rc = 0,
     +		.hook_name = hook_name,
    -+		.hook_path = hook_path,
     +		.options = options,
     +	};
    ++	const char *const hook_path = find_hook(hook_name);
     +	int jobs = 1;
    ++	int ret = 0;
     +
     +	if (!options)
     +		BUG("a struct run_hooks_opt must be provided to run_hooks");
     +
    ++	if (!hook_path && !options->error_if_missing)
    ++		goto cleanup;
    ++
    ++	if (!hook_path) {
    ++		ret = error("cannot find a hook named %s", hook_name);
    ++		goto cleanup;
    ++	}
    ++
    ++	cb_data.hook_path = hook_path;
     +	run_processes_parallel_tr2(jobs,
     +				   pick_next_hook,
     +				   notify_start_failure,
    @@ hook.c: int hook_exists(const char *name)
     +				   &cb_data,
     +				   "hook",
     +				   hook_name);
    -+
    -+	return cb_data.rc;
    ++	ret = cb_data.rc;
    ++cleanup:
    ++	run_hooks_opt_clear(options);
    ++	return ret;
     +}
     
      ## hook.h ##
    @@ hook.h
     +
     +	/* Args to be passed to each hook */
     +	struct strvec args;
    ++
    ++	/* Emit an error if the hook is missing */
    ++	unsigned int error_if_missing:1;
     +};
     +
     +#define RUN_HOOKS_OPT_INIT { \
    @@ hook.h: const char *find_hook(const char *name);
      int hook_exists(const char *hookname);
      
     +/**
    -+ * Clear data from an initialized "struct run_hooks_opt".
    -+ */
    -+void run_hooks_opt_clear(struct run_hooks_opt *o);
    -+
    -+/**
    -+ * Takes an already resolved hook found via find_hook() and runs
    -+ * it. Does not call run_hooks_opt_clear() for you.
    ++ * Takes a `hook_name`, resolves it to a path with find_hook(), and
    ++ * runs the hook for you with the options specified in "struct
    ++ * run_hooks opt". Will free memory associated with the "struct run_hooks_opt".
    ++ *
    ++ * Returns the status code of the run hook, or a negative value on
    ++ * error().
     + */
    -+int run_hooks(const char *hookname, const char *hook_path,
    -+	      struct run_hooks_opt *options);
    ++int run_hooks_opt(const char *hook_name, struct run_hooks_opt *options);
      #endif
     
      ## t/t1800-hook.sh (new) ##
 -:  ----------- >  2:  ca6464f7d5e hook API: add a run_hooks() wrapper
 2:  42cc4d2c3c6 !  3:  173860afca1 gc: use hook library for pre-auto-gc hook
    @@ Commit message
         gc: use hook library for pre-auto-gc hook
     
         Move the pre-auto-gc hook away from run-command.h to and over to the
    -    new hook.h library.
    -
    -    To do this introduce a simple run_hooks_oneshot() wrapper, we'll be
    -    using it extensively for these simple cases of wanting to run a single
    -    hook under a given name, and having it free the memory we allocate for
    -    us.
    +    new hook.h library. This uses the new run_hooks() wrapper.
     
         Signed-off-by: Emily Shaffer <emilyshaffer@google.com>
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
    @@ builtin/gc.c: static int need_to_gc(void)
      		return 0;
      
     -	if (run_hook_le(NULL, "pre-auto-gc", NULL))
    -+	if (run_hooks_oneshot("pre-auto-gc", NULL))
    ++	if (run_hooks("pre-auto-gc"))
      		return 0;
      	return 1;
      }
    -
    - ## hook.c ##
    -@@ hook.c: int run_hooks(const char *hook_name, const char *hook_path,
    - 
    - 	return cb_data.rc;
    - }
    -+
    -+int run_hooks_oneshot(const char *hook_name, struct run_hooks_opt *options)
    -+{
    -+	const char *hook_path;
    -+	struct run_hooks_opt hook_opt_scratch = RUN_HOOKS_OPT_INIT;
    -+	int ret = 0;
    -+
    -+	if (!options)
    -+		options = &hook_opt_scratch;
    -+
    -+	hook_path = find_hook(hook_name);
    -+	if (!hook_path)
    -+		goto cleanup;
    -+
    -+	ret = run_hooks(hook_name, hook_path, options);
    -+cleanup:
    -+	run_hooks_opt_clear(options);
    -+
    -+	return ret;
    -+}
    -
    - ## hook.h ##
    -@@ hook.h: void run_hooks_opt_clear(struct run_hooks_opt *o);
    - /**
    -  * Takes an already resolved hook found via find_hook() and runs
    -  * it. Does not call run_hooks_opt_clear() for you.
    -+ *
    -+ * See run_hooks_oneshot() for the simpler one-shot API.
    -  */
    - int run_hooks(const char *hookname, const char *hook_path,
    - 	      struct run_hooks_opt *options);
    -+
    -+/**
    -+ * Calls find_hook() on your "hook_name" and runs the hooks (if any)
    -+ * with run_hooks().
    -+ *
    -+ * If "options" is provided calls run_hooks_opt_clear() on it for
    -+ * you. If "options" is NULL the default options from
    -+ * RUN_HOOKS_OPT_INIT will be used.
    -+ */
    -+int run_hooks_oneshot(const char *hook_name, struct run_hooks_opt *options);
    -+
    - #endif
 4:  b26cef24f39 !  4:  80a2171ddaf am: convert applypatch to use hook.h
    @@ Metadata
     Author: Emily Shaffer <emilyshaffer@google.com>
     
      ## Commit message ##
    -    am: convert applypatch to use hook.h
    +    am: convert {pre,post}-applypatch to use hook.h
     
    -    Teach pre-applypatch, post-applypatch, and applypatch-msg to use the
    -    hook.h library instead of the run-command.h library.
    +    Teach pre-applypatch and post-applypatch to use the hook.h library
    +    instead of the run-command.h library.
     
         Signed-off-by: Emily Shaffer <emilyshaffer@google.com>
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
      ## builtin/am.c ##
    -@@ builtin/am.c: static void am_destroy(const struct am_state *state)
    - static int run_applypatch_msg_hook(struct am_state *state)
    - {
    - 	int ret;
    -+	struct run_hooks_opt opt = RUN_HOOKS_OPT_INIT;
    - 
    - 	assert(state->msg);
    --	ret = run_hook_le(NULL, "applypatch-msg", am_path(state, "final-commit"), NULL);
    -+	strvec_push(&opt.args, am_path(state, "final-commit"));
    -+	ret = run_hooks_oneshot("applypatch-msg", &opt);
    - 
    - 	if (!ret) {
    - 		FREE_AND_NULL(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;
      
     -	if (run_hook_le(NULL, "pre-applypatch", NULL))
    -+	if (run_hooks_oneshot("pre-applypatch", NULL))
    ++	if (run_hooks("pre-applypatch"))
      		exit(1);
      
      	if (write_cache_as_tree(&tree, 0, NULL))
    @@ builtin/am.c: static void do_commit(const struct am_state *state)
      	}
      
     -	run_hook_le(NULL, "post-applypatch", NULL);
    -+	run_hooks_oneshot("post-applypatch", NULL);
    ++	run_hooks("post-applypatch");
      
      	strbuf_release(&sb);
      }
 -:  ----------- >  5:  74f459db287 hook API: add a run_hooks_l() wrapper
 3:  cbbfd77a4f6 !  6:  1fd70c0e88a rebase: convert pre-rebase to use hook.h
    @@ Commit message
         Move the pre-rebase hook away from run-command.h to and over to the
         new hook.h library.
     
    +    Since this hook needs arguments introduce a run_hooksl() wrapper, like
    +    run_hooks(), but it takes varargs.
    +
         Signed-off-by: Emily Shaffer <emilyshaffer@google.com>
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
    @@ builtin/rebase.c
      #define DEFAULT_REFLOG_ACTION "rebase"
      
     @@ builtin/rebase.c: int cmd_rebase(int argc, const char **argv, const char *prefix)
    - 	int reschedule_failed_exec = -1;
    - 	int allow_preemptive_ff = 1;
    - 	int preserve_merges_selected = 0;
    -+	struct run_hooks_opt hook_opt = RUN_HOOKS_OPT_INIT;
    - 	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)
    - 	}
      
      	/* If a hook exists, give it a chance to interrupt*/
    -+	strvec_push(&hook_opt.args, options.upstream_arg);
    -+	if (argc)
    -+		strvec_push(&hook_opt.args, argv[0]);
      	if (!ok_to_skip_pre_rebase &&
     -	    run_hook_le(NULL, "pre-rebase", options.upstream_arg,
    --			argc ? argv[0] : NULL, NULL))
    -+	    run_hooks_oneshot("pre-rebase", &hook_opt))
    ++	    run_hooks_l("pre-rebase", options.upstream_arg,
    + 			argc ? argv[0] : NULL, NULL))
      		die(_("The pre-rebase hook refused to rebase."));
      
    - 	if (options.flags & REBASE_DIFFSTAT) {
 -:  ----------- >  7:  ccba3ddf52e am: convert applypatch-msg to use hook.h
 6:  7a9fd8627cd !  8:  2c23e8645ec merge: convert post-merge to use hook.h
    @@ Commit message
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
      ## builtin/merge.c ##
    -@@ builtin/merge.c: static void finish(struct commit *head_commit,
    - 		   const struct object_id *new_head, const char *msg)
    - {
    - 	struct strbuf reflog_message = STRBUF_INIT;
    -+	struct run_hooks_opt opt = RUN_HOOKS_OPT_INIT;
    - 	const struct object_id *head = &head_commit->object.oid;
    - 
    - 	if (!msg)
     @@ builtin/merge.c: static void finish(struct commit *head_commit,
      	}
      
      	/* Run a post-merge hook */
     -	run_hook_le(NULL, "post-merge", squash ? "1" : "0", NULL);
    -+	strvec_push(&opt.args, squash ? "1" : "0");
    -+	run_hooks_oneshot("post-merge", &opt);
    ++	run_hooks_l("post-merge", squash ? "1" : "0", NULL);
      
      	apply_autostash(git_path_merge_autostash(the_repository));
      	strbuf_release(&reflog_message);
 -:  ----------- >  9:  cb95c79093b hooks: convert non-worktree 'post-checkout' hook to hook library
 5:  2a747a65829 ! 10:  f330600fec8 hooks: convert 'post-checkout' hook to hook library
    @@ Metadata
     Author: Emily Shaffer <emilyshaffer@google.com>
     
      ## Commit message ##
    -    hooks: convert 'post-checkout' hook to hook library
    +    hooks: convert worktree 'post-checkout' hook to hook library
     
         Move the running of the 'post-checkout' hook away from run-command.h
    -    to the new hook.h library. For "worktree" this requires a change to it
    -    to run the hooks from a given directory.
    +    to the new hook.h library in builtin/worktree.c. For this special case
    +    we need a change to the hook API to teach it to run the hook from a
    +    given directory.
     
    -    We could strictly speaking skip the "absolute_path" flag and just
    -    check if "dir" is specified, but let's split them up for clarity, as
    -    well as for any future user who'd like to set "dir" but not implicitly
    -    change the argument to an absolute path.
    +    We cannot skip the "absolute_path" flag and just check if "dir" is
    +    specified as we'd then fail to find our hook in the new dir we'd
    +    chdir() to. We currently don't have a use-case for running a hook not
    +    in our "base" repository at a given absolute path, so let's have "dir"
    +    imply absolute_path(find_hook(hook_name)).
     
         Signed-off-by: Emily Shaffer <emilyshaffer@google.com>
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
    - ## builtin/checkout.c ##
    -@@
    - #include "config.h"
    - #include "diff.h"
    - #include "dir.h"
    -+#include "hook.h"
    - #include "ll-merge.h"
    - #include "lockfile.h"
    - #include "merge-recursive.h"
    -@@ builtin/checkout.c: struct branch_info {
    - static int post_checkout_hook(struct commit *old_commit, struct commit *new_commit,
    - 			      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()),
    --			   changed ? "1" : "0", NULL);
    -+	struct run_hooks_opt opt = RUN_HOOKS_OPT_INIT;
    -+
    - 	/* "new_commit" can be NULL when checking out from the index before
    - 	   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()),
    -+		     changed ? "1" : "0",
    -+		     NULL);
    -+	return run_hooks_oneshot("post-checkout", &opt);
    - }
    - 
    - static int update_some(const struct object_id *oid, struct strbuf *base,
    -
    - ## builtin/clone.c ##
    -@@
    - #include "connected.h"
    - #include "packfile.h"
    - #include "list-objects-filter-options.h"
    -+#include "hook.h"
    - 
    - /*
    -  * Overall FIXMEs:
    -@@ builtin/clone.c: static int checkout(int submodule_progress)
    - 	struct tree *tree;
    - 	struct tree_desc t;
    - 	int err = 0;
    -+	struct run_hooks_opt hook_opt = RUN_HOOKS_OPT_INIT;
    - 
    - 	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()),
    --			   oid_to_hex(&oid), "1", NULL);
    -+	strvec_pushl(&hook_opt.args, oid_to_hex(null_oid()), oid_to_hex(&oid),
    -+		     "1", NULL);
    -+	err |= run_hooks_oneshot("post-checkout", &hook_opt);
    - 
    - 	if (!err && (option_recurse_submodules.nr > 0)) {
    - 		struct strvec args = STRVEC_INIT;
    -
      ## builtin/worktree.c ##
     @@ builtin/worktree.c: static int add_worktree(const char *path, const char *refname,
      	 * is_junk is cleared, but do return appropriate code when hook fails.
    @@ builtin/worktree.c: static int add_worktree(const char *path, const char *refnam
     +			     "1",
     +			     NULL);
     +		opt.dir = path;
    -+		opt.absolute_path = 1;
     +
    -+		ret = run_hooks_oneshot("post-checkout", &opt);
    ++		ret = run_hooks_opt("post-checkout", &opt);
      	}
      
      	strvec_clear(&child_env);
    @@ hook.c: static int pick_next_hook(struct child_process *cp,
      
      	strvec_push(&cp->args, hook_path);
      	strvec_pushv(&cp->args, hook_cb->options->args.v);
    -@@ hook.c: static int notify_hook_finished(int result,
    - int run_hooks(const char *hook_name, const char *hook_path,
    - 	      struct run_hooks_opt *options)
    +@@ hook.c: static void run_hooks_opt_clear(struct run_hooks_opt *options)
    + 
    + int run_hooks_opt(const char *hook_name, struct run_hooks_opt *options)
      {
     +	struct strbuf abs_path = STRBUF_INIT;
      	struct hook_cb_data cb_data = {
      		.rc = 0,
      		.hook_name = hook_name,
    --		.hook_path = hook_path,
    - 		.options = options,
    - 	};
    - 	int jobs = 1;
    -@@ hook.c: int run_hooks(const char *hook_name, const char *hook_path,
    - 	if (!options)
    - 		BUG("a struct run_hooks_opt must be provided to run_hooks");
    +@@ hook.c: int run_hooks_opt(const char *hook_name, struct run_hooks_opt *options)
    + 	}
      
    -+	if (options->absolute_path) {
    + 	cb_data.hook_path = hook_path;
    ++	if (options->dir) {
     +		strbuf_add_absolute_path(&abs_path, hook_path);
    -+		hook_path = abs_path.buf;
    ++		cb_data.hook_path = abs_path.buf;
     +	}
    -+	cb_data.hook_path = hook_path;
     +
      	run_processes_parallel_tr2(jobs,
      				   pick_next_hook,
      				   notify_start_failure,
    -@@ hook.c: int run_hooks(const char *hook_name, const char *hook_path,
    - 				   "hook",
    +@@ hook.c: int run_hooks_opt(const char *hook_name, struct run_hooks_opt *options)
      				   hook_name);
    - 
    -+	if (options->absolute_path)
    -+		strbuf_release(&abs_path);
    -+
    - 	return cb_data.rc;
    + 	ret = cb_data.rc;
    + cleanup:
    ++	strbuf_release(&abs_path);
    + 	run_hooks_opt_clear(options);
    + 	return ret;
      }
    - 
     
      ## hook.h ##
     @@ hook.h: struct run_hooks_opt
      
    - 	/* Args to be passed to each hook */
    - 	struct strvec args;
    + 	/* Emit an error if the hook is missing */
    + 	unsigned int error_if_missing:1;
     +
    -+	/*
    -+	 * Resolve and run the "absolute_path(hook)" instead of
    -+	 * "hook". Used for "git worktree" hooks
    ++	/**
    ++	 * An optional initial working directory for the hook,
    ++	 * translates to "struct child_process"'s "dir" member.
     +	 */
    -+	int absolute_path;
    -+
    -+	/* Path to initial working directory for subprocess */
     +	const char *dir;
      };
      
      #define RUN_HOOKS_OPT_INIT { \
    -
    - ## reset.c ##
    -@@
    - #include "tree-walk.h"
    - #include "tree.h"
    - #include "unpack-trees.h"
    -+#include "hook.h"
    - 
    - int reset_head(struct repository *r, struct object_id *oid, const char *action,
    - 	       const char *switch_to_branch, unsigned flags,
    -@@ reset.c: int reset_head(struct repository *r, struct object_id *oid, const char *action,
    - 			ret = create_symref("HEAD", switch_to_branch,
    - 					    reflog_head);
    - 	}
    --	if (run_hook)
    --		run_hook_le(NULL, "post-checkout",
    --			    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;
    -+		strvec_pushl(&opt.args,
    -+			     oid_to_hex(orig ? orig : null_oid()),
    -+			     oid_to_hex(oid),
    -+			     "1",
    -+			     NULL);
    -+		run_hooks_oneshot("post-checkout", &opt);
    -+	}
    - 
    - leave_reset_head:
    - 	strbuf_release(&msg);
 7:  840fb530df3 ! 11:  a0b6818c766 git hook run: add an --ignore-missing flag
    @@ Commit message
         git hook run: add an --ignore-missing flag
     
         For certain one-shot hooks we'd like to optimistically run them, and
    -    not complain if they don't exist. This will be used by send-email in a
    -    subsequent commit.
    +    not complain if they don't exist.
    +
    +    This was already supported by the underlying hook.c library, but had
    +    not been exposed via "git hook run". The command version of this will
    +    be used by send-email in a subsequent commit.
     
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
    @@ builtin/hook.c: static int run(int argc, const char **argv, const char *prefix)
      	struct run_hooks_opt opt = RUN_HOOKS_OPT_INIT;
     +	int ignore_missing = 0;
      	const char *hook_name;
    - 	const char *hook_path;
      	struct option run_options[] = {
     +		OPT_BOOL(0, "ignore-missing", &ignore_missing,
     +			 N_("silently ignore missing requested <hook-name>")),
    @@ builtin/hook.c: static int run(int argc, const char **argv, const char *prefix)
      	git_config(git_default_config, NULL);
      
      	hook_name = argv[0];
    -+	if (ignore_missing)
    -+		return run_hooks_oneshot(hook_name, &opt);
    - 	hook_path = find_hook(hook_name);
    - 	if (!hook_path) {
    - 		error("cannot find a hook named %s", hook_name);
    +-	opt.error_if_missing = 1;
    ++	if (!ignore_missing)
    ++		opt.error_if_missing = 1;
    + 	ret = run_hooks_opt(hook_name, &opt);
    + 	if (ret < 0) /* error() return */
    + 		ret = 1;
     
      ## t/t1800-hook.sh ##
     @@ t/t1800-hook.sh: test_expect_success 'git hook run: nonexistent hook' '
 8:  716ebabd794 = 12:  efa35971e9f send-email: use 'git hook run' for 'sendemail-validate'
 9:  95782109270 = 13:  98e0e3330fb git-p4: use 'git hook' to run hooks
10:  706426c8a79 ! 14:  79ea5a2a4f5 commit: convert {pre-commit,prepare-commit-msg} hook to hook.h
    @@ commit.c: size_t ignore_non_trailer(const char *buf, size_t len)
     -	strvec_clear(&hook_env);
      
     -	return ret;
    -+	return run_hooks_oneshot(name, &opt);
    ++	return run_hooks_opt(name, &opt);
      }
11:  39069a9c3ff ! 15:  81612f94707 read-cache: convert post-index-change to use hook.h
    @@ read-cache.c
      
      /* 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
    - {
    - 	int ret;
    - 	int was_full = !istate->sparse_index;
    -+	struct run_hooks_opt hook_opt = RUN_HOOKS_OPT_INIT;
    - 
    - 	ret = convert_to_sparse(istate, 0);
    - 
     @@ read-cache.c: static int do_write_locked_index(struct index_state *istate, struct lock_file *l
      	else
      		ret = close_lock_file_gently(lock);
      
     -	run_hook_le(NULL, "post-index-change",
    --			istate->updated_workdir ? "1" : "0",
    --			istate->updated_skipworktree ? "1" : "0", NULL);
    -+	strvec_pushl(&hook_opt.args,
    -+		     istate->updated_workdir ? "1" : "0",
    -+		     istate->updated_skipworktree ? "1" : "0",
    -+		     NULL);
    -+	run_hooks_oneshot("post-index-change", &hook_opt);
    -+
    ++	run_hooks_l("post-index-change",
    + 			istate->updated_workdir ? "1" : "0",
    + 			istate->updated_skipworktree ? "1" : "0", NULL);
      	istate->updated_workdir = 0;
    - 	istate->updated_skipworktree = 0;
    - 
     
      ## run-command.c ##
     @@ run-command.c: int async_with_fork(void)
12:  9818078f1e5 ! 16:  43ecd6697e0 receive-pack: convert push-to-checkout hook to hook.h
    @@ builtin/receive-pack.c: static const char *push_to_checkout(unsigned char *hash,
     -			hash_to_hex(hash), NULL))
     +	strvec_pushv(&opt.env, env->v);
     +	strvec_push(&opt.args, hash_to_hex(hash));
    -+	if (run_hooks_oneshot(push_to_checkout_hook, &opt))
    ++	if (run_hooks_opt(push_to_checkout_hook, &opt))
      		return "push-to-checkout hook declined";
      	else
      		return NULL;
13:  1bc080d3611 = 17:  9ef574fa30c run-command: remove old run_hook_{le,ve}() hook API
-- 
2.33.1.1570.g069344fdd45


  parent reply	other threads:[~2021-11-01 18:58 UTC|newest]

Thread overview: 115+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-10-15  9:43 [PATCH v2 00/13] hook.[ch]: new library to run hooks + simple hook conversion Ævar Arnfjörð Bjarmason
2021-10-15  9:43 ` [PATCH v2 01/13] hook: add 'run' subcommand Ævar Arnfjörð Bjarmason
2021-10-15 16:24   ` Emily Shaffer
2021-10-15 17:53     ` Eric Sunshine
2021-10-19 23:08     ` Ævar Arnfjörð Bjarmason
2021-10-15  9:43 ` [PATCH v2 02/13] gc: use hook library for pre-auto-gc hook Ævar Arnfjörð Bjarmason
2021-10-15 16:24   ` Emily Shaffer
2021-10-15  9:43 ` [PATCH v2 03/13] rebase: convert pre-rebase to use hook.h Ævar Arnfjörð Bjarmason
2021-10-15 16:25   ` Emily Shaffer
2021-10-15  9:43 ` [PATCH v2 04/13] am: convert applypatch " Ævar Arnfjörð Bjarmason
2021-10-15 16:25   ` Emily Shaffer
2021-10-15  9:43 ` [PATCH v2 05/13] hooks: convert 'post-checkout' hook to hook library Ævar Arnfjörð Bjarmason
2021-10-15 16:25   ` Emily Shaffer
2021-10-15  9:43 ` [PATCH v2 06/13] merge: convert post-merge to use hook.h Ævar Arnfjörð Bjarmason
2021-10-15 16:26   ` Emily Shaffer
2021-10-15  9:43 ` [PATCH v2 07/13] git hook run: add an --ignore-missing flag Ævar Arnfjörð Bjarmason
2021-10-15 16:26   ` Emily Shaffer
2021-10-15  9:43 ` [PATCH v2 08/13] send-email: use 'git hook run' for 'sendemail-validate' Ævar Arnfjörð Bjarmason
2021-10-15 17:07   ` Emily Shaffer
2021-10-15  9:43 ` [PATCH v2 09/13] git-p4: use 'git hook' to run hooks Ævar Arnfjörð Bjarmason
2021-10-15 17:08   ` Emily Shaffer
2021-10-15  9:43 ` [PATCH v2 10/13] commit: convert {pre-commit,prepare-commit-msg} hook to hook.h Ævar Arnfjörð Bjarmason
2021-10-15 17:15   ` Emily Shaffer
2021-10-15  9:43 ` [PATCH v2 11/13] read-cache: convert post-index-change to use hook.h Ævar Arnfjörð Bjarmason
2021-10-15 17:17   ` Emily Shaffer
2021-10-15  9:43 ` [PATCH v2 12/13] receive-pack: convert push-to-checkout hook to hook.h Ævar Arnfjörð Bjarmason
2021-10-15  9:43 ` [PATCH v2 13/13] run-command: remove old run_hook_{le,ve}() hook API Ævar Arnfjörð Bjarmason
2021-10-15 17:18   ` Emily Shaffer
2021-10-15 16:23 ` [PATCH v2 00/13] hook.[ch]: new library to run hooks + simple hook conversion Emily Shaffer
2021-10-16  0:58 ` Junio C Hamano
2021-10-16  5:22   ` Eric Sunshine
2021-10-16  5:47   ` Ævar Arnfjörð Bjarmason
2021-10-16 18:04     ` Junio C Hamano
2021-10-16 18:10       ` Ævar Arnfjörð Bjarmason
2021-10-19 23:20 ` [PATCH v3 " Ævar Arnfjörð Bjarmason
2021-10-19 23:20   ` [PATCH v3 01/13] hook: add 'run' subcommand Ævar Arnfjörð Bjarmason
2021-10-19 23:20   ` [PATCH v3 02/13] gc: use hook library for pre-auto-gc hook Ævar Arnfjörð Bjarmason
2021-10-19 23:20   ` [PATCH v3 03/13] rebase: convert pre-rebase to use hook.h Ævar Arnfjörð Bjarmason
2021-10-29  5:48     ` Junio C Hamano
2021-10-19 23:20   ` [PATCH v3 04/13] am: convert applypatch " Ævar Arnfjörð Bjarmason
2021-10-19 23:20   ` [PATCH v3 05/13] hooks: convert 'post-checkout' hook to hook library Ævar Arnfjörð Bjarmason
2021-10-29  5:55     ` Junio C Hamano
2021-10-19 23:20   ` [PATCH v3 06/13] merge: convert post-merge to use hook.h Ævar Arnfjörð Bjarmason
2021-10-19 23:20   ` [PATCH v3 07/13] git hook run: add an --ignore-missing flag Ævar Arnfjörð Bjarmason
2021-10-29  5:59     ` Junio C Hamano
2021-10-19 23:20   ` [PATCH v3 08/13] send-email: use 'git hook run' for 'sendemail-validate' Ævar Arnfjörð Bjarmason
2021-10-19 23:20   ` [PATCH v3 09/13] git-p4: use 'git hook' to run hooks Ævar Arnfjörð Bjarmason
2021-10-19 23:20   ` [PATCH v3 10/13] commit: convert {pre-commit,prepare-commit-msg} hook to hook.h Ævar Arnfjörð Bjarmason
2021-10-19 23:20   ` [PATCH v3 11/13] read-cache: convert post-index-change to use hook.h Ævar Arnfjörð Bjarmason
2021-10-19 23:20   ` [PATCH v3 12/13] receive-pack: convert push-to-checkout hook to hook.h Ævar Arnfjörð Bjarmason
2021-10-19 23:20   ` [PATCH v3 13/13] run-command: remove old run_hook_{le,ve}() hook API Ævar Arnfjörð Bjarmason
2021-10-29  6:27   ` [PATCH v3 00/13] hook.[ch]: new library to run hooks + simple hook conversion Junio C Hamano
2021-11-01 18:56   ` Ævar Arnfjörð Bjarmason [this message]
2021-11-01 18:56     ` [PATCH v4 01/17] hook: add 'run' subcommand Ævar Arnfjörð Bjarmason
2021-11-01 18:56     ` [PATCH v4 02/17] hook API: add a run_hooks() wrapper Ævar Arnfjörð Bjarmason
2021-11-01 18:56     ` [PATCH v4 03/17] gc: use hook library for pre-auto-gc hook Ævar Arnfjörð Bjarmason
2021-11-01 18:56     ` [PATCH v4 04/17] am: convert {pre,post}-applypatch to use hook.h Ævar Arnfjörð Bjarmason
2021-11-01 18:56     ` [PATCH v4 05/17] hook API: add a run_hooks_l() wrapper Ævar Arnfjörð Bjarmason
2021-11-01 18:56     ` [PATCH v4 06/17] rebase: convert pre-rebase to use hook.h Ævar Arnfjörð Bjarmason
2021-11-01 18:56     ` [PATCH v4 07/17] am: convert applypatch-msg " Ævar Arnfjörð Bjarmason
2021-11-01 18:56     ` [PATCH v4 08/17] merge: convert post-merge " Ævar Arnfjörð Bjarmason
2021-11-01 18:56     ` [PATCH v4 09/17] hooks: convert non-worktree 'post-checkout' hook to hook library Ævar Arnfjörð Bjarmason
2021-11-01 18:56     ` [PATCH v4 10/17] hooks: convert worktree " Ævar Arnfjörð Bjarmason
2021-11-01 18:56     ` [PATCH v4 11/17] git hook run: add an --ignore-missing flag Ævar Arnfjörð Bjarmason
2021-11-01 18:56     ` [PATCH v4 12/17] send-email: use 'git hook run' for 'sendemail-validate' Ævar Arnfjörð Bjarmason
2021-11-01 18:56     ` [PATCH v4 13/17] git-p4: use 'git hook' to run hooks Ævar Arnfjörð Bjarmason
2021-11-01 18:56     ` [PATCH v4 14/17] commit: convert {pre-commit,prepare-commit-msg} hook to hook.h Ævar Arnfjörð Bjarmason
2021-11-01 18:56     ` [PATCH v4 15/17] read-cache: convert post-index-change to use hook.h Ævar Arnfjörð Bjarmason
2021-11-01 18:56     ` [PATCH v4 16/17] receive-pack: convert push-to-checkout hook to hook.h Ævar Arnfjörð Bjarmason
2021-11-01 18:56     ` [PATCH v4 17/17] run-command: remove old run_hook_{le,ve}() hook API Ævar Arnfjörð Bjarmason
2021-11-23 11:45     ` [PATCH v5 00/17] hook.[ch]: new library to run hooks + simple hook conversion Ævar Arnfjörð Bjarmason
2021-11-23 11:46       ` [PATCH v5 01/17] hook: add 'run' subcommand Ævar Arnfjörð Bjarmason
2021-11-23 11:46       ` [PATCH v5 02/17] hook API: add a run_hooks() wrapper Ævar Arnfjörð Bjarmason
2021-11-23 11:46       ` [PATCH v5 03/17] gc: use hook library for pre-auto-gc hook Ævar Arnfjörð Bjarmason
2021-11-23 11:46       ` [PATCH v5 04/17] am: convert {pre,post}-applypatch to use hook.h Ævar Arnfjörð Bjarmason
2021-11-23 11:46       ` [PATCH v5 05/17] hook API: add a run_hooks_l() wrapper Ævar Arnfjörð Bjarmason
2021-11-23 11:46       ` [PATCH v5 06/17] rebase: convert pre-rebase to use hook.h Ævar Arnfjörð Bjarmason
2021-11-23 11:46       ` [PATCH v5 07/17] am: convert applypatch-msg " Ævar Arnfjörð Bjarmason
2021-11-23 11:46       ` [PATCH v5 08/17] merge: convert post-merge " Ævar Arnfjörð Bjarmason
2021-11-23 11:46       ` [PATCH v5 09/17] hooks: convert non-worktree 'post-checkout' hook to hook library Ævar Arnfjörð Bjarmason
2021-11-23 11:46       ` [PATCH v5 10/17] hooks: convert worktree " Ævar Arnfjörð Bjarmason
2021-11-23 11:46       ` [PATCH v5 11/17] git hook run: add an --ignore-missing flag Ævar Arnfjörð Bjarmason
2021-11-23 11:46       ` [PATCH v5 12/17] send-email: use 'git hook run' for 'sendemail-validate' Ævar Arnfjörð Bjarmason
2021-11-23 11:46       ` [PATCH v5 13/17] git-p4: use 'git hook' to run hooks Ævar Arnfjörð Bjarmason
2021-11-23 11:46       ` [PATCH v5 14/17] commit: convert {pre-commit,prepare-commit-msg} hook to hook.h Ævar Arnfjörð Bjarmason
2021-11-23 11:46       ` [PATCH v5 15/17] read-cache: convert post-index-change to use hook.h Ævar Arnfjörð Bjarmason
2021-11-23 11:46       ` [PATCH v5 16/17] receive-pack: convert push-to-checkout hook to hook.h Ævar Arnfjörð Bjarmason
2021-11-23 11:46       ` [PATCH v5 17/17] run-command: remove old run_hook_{le,ve}() hook API Ævar Arnfjörð Bjarmason
2021-12-22  3:59       ` [PATCH v6 00/17] hook.[ch]: new library to run hooks + simple hook conversion Ævar Arnfjörð Bjarmason
2021-12-22  3:59         ` [PATCH v6 01/17] hook: add 'run' subcommand Ævar Arnfjörð Bjarmason
2022-01-07 21:53           ` Emily Shaffer
2022-01-07 23:08             ` Junio C Hamano
2021-12-22  3:59         ` [PATCH v6 02/17] hook API: add a run_hooks() wrapper Ævar Arnfjörð Bjarmason
2022-01-06 18:53           ` Glen Choo
2021-12-22  3:59         ` [PATCH v6 03/17] gc: use hook library for pre-auto-gc hook Ævar Arnfjörð Bjarmason
2021-12-22  3:59         ` [PATCH v6 04/17] am: convert {pre,post}-applypatch to use hook.h Ævar Arnfjörð Bjarmason
2021-12-22  3:59         ` [PATCH v6 05/17] hook API: add a run_hooks_l() wrapper Ævar Arnfjörð Bjarmason
2022-01-06 18:56           ` Glen Choo
2022-01-07 21:56           ` Emily Shaffer
2021-12-22  3:59         ` [PATCH v6 06/17] rebase: convert pre-rebase to use hook.h Ævar Arnfjörð Bjarmason
2021-12-22  3:59         ` [PATCH v6 07/17] am: convert applypatch-msg " Ævar Arnfjörð Bjarmason
2021-12-22  3:59         ` [PATCH v6 08/17] merge: convert post-merge " Ævar Arnfjörð Bjarmason
2021-12-22  3:59         ` [PATCH v6 09/17] hooks: convert non-worktree 'post-checkout' hook to hook library Ævar Arnfjörð Bjarmason
2021-12-22  3:59         ` [PATCH v6 10/17] hooks: convert worktree " Ævar Arnfjörð Bjarmason
2021-12-22  3:59         ` [PATCH v6 11/17] git hook run: add an --ignore-missing flag Ævar Arnfjörð Bjarmason
2022-01-06 19:33           ` Glen Choo
2021-12-22  3:59         ` [PATCH v6 12/17] send-email: use 'git hook run' for 'sendemail-validate' Ævar Arnfjörð Bjarmason
2021-12-22  3:59         ` [PATCH v6 13/17] git-p4: use 'git hook' to run hooks Ævar Arnfjörð Bjarmason
2021-12-22  3:59         ` [PATCH v6 14/17] commit: convert {pre-commit,prepare-commit-msg} hook to hook.h Ævar Arnfjörð Bjarmason
2021-12-22  3:59         ` [PATCH v6 15/17] read-cache: convert post-index-change to use hook.h Ævar Arnfjörð Bjarmason
2021-12-22  3:59         ` [PATCH v6 16/17] receive-pack: convert push-to-checkout hook to hook.h Ævar Arnfjörð Bjarmason
2021-12-22  3:59         ` [PATCH v6 17/17] run-command: remove old run_hook_{le,ve}() hook API Ævar Arnfjörð Bjarmason
2022-01-06 18:47         ` [PATCH v6 00/17] hook.[ch]: new library to run hooks + simple hook conversion Glen Choo
2022-01-07 21:48         ` Emily Shaffer
2022-01-07 22:01           ` Emily Shaffer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

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

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

  git send-email \
    --in-reply-to=cover-v4-00.17-00000000000-20211101T184938Z-avarab@gmail.com \
    --to=avarab@gmail.com \
    --cc=bagasdotme@gmail.com \
    --cc=emilyshaffer@google.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=l.s.r@web.de \
    --cc=phillip.wood123@gmail.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).