[PATCH v2] Introduce core.initHook
From: Johannes Schindelin <hidden>
Date: 2016-06-15 22:44:25
Subsystem:
documentation, the rest · Maintainers:
Jonathan Corbet, Linus Torvalds
Possibly related (same subject, not in this thread)
- 2016-06-15 · Re: [PATCH v2] Introduce core.initHook · Junio C Hamano <hidden>
This variable, if set, specifies the path of a hook which is executed
after every git-init. It can be used to override settings in the
templates per-user.
In case of a re-initialization, the hook gets called with the argument
"reinit".
Signed-off-by: Johannes Schindelin <redacted>
---
On Mon, 24 Mar 2008, Junio C Hamano wrote:
> Johannes Schindelin [off-list ref] writes:
>
> > If you want to run a specific script everytime git-init was
> > issued, you can set the variable `core.initHook`.
>
> ... in your $HOME/.gitconfig, naturally ;-)
Naturally.
> I like the general idea, but with a few nits.
>
> The hook might want to differentiate its behaviour based on how
> git-init was invoked, don't you think?
Okay. It now gets an argument "reinit" when reinitialised. As
you said, the other usages (clone, cvsimport, ...) are a bit
fiddly to implement.
> > +static int config_init_hook(const char *key, const char *value)
> > +{
> > + if (!strcmp(key, "core.inithook"))
> > + init_hook = xstrdup(value);
> > + return 0;
>
> The current way to spell this is with git_config_string() to
> protect yourself from segfaulting on:
Yeah, sorry. Fixed.
> > @@ -407,6 +430,9 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
> > git_config_set("receive.denyNonFastforwards", "true");
> > }
> >
> > + if (run_init_hook())
> > + return 1;
> > +
>
> Hmm. Exit without a message even under !quiet?
Even under quiet, run_init_hook() will complain if the hook is
invalid.
Documentation/config.txt | 5 +++++
Documentation/git-init.txt | 6 ++++++
builtin-init-db.c | 28 ++++++++++++++++++++++++++++
t/t0001-init.sh | 21 +++++++++++++++++++++
4 files changed, 60 insertions(+), 0 deletions(-)
diff --git a/Documentation/config.txt b/Documentation/config.txt
index efde54d..355f049 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt@@ -358,6 +358,11 @@ core.whitespace:: does not trigger if the character before such a carriage-return is not a whitespace (not enabled by default). +core.inithook:: + The path to a program which is run after each call to + linkgit:git-init[1]. The hook is called with the argument + "reinit" if an existing repository is re-initialized. + alias.*:: Command aliases for the linkgit:git[1] command wrapper - e.g. after defining "alias.last = cat-file commit HEAD", the invocation
diff --git a/Documentation/git-init.txt b/Documentation/git-init.txt
index 03a4f0e..26deaaf 100644
--- a/Documentation/git-init.txt
+++ b/Documentation/git-init.txt@@ -60,6 +60,12 @@ If you are initializing a non-bare repository, the config variable `receive.guardCurrentBranch` is set to true. This avoids problems with pushing into the current branch, which does not touch the working tree. +If you want to run a specific script everytime git-init was issued, you +can set the variable `core.initHook` in /etc/gitconfig or $HOME/.gitconfig, +or in the existing repository when re-initializing. In the case that you +reinitialize a repository, the hook is called with the single argument +"reinit". + --
diff --git a/builtin-init-db.c b/builtin-init-db.c
index 36c12a2..e1a54b5 100644
--- a/builtin-init-db.c
+++ b/builtin-init-db.c@@ -6,6 +6,7 @@ #include "cache.h" #include "builtin.h" #include "exec_cmd.h" +#include "run-command.h" #ifndef DEFAULT_GIT_TEMPLATE_DIR #define DEFAULT_GIT_TEMPLATE_DIR "/usr/share/git-core/templates"
@@ -310,6 +311,30 @@ static void guess_repository_type(const char *git_dir) return; } +static const char *init_hook; +static int config_init_hook(const char *key, const char *value) +{ + if (!strcmp(key, "core.inithook")) + return git_config_string(&init_hook, key, value); + return 0; +} + +static int run_init_hook(int reinit) +{ + const char *argv[3] = { NULL, NULL, NULL }; + + git_config(config_init_hook); + if (!init_hook) + return 0; + if (access(init_hook, X_OK) < 0) + return error("init hook '%s' not found", init_hook); + + argv[0] = init_hook; + if (reinit) + argv[1] = "reinit"; + return run_command_v_opt(argv, 0); +} + static const char init_db_usage[] = "git-init [-q | --quiet] [--template=<template-directory>] [--shared]";
@@ -407,6 +432,9 @@ int cmd_init_db(int argc, const char **argv, const char *prefix) git_config_set("receive.denyNonFastforwards", "true"); } + if (run_init_hook(reinit)) + return 1; + if (!quiet) printf("%s%s Git repository in %s/\n", reinit ? "Reinitialized existing" : "Initialized empty",
diff --git a/t/t0001-init.sh b/t/t0001-init.sh
index c015405..7c18d24 100755
--- a/t/t0001-init.sh
+++ b/t/t0001-init.sh@@ -113,4 +113,25 @@ test_expect_success 'GIT_DIR & GIT_WORK_TREE (2)' ' fi ' +cat > init-hook.sh << EOF +#!$SHELL_PATH + +git config test.message success +EOF +chmod a+x init-hook.sh + +# using reinit because of lacking system/global config in the tests + +test_expect_success 'core.initHook' ' + + mkdir hook && + (cd hook && + git init && + test -z "$(git config test.message)" && + git config core.initHook "$(pwd)"/../init-hook.sh && + git init && + test success = "$(git config test.message)") + +' + test_done
--
1.5.5.rc1.178.gd799d