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
[email protected]
https://lists.sourceforge.net/lists/listinfo/plplot-devel