0

Prologue

I want to create a pre-receive hook from my pre-push hook. Now, looking around the 'net and the SO, I have found many questions pertaining to specific problems, and/or focusing on a description of the hook, instead of actually showing it (I'm looking at you, git-scm).

The point

So anyway, as far as I have gathered, pre-receive hook is called with no parameters. How do I get data then? There is very much data that I would see myself wanting to get a hold of in such hook, for example:

  • pushername (pardon the pun)
  • commit message
  • timestamp
  • changed files
  • target branch

but I honestly have no idea how to get the data - and I know that people do it, because I have seen such scripts in action.

Assumptions

I would like to assume that it's bash-doable, because the less configuration the better, amirite?

Actual question

Coding a pre-receive hook, how to gather data about the push that triggered it?

2 Answers2

1

This is documented, see https://git-scm.com/docs/githooks#pre-receive :

This hook executes once for the receive operation. It takes no arguments, but for each ref to be updated it receives on standard input a line of the format:

<old-value> SP <new-value> SP <ref-name> LF

where <old-value> is the old object name stored in the ref, <new-value> is the new object name to be stored in the ref and <ref-name> is the full name of the ref. When creating a new ref, <old-value> is 40 0.

Note that you can receive updates to multiple branches. When you write your pre-receive hook in bash, you can start with:

while read old new ref; do
    # do something with each $old $new $ref
done

$ref will be the full name, for example, refs/heads/my-branch. $old and $new are SHA-1 names of commit objects.

To get at the commit message, author, etc. you can invoke git commands with $old and $new, for example, git log $old..$new (note that there may be multiple new commits pushed on one branch).

Bruno De Fraine
  • 39,825
  • 8
  • 50
  • 62
  • Can I somehow get the pusher username though? I see that git log gives me acecss to authors, emails, but what if the actual commit is of no interest to me, but the process that brought the commit to the repository? – Matthew Blackwind Oct 14 '16 at 10:09
  • 1
    @MatthewBlackwind: Git doesn't *know* who ran `git push`, in general. You're running on some server and someone has connected to you and said "here, have some commits". Who connected to you, and *how do you know*? Git doesn't care, it leaves authentication up to whatever is running `git receive-pack`. Note that ssh and https do authentication; ssh leaves some env variables set; and `git push --signed` adds a signature blob that `git receive-pack` marks with env variables: https://www.kernel.org/pub/software/scm/git/docs/git-receive-pack.html – torek Oct 14 '16 at 18:54
1

You need to read from stdin. Each line gives you the old reference, new reference and reference name. An starting example can be found at Git pre-receive hook.

Community
  • 1
  • 1
Johan van Breda
  • 473
  • 7
  • 10