#!/bin/sh # # Watches for merges that had only local merges (e.g. should have been rebases). # # If they are introducing non-merge commits /and/ merge commits, it could # look like one of two ways. This way: # # * --- B --- * --- oldrev # \ \ # new --- new --- newrev # # They basically had an un-shared local dev branch (probably by making a # merge) and instead should have done a rebase. Also, if they did: # # * --- B --- * --- oldrev # \ \ # new --- new --- new -- newrev # # We should try and catch them--where the merge happened previously to # them doing more work in the newrev commit. # # But if it looks like: # # * --- B --- * --- oldrev # \ \ # old --- new --- newrev # # Then they had a pre-shared branch that cannot be rebased and so they # were correct in doing a merge to tie "old" and "oldrev" together. # # Also, we obviously have to be okay with: # # * --- * --- * --- oldrev --- new --- new --- newrev refname="$1" oldrev="$2" newrev="$3" if expr "$oldrev" : '0*$' >/dev/null ; then exit 0 fi # Read backwards: all commits from old..new, unless they are already referenced by a branch git rev-parse --not --branches | git rev-list --stdin $oldrev..$newrev | while read commit ; do number_of_parents=$(git rev-list -n 1 --parents $commit | sed 's/ /\n/g' | grep -v $commit | wc -l) if [[ $number_of_parents > 1 ]] ; then # Hack to not interfer with the update-stable "--no-ff" method if [[ "$refname" == "refs/heads/stable" && "$commit" == "$newrev" ]] ; then exit 0 fi # Find the original branch point (B) parents=$(git rev-list -n 1 --parents $commit | sed 's/ /\n/g' | grep -v $commit) # For each baserev git merge-base --all $parents | while read baserev ; do # For each parent git rev-list -n 1 --parents $commit | sed 's/ /\n/g' | grep -v $commit | while read parent ; do all_commits=$(git rev-list --first-parent $baserev..$parent | wc -l) new_commits=$(git rev-parse --not --branches | git rev-list --stdin $baserev..$parent | wc -l) if [[ $all_commits -eq $new_commits ]] ; then echo "----------------------------------------------------" echo echo "It looks like you should rebase instead of merging $commit" echo echo "----------------------------------------------------" exit 1 fi done if [ $? -ne 0 ] ; then exit 1 fi done if [ $? -ne 0 ] ; then exit 1 fi fi done