I work on a team where we have a code in a mercurial repository with several subrepositories:
main/
main/subrepo1/
main/subrepo1/subrepo2/
The default behavior of Mercurial is that when a hg commit
is performed in "main", any outstanding changes in the subrepositories "subrepo1" and "subrepo2" will also be committed. Similarly, when "main" is pushed, any outgoing commits in "subrepo1" and "subrepo2" will also be pushed.
We find that people frequently inadvertently commit and push changes in their subrepositories (because they forgot they had made changes, and hg status
by default does not show recursive changes). We also find that such global commits / pushes are almost always accidental in our team.
Mercurial 1.7 recently improved the situation with hg status -S
and hg outgoing -S
, which show changes in subrepositories; but still, this requires people to be paying attention.
Is there a way in Mercurial to make hg commit
and hg push
abort if there are changes/commits in subrepostories that would otherwise be committed/pushed?
Mercurial 2.0 automatically prevents you from committing subrepositories unless you manually specify the --subrepos
(or, alternatively, -S
) argument to commit
.
For example, you try to perform a commit while there are pending changes in a subrepository, you get the following message:
# hg commit -m 'change main repo'
abort: uncommitted changes in subrepo hello
(use --subrepos for recursive commit)
You can successfully perform the commit, however, by adding --subrepos
to the command:
# hg commit --subrepos -m 'commit subrepos'
committing subrepository hello
Some things to still be careful about: If you have changed the revision a subrepository is currently at, but not the contents of the subrepository, Mercurial will happily commit the version change without the --subrepos
flag. Further, recursive pushes are still performed without warning.
Since Mercurial 1.8 there is a configuration setting that disables recursive commits. In the parent repositories .hg/hgrc
you can add:
[ui]
commitsubrepos = no
If a commit in the parent repository finds uncommitted changes in a subrepository the whole commit is aborted, instead of silently committing the subrepositories.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With