Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Git only allow merge from development into master

Tags:

git

branch

merge

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.

like image 794
Mark Gargan Avatar asked Apr 12 '17 11:04

Mark Gargan


1 Answers

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
}
like image 87
torek Avatar answered Oct 20 '22 02:10

torek