Jump to content

Incidents/2018-03-06 MasterMergedInWMFBranch

From Wikitech

Summary

During deployment of a patch for mediawiki/core@wmf/1.31.0-wmf.23, the deployer found out the difference between HEAD the origin/wmf/1.31.0-wmf.23 had too many commits. That prompted for an immediate halt.

The root cause has been determined to be the commit from master being sent for review to the wmf branch. In such a case, Gerrit will implicitly merge master into wmf branch. The Gerrit UI was not showing that and when the patch got merged the master branch made it to the wmf branch.

Timeline

  • Mar 05 - CR 416499 for mediawiki-core submitted and merged into the master branch
  • Mar 06 13:18 UTC - The change cherry-picked from the master branch to wmf/1.31.0-wmf.23 branch with CR 416675 and merged. Gerrit implicitly merged all the ancestors of the commit from master branch to wmf/1.31.0-wm.23 branch
  • Mar 06 13:18 UTC Attempt to deploy revealed that the diff is too big and deploy was halted.
  • Mar 06 14:46 UTC A revert of the erroneous commit created 416686 and merged, the state of gerrit returns back to normal.

Conclusions

  • Deployer followed the documentation (git diff HEAD..HEAD@{u}) and properly halted on the first oddity
  • Gerrit is being too helpful

The reason behind is:

Given a git tree such as:

A -- B -- C (master)
 \
  \-- X (wmf)

One is locally on the master branch and does a git push HEAD:refs/publish/wmf. Gerrit will create a new change Y that implicitly merge master into the wmf branch:

A -- B -- C (master)
 \            \
  \-- X (wmf)--\-- Z (new change)

The Gerrit GUI fails to reflect that the new change (Z) is a merge commit. One can tell though since the parent commit will be B from the master branch.

When Z is submitted the master branch ends up having been merged in wmf since B and C got already merged in master.

Gerrit 2.13 offers the option receive.rejectImplicitMerges to prevent that implict merge. From | Gerrit 2.13 release notes :

The ‘Reject Implicit Merges’ option can be enabled to prevent non-merge commits from implicitly bringing unwanted changes into a branch. This can happen for example when a commit is made based on one branch but is mistakenly pushed to another, for example based on refs/heads/master but pushed to refs/for/stable.


Actionables