4 # This enforces stable moving in approved ways.
8 # * stable must move by only 1 commit-per-push
9 # * the stable commit must have 2 and only 2 parents
10 # * The first parent must be the previous stable commit
11 # * The second parent is the tip of the candidate branch being released
12 # * the stable commit must have the same contents as the candidate tip
13 # * Any merge conflicts should have been resolved in the candidate tip
14 # by pulling stable into the candidate and having qa/tests done--pulling
15 # candidate into stable should then apply cleanly
17 # For DAG aesthetics, we prefer stable only moving in the approved way,
18 # which is via empty (no change) merge commits. The rationale is that
19 # in the DAG we want a simple, one-commit move from each release to the
22 # We started out with:
26 # \ * -- * -- B topic1
30 # And then publishing stable was a matter of fast-forwarding
33 # In a complicated (non-rebased) DAG, this becomes hard to follow,
34 # so want we want instead is:
36 # * -- A ----------- C stable
38 # \ * -- * -- B topic1
42 # Where commit C lists as it's first parent the prior stable
43 # commit and as it's second parent the release candidate. No
44 # other parents are allowed (e.g. no octopus merges here, which
45 # would insinuate qa didn't happen on the merged result).
47 # Also, we want to enforce that C does not actually introduce
48 # any diffs to the files between B and C--as they would be changes
49 # that QA does not see.
52 . $(dirname $0)/functions
60 short_refname=${refname##refs/heads/}
68 if [ "$change_type" == "delete" ] ; then
72 # create/delete is okay
73 if [ "$change_type" != "update" ] ; then
77 if [ "$short_refname" == "stable" ] ; then
81 # - all commits from old..new
82 # - unless they were already pointed to by a branch
83 # = all new commits on stable
84 count=$(git rev-parse --not --branches | git rev-list --stdin $oldrev..$newrev | wc -l)
85 if [ "$count" -ne "1" ] ; then
86 display_error_message "Moving stable must entail a single commit"
90 number_of_parents=$(git rev-list --no-walk --parents $newrev | sed 's/ /\n/g' | grep -v $newrev | wc -l)
91 if [ "$number_of_parents" -ne "2" ] ; then
92 display_error_message "Moving stable must entail a merge commit"
96 first_parent=$(git rev-list --no-walk --parents $newrev | sed 's/ /\n/g' | grep -v $newrev | head --lines=1)
97 if [ "$first_parent" != "$oldrev" ] ; then
98 display_error_message "Moving stable must have the previous stable as the first parent"
102 second_parent=$(git rev-list --no-walk --parents $newrev | sed 's/ /\n/g' | grep -v $newrev | tail --lines=1)
103 changed_lines=$(git diff $second_parent..$newrev | wc -l)
104 if [ "$changed_lines" -ne "0" ] ; then
105 display_error_message "Moving stable must not result in any changes from $second_parent"