Is it possible to force git to only merge remote tracking branches into the corresponding local branch? E.g. assume origin/X tracks X on origin and corresponds to local X and the same for origin/Y and Y. I want to prevent users to do git checkout Y; git merge origin/X
. Is it possible? How?
Edit:
To make it clear: The workflow is not the problem. People try to merge the wrong branches because they forgot to checkout the correct branch before merging. It is not about “offenders” or pushing to the central repo. It’s just people forgetting at which branch they are. The last “incident” was literally:
“I should commit and push real quick before I leave.
git add .
git commit -am ‘Feature Y’
git push originWhoops, whats that. It tells me to merge branch origin/X first. OK whatevs.
git merge origin/X
Whoops, whats that now. Lots of merge conflicts. What have I done. I better call somebody…”
The user was working in branch Y and did not understand what the git push origin
was saying. It told it that origin/X needed merging and that’s what he did, because he wanted to “push real quick”. In the case above branch X was one commit ahead of the local X, so pushing all branches yielded the “needs merging” error.
I adjusted the “workflow” now to always push a branch explicitly, e.g. git push origin Y
instead of just git push origin
, but that’s not curing the problem. It should (usually) not be allowed without a warning to merge origin/X with Y. For merging feature branches X and Y can be merged.
4
As git is distributed, there is no way to prohibit users to do it locally, and I’m not even sure if it’s possible with local hooks.
And because a user doesn’t have to push all local refs, there is no way to prevent it on the server either.
Edit:
You are talking about mistakes. Git allows users to fix their mistakes and undo the error, but that requires them to notice it. Like I said in the comments you could try to use hooks for this, but there is no pre-merge hook or something.
3
I think that you may be approaching this from the wrong angle.
Why is merging origin/X
into Y
a problem? If it is because, for instance, Y
is a release branch (which is tracking origin/Y
), while origin/X
is a development branch, and you don’t want development code leaking into a production release, then it is more important to control origin/Y
than to control Y
.
As Christopher suggests in a comment, this should really be taken care of by your workflow.
To prevent mistakes though, as Ikke points out, you may want to make use of permissions to limit who can update different remote references. For example, gitolite
allows very fine grained access control. From Scott Chacon’s excellent Pro Git:
Gitolite allows you to specify permissions not just by repository, but also by branch or tag names within each repository. That is, you can specify that certain people (or groups of people) can only push certain “refs” (branches or tags) but not others.
One option is to only allow your continuous integration server to push to your release branches, and only then after your integration and unit tests have passed. This sort of automated workflow can really help prevent mistakes propagating.
One way is to give them alternative commands. I rarely use git merge
; instead, I use the bash functions below. If you’re running on Windows (and not using Cygwin), I suppose you could create batch files to do the same thing.
function branch
{
if [ $# == 0 ] ; then
git branch | grep '^*' | sed -e 's/.* //' ;
elif git branch | grep -q " $1$" ; then
git checkout $1
else
git checkout master
git checkout -b $1
fi ;
}
function push
{
src=`branch`
if [ $# == 0 ] ; then
git push origin ${src} ;
elif [ $# == 1 ] ; then
git push $1 ${src} ;
else
git push $1 ${src}:${2} ;
fi ;
}
function pull
{
if [ $# == 0 ] ; then
src=`branch` ;
git pull origin ${src} ;
elif [ $# == 1 ] ; then
branch $1
git pull origin $1 ;
else
echo "usage: pull [BRANCH]" ;
fi ;
}