I'd like be able to setup our branches so that merges can only go into master from the development branch.
I understand that perhaps this sounds draconian and I should to ask myself the question, do i not trust the developers on the team... For the time being I don't because they're just becoming familiar with Git. In time I'll remove the restriction but until then this would be a useful. Is it possible?
Thanks, Mark.
As kowsky answered, it's possible to do this in a server-side pre-receive hook. It is surprisingly difficult though, primarily because Git's notion of a branch is somewhat slippery.
I wrote a pre-receive hook that does this, among other things; the code is available here. See the merges_from
function, and note the comments above it. Since links are a bit iffy in StackOverflow I will include the actual function here as well. (Note that this code is meant to work with positively ancient versions of Git, so it does not use modern features like git for-each-ref --merged
.)
# $1 is a merge commit. Find all its parents, except the first
# (which is "on" the branch being merged-into and hence not relevant).
# For each remaining parent, find which branch(es) contain them.
# If those branch heads *are* them, consider that the "source" of the merge.
#
# Note that this means if branches A and B both name commit 1234567,
# and you merge commit 1234567 into branch master, this considers
# the merge (with its one parent) to merge both branches A and B.
# That may not be ideal, but it is what we get...
merges_from()
{
local branches b src
set -- $($GIT rev-list --parents --no-walk $1)
shift 2
for i do
# git branch --contains may print something like
# * (no branch)
# or
# * (detached from blah)
# if HEAD is detached. This should not happen in
# a bare repo, but if it does, we'll add HEAD to
# our list.
branches=$($GIT branch --merged $i |
sed -e 's/\* (.*)/HEAD/' -e 's/^[* ]//')
set -- $branches
src=""
for b do
if [ $($GIT rev-parse $b) = $i ]; then
src="${src}${src:+ }$b"
fi
[ "$src" == "" ] && src="-"
done
echo $src
done
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With