I have numerous projects with subrepositories:
/project <- Main repository
/project/src <- Source code subrepository (subrepository to /project)
/project/src/module <- Module subrepository (subrepository to /project/src repository)
I've now worked on a feature branch (feature1) which has had a few revisions, which I'd now like to merge back into the default branch. The default branch hasn't had any changes since the feature1 branch was created.
I've tried merging the branch to default however end up with some strange things happening in the subrepositories.
I've followed the instructions in this other post, and get the following results:
$ hg checkout default
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg merge feature1
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
$ hg status -S
M .hgsubstate
$ hg commit -S -m "branch merge test"
nothing changed
$ hg branches
default 19:c2398dc23428
feature1 17:98dc0efbad90 (inactive)
What's strange is that even though many files were changed in the module subrepository, the merge only stated that 1 file was updated. I'm assuming that this happens to be the .hgsubstate.
When I explicitly update the subrepository, then I get the following:
$ cd src/module
$ hg update
39 files updated, 0 files merged, 23 files removed, 0 files unresolved
$ cd ../..
$ hg commit -S -m "feature1 merge"
committing subrepository src
$ hg status -S
M .hgsubstate
So after doing a hg update to bring all the changes into the working directory, I see the changes in the module subrepository that I need to commit. However, .hgsubstate always remains in the modified state. I've tried hg remove. I've tried hg forget. But no matter what I do, it still is marked when I do a hg status.
So my questions are:
You don't say which version of hg you are using - subrepo support has changed a certain amount over time. I've just tried something like your test with 3 subrepo levels in hg v2.8 and it works for me.
When you got a dirty .hgsubstate at the top level, that is normal when you commit a subrepo. [If only a subrepo has been committed independently, only the .hgsubstate will be dirty at the top level.] If you then go up to the top level and commit at that level the .hgsubstate will be committed, and everything is fine. Remember, the top level repo tracks subrepos in a similar fashion to files - it commits a particular changeset from the subrepo at each top level commit.
FWIW. The recommended practice is to commit subrepos separately, i.e. avoid committing at the top level if the subrepos are dirty. The reason is that the subrepos often require a different commit message - they are subrepos for a reason after all; but you can commit at the top level if you wish. In your case with 3 levels the sequence would be:
cd src/module
hg commit -m "src/module commit reason"
cd ..
hg commit -m "src commit reason"
cd ..
hg commit -m "top level reason"
It was intended that subrepos would change infrequently, e.g. third party libraries. If your subrepos are going to change frequently, you and your team will have to be vigilant to avoid mistakes, especially when merging with other peoples work. [But given the date of the question you've probably worked that out yourself by now.]