On Wed, 4 Sep 2013 04:31:26 -0700 (PDT)
Ling <oylf1...@gmail.com> wrote:
> Thanks Thomas, And yes I had read this and also I tried with git log
> but this won't works since git log is only created after the push,
> which means it won't compare the new push comment, it only compare
> the previous pushed comment to trigger the hooks. since what I need
> is trigger the hooks when new push comment not meet my prerequisites.
Are you calling `git log` on a ref name (a branch name, if this sounds
simpler) or on the SHA-1 name of the prospective new tip commit of the
ref of interest? You have to do the latter if you're writing a
pre-receive hook because while it works the refs are not yet updated,
and exiting the hook script with a non-zero exit state will leave the
refs in a pre-push state.
For each ref updated during the push session, Git tells your
pre-receive hook the SHA-1 names of both the old commit at which that
ref pointed, and the new commit at which that ref will point if your
hook will exit successfully. You're able to use these names to inspect
the line of history sent to update each ref.
Note that a push operation might be a bit more complex you think it is:
* Several refs might be updated by a single push.
* More than one commit might be sent to update each ref, that is, it's
quite common to push a line or even a graph of commits (if there were
true merges during the development) to update a ref.
This means that if you're going to inspect the log messages of the
received commits, this should be done over *a range of commits* for each
ref to be updated -- starting with the prospective new tip commit of
that ref and ending at the topographically nearest commit which is
shared between the old history of that ref and its prospective new tip
This hints us that it's better to go lower level and use plumbing tools
to manually traverse the relevant bits of history. I'd go with
`git merge-base`, `git rev-list` and `git cat-file` -- a sketch of how
to do this follows.
For each ref to be updated:
1) Call `git merge-base $oldname $newname` -- this will give you the
name of a commit which is common between the old and the new state of
the ref. In the simplest case -- a fast-forward of the ref this will
be the old tip commit of that ref ($oldname here), in a more complex
case, where a user did a forced push which replaced some (or all) of
the ref's history, this will be the nearest (to the prospective new
tip) commit which won't be replaced, and this means its log message
has already been checked at some point back in time.
2) Having obtained this base commit, call
git rev-list $newname ^$basename
to get the list of the SHA-1 names of all commits reachable from the
new prospective ref's tip but excluding those also reachable from the
3) Iterate over the generated list, calling
git cat-file -p $sha1name
This will print a pretty-printed version of the commit object to its
standard output. Commit objects have standard format: the block of
headers (each of the format <name> SP <value>), a blank line, and
then the commit message, which is what's of interest for you.
Note that a commit object might include the "encoding" header naming
the encoding used to encode the actual message. You might hence want
to filter the commit message through
iconv -f $encoding -t utf-8
if the "encoding" header is detected.
You received this message because you are subscribed to the Google Groups "Git
for human beings" group.
To unsubscribe from this group and stop receiving emails from it, send an email
For more options, visit https://groups.google.com/groups/opt_out.