(This is the first of several shorter blog posts about features in the new vcs sync process.)
Back when the vcs sync project was first dropped in my lap, I quickly decided the initial implementation was going to push to a local repo. On disk, not on a network server. This has the nice properties of
- ruling out any server-permission- or network- related issues,
- allowing for development without an active network connection,
- speeding up the testing process to a small degree,
- and allowing for immediate inspection of the pushed repo's contents.
I named this a
test_push, though I'm waffling on that name.
When it became clearer that non-fastforward pushes and deletions would be an issue for downstream partners, we were looking for ways to prevent that.
Ideally we prevent this at the RoR (repository of record), with pre-commit hooks. However, not all of our upstream repos have pre-commit hooks (see github), so this can't be a blanket solution. (I think our single-head hook on our release branches catches a lot of this, but there might be more we can do on hg.m.o).
Next, it would be good to have these denied at the partner repository level (we've done this on gecko.git and gaia.git). This is less ideal than the pre-commit hook, because a deletion or non-fast-forward commit can land upstream, and then the sync process has nowhere to go. Also, this is the last place we can catch this issue -- if this is set incorrectly, or missed, or if others have administrative rights to the repo and unset this, then we're in a bad position. (
hg debugsetparents can fix non-fastforward commits. I don't know how to recover from deletions, other than track that revision down somewhere and re-push; luckily deletions look to be difficult to do in mercurial.)
I finally decided to add
receive.denyNonFastForwards to the local
test_push repo, via the
--shared=true option in
git init. If the
test_push happens before any network pushes, and
test_push failure prevents any network pushes for that branch, we get another layer of safety. It's still not as good a solution as preventing that change in the first place, but it's something we can control locally.
It looks like I'm missing
receive.denyDeletes from the
test_push... I added that to my development branch so we get that check in each
test_push soon as well.