On Wed, 4 Sep 2013 04:31:26 -0700 (PDT) Ling <[email protected]> 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 commit. 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 base commit. 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 to [email protected]. For more options, visit https://groups.google.com/groups/opt_out.
