In our project, we have a develop branch. We have half a dozen developers who are free to push to develop, but we've asked them to rebase their feature branches on top of the develop before they do the merge. Occasionally, people forget to do this and it creates an uglier merge history on develop.
Is there a config setting in git, or a setting in gitlab that we can use to prevent merges that are not fast forward merges? Ideally, we'd like a policy in GitLab that can turn on/off on the remote server, so we can turn this off globally.
First of all, the usual configuration is for the server to only accept fast forward merges (unless overridden by -f). But I'm assuming your case is where people have their own feature branch, then merge develop into that and then push develop, so now the history has that merge commit.
On the server, you can set up a git update hook. The update hook will be run once per branch and receive arguments of the branch name, the tip of the new commit being pushed and the tip of the branch onto which to add the new commits (i.e., the origin/branchName). The return value of the script indicates whether to reject or accept the commit. You can simply check if there are any merge commits in between these two commits.
#!/bin/sh
# .git/hooks/update
refname="$1"
oldrev="$2"
newrev="$3"
numMergeCommits=$(git rev-list --count --merges $oldrev..$newrev)
if [ $numMergeCommits -gt 0 ]; then
echo "Rejected - pushed branch must not contain any merges"
exit 1
fi
exit 0
Note that this can't be overridden with the -f flag as well. Also, the text that is in that echo "Rejected..." statement is echoed back to the remote pusher, so you can put a more descriptive message there, hopefully with a link to a wiki page showing them how to rework their branch using rebase to get the commit into the proper form.