subrepoctl extension - control subrepository push behavior
This extension adds two alternative strategies for subrepository handling when hg push is issued in the parent repository.
The behavior is controlled by the setting pushsubrepos in the [ui] section. This setting is specified in the parent repository hgrc file, or through the other standard ways of setting configuration options (see hg help config).
One of the following values can be set for ui.pushsubrepos:
push This is the default, built-in Mercurial policy.
When hg push is issued in the parent repository, Mercurial first loops through each subrepository and attempts to push _any_ outgoing changes to the same repository where the the subrepository was originally pulled from (specified in the .hgsub file).
If pushing the subrepository fails (e.g. no push permission), the whole command is aborted.
This strategy tries to prevent pushing a parent repository state which can't be pulled by others because not all the subrepository contents are publicly available.
no_push Never push anything from the subrepositories.
When subrepositories are used to pull in read-only 3rd party dependencies, the standard strategy can be inefficient: it will always query the remote repositories which can be slow, especially with ssh connections and when there are multiple repositories involved.
If it is known that the subrepositories are not locally modified, the no_push strategy can be used to skip all subrepository checks.
Using no_push makes it possible to accidentally push a parent repository state which refers to subrepositories not available to others.
However, it is already possible to commit and push partial directory contents (e.g. forgetting to add a new file under version control) and make a project non-working for others. Fixing unavailable subrepository commits can be handled the same way as forgotted file additions, and should even be easier to spot.
abort_if_outgoing Abort push if outgoing changes are detected
Mercurial normally tries to push any outgoing changes it finds in a subrepository back to the repository where it was pulled from. This can be either useless (the user doesn't have push permission) or dangerous (the user has push permission).
In many cases development is done by pulling from an upstream repository and pushing to a fork so that new contributions can be reviewed and tested. Trying to push directly to the upstream repository is undesirable.
Using the abort_if_outgoing strategy, any locally committed modifications not present in the upstream will abort the operation. The user can then e.g. push those changes to a fork of the original repository, edit .hgsub to point there and try to push again.
Mercurial's default strategy seems to want to push any outgoing revisions, whether they have been snapshotted in the parent repository or not.
abort_if_outgoing stops the command only if the latest snapshotted subrepository revision is not present in the remote repository, even if there are other outgoing commits in the subrepository.
The ideal behavior would be to stop only if any of the snapshotted subrepository revisions are not in the remote repository. This is more complicated to implement and the current behavior is usually good enough, so the ideal implementation is postponed for now.
no commands defined