Git/Hooks: Difference between revisions

From KitwarePublic
< Git
Jump to navigationJump to search
(Created page with '=Local= The [http://www.kernel.org/pub/software/scm/git/docs/git-commit.html git commit] command creates ''local'' commits. A separate [http://www.kernel.org/pub/software/scm/gi…')
 
No edit summary
 
(9 intermediate revisions by 3 users not shown)
Line 1: Line 1:
=Local=
=Setup=


The [http://www.kernel.org/pub/software/scm/git/docs/git-commit.html git commit] command creates ''local'' commits.
The [http://www.kernel.org/pub/software/scm/git/docs/git-commit.html git commit] command creates ''local'' commits.
Line 15: Line 15:
  $ cd .git/hooks
  $ cd .git/hooks
  $ git init
  $ git init
$ cd ../..
Choose one of the following methods to install or update the hooks.
The hooks will then run in the outer repository to enforce some rules on commits.


Many <code>public.kitware.com</code> repositories provides a <code>hooks</code> branch.
===Local Pull===
 
Many <code>public.kitware.com</code> repositories provide a <code>hooks</code> branch.
It will have already been fetched into your local clone.
It will have already been fetched into your local clone.
Pull it from there:
Pull it from there:


$ git fetch origin
$ cd .git/hooks
  $ git pull .. remotes/origin/hooks
  $ git pull .. remotes/origin/hooks
  $ cd ../..
  $ cd ../..


The hooks will now run in the outer repository to enforce some rules on commits.
===Direct Pull===
To update the hooks in the future, run
 
If you did not clone from a <code>public.kitware.com</code> repository you may not have a <code>hooks</code> branch.
Pull it from <code>public.kitware.com</code>:


$ git fetch origin
  $ cd .git/hooks
  $ cd .git/hooks
  $ git pull .. remotes/origin/hooks
  $ git pull git://public.kitware.com/''<repo>''.git hooks
$ cd ../..
 
where <code>''<repo>''.git</code> is the name of your project repository.
 
=Local=


The above sequence maintains the following local hooks in your repository.
The above sequences maintain the following local hooks in your repository.
See Git help on [http://www.kernel.org/pub/software/scm/git/docs/githooks.html githooks] for more details.
See Git help on [http://www.kernel.org/pub/software/scm/git/docs/githooks.html githooks] for more details.


===pre-commit===
==pre-commit==


This runs during <code>git commit</code>.  It checks identity and content of changes:
This runs during <code>git commit</code>.  It checks identity and content of changes:
Line 42: Line 56:
* File modes look reasonable (no executable .cxx files, scripts with shebang lines are executable)
* File modes look reasonable (no executable .cxx files, scripts with shebang lines are executable)
* File size is not too large (don't commit big data files; prints limit and instructions on rejection)
* File size is not too large (don't commit big data files; prints limit and instructions on rejection)
* Submodule updates are staged alone or explicitly allowed (prints instructions on rejection)


One of Git's standard whitespace checks is to reject ''trailing'' whitespace on lines that were added or modified.
One of Git's standard whitespace checks is to reject ''trailing'' whitespace on lines that were added or modified.
Line 83: Line 98:
  $ git config core.whitespace "-blank-at-eol"
  $ git config core.whitespace "-blank-at-eol"


===commit-msg===
==commit-msg==


This runs during <code>git commit</code>.  It checks the commit message format:
This runs during <code>git commit</code>.  It checks the commit message format:
Line 112: Line 127:
Many <code>public.kitware.com</code> repositories have server-side hooks.
Many <code>public.kitware.com</code> repositories have server-side hooks.


===update===
==update==


It runs when someone tries to update a ref on the server by pushing.
The update hook runs when someone tries to update a ref on the server by pushing.
The hook checks all commits included in the push:
The hook checks all commits included in the push:



Latest revision as of 16:31, 1 March 2012

Setup

The git commit command creates local commits. A separate git push step is needed to publish commits to a public.kitware.com repository. The public.kitware.com server enforces some rules on the commits it accepts and will reject non-conforming commits. In order to push rejected commits, one must edit history locally to repair them before publishing.

Since it is possible to create many commits locally and push them all at once, we provide local Git hooks to help developers keep their individual commits clean. Git provides no way to enable such hooks by default, giving developers maximum control over their local repositories. We recommend enabling our hooks manually in all clones.

Git looks for hooks in the .git/hooks directory within the work tree of a local repository. Create a new local repository in this directory to manage the hooks:

$ cd .git/hooks
$ git init
$ cd ../..

Choose one of the following methods to install or update the hooks. The hooks will then run in the outer repository to enforce some rules on commits.

Local Pull

Many public.kitware.com repositories provide a hooks branch. It will have already been fetched into your local clone. Pull it from there:

$ git fetch origin
$ cd .git/hooks
$ git pull .. remotes/origin/hooks
$ cd ../..

Direct Pull

If you did not clone from a public.kitware.com repository you may not have a hooks branch. Pull it from public.kitware.com:

$ cd .git/hooks
$ git pull git://public.kitware.com/<repo>.git hooks
$ cd ../..

where <repo>.git is the name of your project repository.

Local

The above sequences maintain the following local hooks in your repository. See Git help on githooks for more details.

pre-commit

This runs during git commit. It checks identity and content of changes:

  • Git user.name and user.email are set to something reasonable
  • Git's standard whitespace checks (see help on git diff --check)
  • The staged changes do not introduce any leading TABs in source files (we indent with spaces)
  • File modes look reasonable (no executable .cxx files, scripts with shebang lines are executable)
  • File size is not too large (don't commit big data files; prints limit and instructions on rejection)
  • Submodule updates are staged alone or explicitly allowed (prints instructions on rejection)

One of Git's standard whitespace checks is to reject trailing whitespace on lines that were added or modified. Many people consider extra space characters at the end of a line to be an unprofessional style (including Git's own developers), but some don't care. Text editors typically have a mode to highlight trailing whitespace:

Emacs
(custom-set-variables '(show-trailing-whitespace t))
Vim
:highlight ExtraWhitespace ctermbg=red guibg=red
:match ExtraWhitespace /\s\+$/
Visual Studio
To toggle viewing of white space characters, with a source
file document active, choose the menu item:

 Edit > Advanced > View White Space

(2-stroke keyboard shortcut: Ctrl+R, Ctrl+W)
Notepad++ (v5.6.7)
To eliminate trailing white space, choose the menu item:

 Edit > Trim Trailing Space

To toggle viewing of white space characters, choose from the
menu items:

 View > Show Symbol > (multiple items, choose one...)

If you really don't want to keep your code clean of trailing whitespace, you can disable this part of Git's checks locally:

$ git config core.whitespace "-blank-at-eol"

commit-msg

This runs during git commit. It checks the commit message format:

  • The first line must be between 8 and 78 characters long. If you were writing an email to describe the change, this would be the Subject line.
    (Do not bother using 'ENH:' or 'BUG:' prefixes; they take space and are less valuable than a good summary on this line).
  • The first line must not have leading or trailing whitespace.
  • The second line must be blank, if present.
  • The third line and below may be free-form. Try to keep paragraph text formatted in 72 columns (this is not enforced).

GUI and text-based tools that help view history typically use the first line (Subject line) from the commit message to give a one-line summary of each commit. This allows a medium-level view of history, but works well only if developers write good Subject lines for their commits.

Examples of improper commit messages:

Fixed

This is too short and not informative at all.

I did a really complicated change and I am trying to describe the entire thing with a big message entered on the command line.

Many CVS users develop the habit of using the "-m" commit option to specify the whole message on the command line. This is probably because in CVS it is hard to abort a commit if it already brought up the message editor. In Git this is trivial. Just leave the message blank and the whole commit will be aborted. Furthermore, since commits are not published automatically it is easy to allow the commit to complete and then fix it with git commit --amend.

Server

Many public.kitware.com repositories have server-side hooks.

update

The update hook runs when someone tries to update a ref on the server by pushing. The hook checks all commits included in the push:

  • Commit author and committer must have valid email address domains (DNS lookup succeeds).
  • Commit message does not start with "WIP:". (Use the prefix locally for work-in-progress that must be rewritten before publishing.)
  • Changes to paths updated by robots (such as Utilities/kwsys) are not allowed.
  • No "large" blobs may be pushed. The limit is set on a per-repository basis and is typically 1MB or so.
  • No CRLF newlines may be added in the repository (see core.autocrlf in git help config).
  • Submodules (if any) must be pushed before the references to them are pushed.