On 2014-08-17 06:29-0700 phil rosenberg wrote:
Hi Alan I'm not great with shell scripts - I use them so infrequently I never remember the syntax. However I have quickly tried to modify the hook fromhttps://gist.github.com/caniszczyk/1327469. Basically you are trying to do something like:git rev-list --first-parent newrev | grep `git rev-list --first-parent --max-count=1 oldrev` where newrev is the revision being pushed and oldrev is the revision being updated. If this gives an empty string then then newrev is not a direct descendant of oldrev. This could be because the merge was done the wrong way round (which is the check described on the CMAKE page) or because someone has modified oldrev on the server before the push occurred. The command works because git rev-list --first-parent commit lists the sha values for each parent of the commit choosing only the first parent, rather than the merged in parent in the case of a merge. Therefore if you have merged the wrong way the new commit will not inherit from the parent of the old commit. Note that the one exception is a fast forward commit, however in this case the result is identical no matter which way the merge was performed so it makes no difference. If you intend to have a "next" branch then you could also ensure that the topic branch being merged in inherits from master (instead of next or bugfixes or whatever), by branching next, making a change to master. Finding the sha for this first commit which is not on next and grepping for it in the same way as above. Attached is my quick hack of that script which just replaces the requirement for fast forward merges only, with the requirement above - I haven't tested it or tried to run it and it will have windows line endings but I haven't got time right now. The syntax might be wrong, but I'm sure you can see the intent. I'm sure you can have a look at it and have a play with the git rev-list command to see what is happening and add stuff if you like.
Hi Phil: I am impressed at how far you have gotten with this! This sounds like it may lead to the exact server-side hook that we need. Note, it is going to take me a while to follow what you have discovered in any detail because I am distracted by the client-side hook implementation that should nicely complement the server-side hook implementation, and I still need to get up to speed on some of the commands you are using and relate them to what the wiki says about maintaining a "clean shape of history". Alan __________________________ Alan W. Irwin Astronomical research affiliation with Department of Physics and Astronomy, University of Victoria (astrowww.phys.uvic.ca). Programming affiliations with the FreeEOS equation-of-state implementation for stellar interiors (freeeos.sf.net); the Time Ephemerides project (timeephem.sf.net); PLplot scientific plotting software package (plplot.sf.net); the libLASi project (unifont.org/lasi); the Loads of Linux Links project (loll.sf.net); and the Linux Brochure Project (lbproject.sf.net). __________________________ Linux-powered Science __________________________
#!/bin/sh # # For each ref, validate the commit. # # - It disallows deleting branches without a /. # - It disallows non fast-forward on branches without a /. # - It disallows deleting tags without a /. # - It disallows unannotated tags to be pushed. validate_ref() { # --- Arguments oldrev=$(git rev-parse $1) newrev=$(git rev-parse $2) refname="$3" allownonffpush=$( git config --bool hooks.allownonffpush ) allowdeletebranch=$( git config --bool hooks.allowdeletebranch ) allowdeletetag=$( git config --bool hooks.allowdeletetag ) allowcreatenottopicbranch=$( git config --bool hooks.allowcreatenottopicbranch ) # oldrev could be 0s which means creating refname # newrev could be 0s which means deleting refname case "$refname" in refs/heads/*) branch=$(expr "$refname" : "refs/heads/\(.*\)") topicbranch=$(expr "$branch" : "\(.*/.*\)") topicuser=$(expr "$branch" : "\(.*\)/.*") if [ 0 -ne $(expr "$newrev" : "0*$") ]; then # deleting # only topic branches can be deleted if [ "$allowdeletebranch" != "true" -a -z "$topicbranch" ]; then fail=1 echo >&2 "*** Deleting the branch $branch is not permitted. ***" return fi if [ "$allowdeletebranch" != "true" -a "$USER" != "$topicuser" ]; then fail=1 echo >&2 "*** Deleting the branch $branch is not permitted by $USER. ***" return fi return # Don't need to validate old revision else #updating if [ 0 -ne $(expr "$oldrev" : "0*$") ]; then # pushing a new branch if [ "$allowcreatenottopicbranch" != "true" -a -z "$topicbranch" ]; then fail=1 echo >&2 "*** creation of branch $branch is not permitted. ***" fi return # it's not a FF merge fi oldrevparent=`git rev-list --first-parent --max-count=1 oldrev` if [ "" -eq `git rev-list --first-parent newrev | grep oldrevparent` ]; then # non fast-forward fail=1 echo >&2 "*** Branch merge has been performed the wrong way round or the branch has been modified since the merge. ***" fi fi ;; refs/tags/*) tag=$(expr "$refname" : "refs/tags/\(.*\)") topictag=$(expr "$tag" : "\(.*/.*\)") topicuser=$(expr "$tag" : "\(.*\)/.*") if [ 0 -ne $(expr "$newrev" : "0*$") ]; then # deleting # only topic tags can be deleted if [ "$allowdeletetag" != "true" -a -z "$topictag" ]; then fail=1 echo >&2 "*** Deleting the tag $tag is not permitted. ***" return fi if [ "$allowdeletetag" != "true" -a "$USER" != "$topicuser" ]; then fail=1 echo >&2 "*** Deleting the tag $tag is not permitted by $USER. ***" return fi return fi ;; *) fail=1 echo >&2 "*** pre-receive hook does not understand ref $refname in this repository. ***" echo >&2 "*** Contact the repository administrator. ***" ;; esac } fail="" # Allow dual mode: run from the command line just like the update hook, or # if no arguments are given then run as a hook script if [ -n "$1" -a -n "$2" -a -n "$3" ]; then # Output to the terminal in command line mode - if someone wanted to # resend an email; they could redirect the output to sendmail # themselves PAGER= validate_ref $2 $3 $1 else while read oldrev newrev refname do validate_ref $oldrev $newrev $refname done fi if [ -n "$fail" ]; then exit $fail fi
------------------------------------------------------------------------------
_______________________________________________ Plplot-devel mailing list Plplot-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/plplot-devel