Prefer rebase. Nice.
[git-central.git] / server / pre-receive-prefer-rebase
1 #!/bin/sh
2
3 while read oldrev newrev refname ; do
4         if expr "$oldrev" : '0*$' >/dev/null ; then
5                 exit 0
6         fi
7
8         # If the new ref is a merge, it'll have spaces in the parents log (ugly, yes)
9         git log -n 1 --pretty=format:%p $newrev | grep " "
10         if [ $? -ne 0 ] ; then
11                 exit 0
12         fi
13
14         # If they are introducing non-merge commits /and/ merge commits, it could
15         # look like:
16         #
17         # * --- * --- * --- O
18         #        \           \
19         #         N --- N --- M
20         #
21         # They should have done a rebase.
22         #
23         # But if it looks like:
24         #
25         # * --- * --- * --- O
26         #        \           \
27         #         S --- N --- M
28         #
29         # Then they were correct in doing a merge as S was already shared.
30
31         baserev=$(git merge-base $oldrev $newrev)
32         base_to_old=$(git rev-list $baserev..$oldrev | wc -l)
33         base_to_new=$(git rev-list $baserev..$newrev | wc -l)
34         # includes the base_to_new includes both legs, so subtract to get new leg count
35         new_leg=$(expr $base_to_new - $base_to_old)
36         all_new=$(git rev-parse --not --branches | grep -v $(git rev-parse $refname) | git rev-list --stdin $oldrev..$newrev | wc -l)
37
38         # echo "new_leg=$new_leg"
39         # echo "all_new=$all_new"
40         if [ $all_new -eq $new_leg ] ; then
41                 echo "----------------------------------------------------"
42                 echo
43                 echo "It looks like you should rebase"
44                 echo
45                 echo "----------------------------------------------------"
46                 exit 1
47         fi
48 done
49