Help: subrepos
Subrepositories
Subrepositories let you nest external repositories or projects into a
parent Mercurial repository, and make commands operate on them as a group.
Mercurial currently supports Mercurial, Git, and Subversion
subrepositories.
Subrepositories are made of three components:
1. Nested repository checkouts. They can appear anywhere in the parent
working directory.
2. Nested repository references. They are defined in ".hgsub", which
should be placed in the root of working directory, and tell where the
subrepository checkouts come from. Mercurial subrepositories are
referenced like:
path/to/nested = https://example.com/nested/repo/path
Git and Subversion subrepos are also supported:
path/to/nested = [git]git://example.com/nested/repo/path
path/to/nested = [svn]https://example.com/nested/trunk/path
where "path/to/nested" is the checkout location relatively to the
parent Mercurial root, and "https://example.com/nested/repo/path" is
the source repository path. The source can also reference a filesystem
path.
Note that ".hgsub" does not exist by default in Mercurial repositories,
you have to create and add it to the parent repository before using
subrepositories.
3. Nested repository states. They are defined in ".hgsubstate", which is
placed in the root of working directory, and capture whatever
information is required to restore the subrepositories to the state
they were committed in a parent repository changeset. Mercurial
automatically record the nested repositories states when committing in
the parent repository.
Note:
The ".hgsubstate" file should not be edited manually.
Adding a Subrepository
----------------------
If ".hgsub" does not exist, create it and add it to the parent repository.
Clone or checkout the external projects where you want it to live in the
parent repository. Edit ".hgsub" and add the subrepository entry as
described above. At this point, the subrepository is tracked and the next
commit will record its state in ".hgsubstate" and bind it to the committed
changeset.
Synchronizing a Subrepository
-----------------------------
Subrepos do not automatically track the latest changeset of their sources.
Instead, they are updated to the changeset that corresponds with the
changeset checked out in the top-level changeset. This is so developers
always get a consistent set of compatible code and libraries when they
update.
Thus, updating subrepos is a manual process. Simply check out target
subrepo at the desired revision, test in the top-level repo, then commit
in the parent repository to record the new combination.
Deleting a Subrepository
------------------------
To remove a subrepository from the parent repository, delete its reference
from ".hgsub", then remove its files.
Interaction with Mercurial Commands
-----------------------------------
add add does not recurse in subrepos unless -S/--subrepos is
specified. However, if you specify the full path of a file
in a subrepo, it will be added even without -S/--subrepos
specified. Git and Subversion subrepositories are currently
silently ignored.
archive archive does not recurse in subrepositories unless
-S/--subrepos is specified.
commit commit creates a consistent snapshot of the state of the
entire project and its subrepositories. If any
subrepositories have been modified, Mercurial will abort.
Mercurial can be made to instead commit all modified
subrepositories by specifying -S/--subrepos, or setting
"ui.commitsubrepos=True" in a configuration file (see "hg
help config"). After there are no longer any modified
subrepositories, it records their state and finally commits
it in the parent repository.
diff diff does not recurse in subrepos unless -S/--subrepos is
specified. Changes are displayed as usual, on the
subrepositories elements. Git and Subversion subrepositories
are currently silently ignored.
forget forget currently only handles exact file matches in
subrepos. Git and Subversion subrepositories are currently
silently ignored.
incoming incoming does not recurse in subrepos unless -S/--subrepos
is specified. Git and Subversion subrepositories are
currently silently ignored.
outgoing outgoing does not recurse in subrepos unless -S/--subrepos
is specified. Git and Subversion subrepositories are
currently silently ignored.
pull pull is not recursive since it is not clear what to pull
prior to running "hg update". Listing and retrieving all
subrepositories changes referenced by the parent repository
pulled changesets is expensive at best, impossible in the
Subversion case.
push Mercurial will automatically push all subrepositories first
when the parent repository is being pushed. This ensures new
subrepository changes are available when referenced by top-
level repositories. Push is a no-op for Subversion
subrepositories.
status status does not recurse into subrepositories unless
-S/--subrepos is specified. Subrepository changes are
displayed as regular Mercurial changes on the subrepository
elements. Subversion subrepositories are currently silently
ignored.
update update restores the subrepos in the state they were
originally committed in target changeset. If the recorded
changeset is not available in the current subrepository,
Mercurial will pull it in first before updating. This means
that updating can require network access when using
subrepositories.
Remapping Subrepositories Sources
---------------------------------
A subrepository source location may change during a project life,
invalidating references stored in the parent repository history. To fix
this, rewriting rules can be defined in parent repository "hgrc" file or
in Mercurial configuration. See the "[subpaths]" section in hgrc(5) for
more details.