User Tools

Site Tools


git_hooks

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
Last revision Both sides next revision
git_hooks [2019/02/19 09:34]
rpjday [Default hook installation for a new repository]
git_hooks [2019/02/19 11:07]
rpjday [Default hook installation for a new repository]
Line 9: Line 9:
   * client-side   * client-side
   * server-side   * server-side
 +
 +Note that hooks can get their arguments from any combination of:
 +
 +  * the environment
 +  * command-line arguments
 +  * stdin
  
 ===== Default hook installation for a new repository ===== ===== Default hook installation for a new repository =====
Line 26: Line 32:
   * ''​update.sample*''​   * ''​update.sample*''​
  
-These are sample scripts supplied by Git that you can use as is, or customize to taste. In order to activate such scripts:+These are sample scripts supplied by Git that you can use as is, or customize to taste. In order to activate such scripts ​once they'​re copied to the new repository:
  
   * Make sure they are marked as executable.   * Make sure they are marked as executable.
-  * Remove the ''​.sample'' ​prefix ​(exact spelling is important).+  * Remove the ''​.sample'' ​suffix ​(exact spelling is important).
  
-===== Properties of hooks ===== +===== commit-related ​client-side hooks =====
- +
-  * They must be marked executable in order to be active. +
-  * They normally live in ''​$GIT_DIR/​hooks'',​ unless overridden via ''​core.hooksPath''​. +
-  * Running ''​git init''​ on an existing directory will copy in only new hooks; it will never overwrite existing hooks. +
-  * Hooks can get their arguments via the environment,​ command-line arguments, and stdin. +
- +
-===== Supporting code ===== +
- +
-==== run_commit_hook() ==== +
- +
-<​code>​ +
-int run_commit_hook(int editor_is_used,​ const char *index_file,​ const char *name, ...) +
-+
-        struct argv_array hook_env = ARGV_ARRAY_INIT;​ +
-        va_list args; +
-        int ret; +
- +
-        argv_array_pushf(&​hook_env,​ "​GIT_INDEX_FILE=%s",​ index_file);​ +
- +
-        /* +
-         * Let the hook know that no editor will be launched. +
-         */ +
-        if (!editor_is_used) +
-                argv_array_push(&​hook_env,​ "​GIT_EDITOR=:"​);​ +
- +
-        va_start(args,​ name); +
-        ret = run_hook_ve(hook_env.argv,​name,​ args); +
-        va_end(args);​ +
-        argv_array_clear(&​hook_env);​ +
- +
-        return ret; +
-+
-</​code>​ +
- +
-==== builtin/commit.c ==== +
- +
-<​code>​ +
-static int prepare_to_commit(const char *index_file,​ const char *prefix, +
-                             ​struct commit *current_head,​ +
-                             ​struct wt_status *s, +
-                             ​struct strbuf *author_ident) +
-+
-        struct stat statbuf; +
-        struct strbuf committer_ident = STRBUF_INIT;​ +
-        int commitable;​ +
-        struct strbuf sb = STRBUF_INIT;​ +
-        const char *hook_arg1 = NULL; +
-        const char *hook_arg2 = NULL; +
-        int clean_message_contents = (cleanup_mode != COMMIT_MSG_CLEANUP_NONE);​ +
-        int old_display_comment_prefix;​ +
- +
-        /* This checks and barfs if author is badly specified */ +
-        determine_author_info(author_ident);​ +
- +
-        if (!no_verify && run_commit_hook(use_editor,​ index_file, "pre-commit",​ NULL)) +
-                return 0; +
-                 +
-                ... snip ... +
-                 +
-        if (run_commit_hook(use_editor,​ index_file, "​prepare-commit-msg",​ +
-                            git_path_commit_editmsg(),​ hook_arg1, hook_arg2, NULL)) +
-                return 0; +
- +
-        if (use_editor) { +
-                struct argv_array env = ARGV_ARRAY_INIT;​ +
- +
-                argv_array_pushf(&​env,​ "​GIT_INDEX_FILE=%s",​ index_file);​ +
-                if (launch_editor(git_path_commit_editmsg(),​ NULL, env.argv)) { +
-                        fprintf(stderr,​ +
-                        _("​Please supply the message using either -m or -F option.\n"​));​ +
-                        exit(1); +
-                } +
-                argv_array_clear(&​env);​ +
-        } +
- +
-        if (!no_verify &&​ +
-            run_commit_hook(use_editor,​ index_file, "​commit-msg",​ git_path_commit_editmsg(),​ NULL)) { +
-                return 0; +
-        } +
- +
-        return 1; +
-}                 +
-</​code>​ +
- +
-<​code>​ +
-int cmd_commit(int argc, const char **argv, const char *prefix) +
-+
-        const char *argv_gc_auto[] = {"​gc",​ "​--auto",​ NULL}; +
-        static struct wt_status s; +
-        static struct option builtin_commit_options[] = { +
- +
-... snip ... +
- +
-        run_commit_hook(use_editor,​ get_index_file(),​ "​post-commit",​ NULL); +
-        if (amend && !no_post_rewrite) { +
-                commit_post_rewrite(current_head,​ &​oid);​ +
-        } +
-        if (!quiet) { +
-                unsigned int flags = 0; +
- +
-                if (!current_head) +
-                        flags |= SUMMARY_INITIAL_COMMIT;​ +
-                if (author_date_is_interesting()) +
-                        flags |= SUMMARY_SHOW_AUTHOR_DATE;​ +
-                print_commit_summary(prefix,​ &oid, flags); +
-        } +
- +
-        UNLEAK(err);​ +
-        UNLEAK(sb);​ +
-        return 0; +
-+
-</​code>​ +
- +
-===== The client-side hooks =====+
  
 ==== pre-commit ==== ==== pre-commit ====
  
-In a nutshell (from ''​man githooks''​):+From ''​man githooks'':​
  
 <​code>​ <​code>​
-This hook is invoked by git commit, and can be bypassed with+This hook is invoked by git commit(1), and can be bypassed with
 the --no-verify option. It takes no parameters, and is invoked the --no-verify option. It takes no parameters, and is invoked
 before obtaining the proposed commit log message and making a before obtaining the proposed commit log message and making a
Line 210: Line 102:
  
 # If there are whitespace errors, print the offending file names and fail. # If there are whitespace errors, print the offending file names and fail.
-</​code>​ 
- 
-Here's the money command: 
- 
-<​code>​ 
-exec git diff-index --check --cached $against -- 
 </​code>​ </​code>​
  
Line 346: Line 232:
 This hook is meant primarily for notification,​ and cannot affect This hook is meant primarily for notification,​ and cannot affect
 the outcome of git commit. the outcome of git commit.
 +</​code>​
 +
 +There is no sample script provided by Git; you're on your own here.
 +
 +===== Overriding the default hooks =====
 +
 +==== git init ====
 +
 +When initializing a new repository, the template content used for the new repository comes from one of (in order of precedence):​
 +
 +  * the ''​%%--%%template=<​template directory>''​ option
 +  * the value of the ''​$GIT_TEMPLATE_DIR''​ environment variable
 +  * the ''​init.templateDir''​ configuration option
 +  * the contents of ''/​usr/​share/​git-core/​templates/''​
 +
 +==== git clone ====
 +
 +When cloning a repository, the only way to override the installation of default hooks (and template content) is via the ''​%%--%%template=<​template directory>''​ command-line option.
 +==== During normal operation ====
 +
 +From ''​man git-config'':​
 +
 +<​code>​
 +core.hooksPath
 +    By default Git will look for your hooks in the
 +    $GIT_DIR/​hooks directory. Set this to different path, e.g.
 +    /​etc/​git/​hooks,​ and Git will try to find your hooks in that
 +    directory, e.g.  /​etc/​git/​hooks/​pre-receive instead of in
 +    $GIT_DIR/​hooks/​pre-receive.
 +
 +    The path can be either absolute or relative. A relative
 +    path is taken as relative to the directory where the hooks
 +    are run (see the "​DESCRIPTION"​ section of githooks(5)).
 +
 +    This configuration variable is useful in cases where you’d
 +    like to centrally configure your Git hooks instead of
 +    configuring them on a per-repository basis, or as a more
 +    flexible and centralized alternative to having an
 +    init.templateDir where you’ve changed default hooks.
 </​code>​ </​code>​
git_hooks.txt · Last modified: 2019/02/19 11:10 by rpjday