Subrepositories let you nest external repositories or projects into a
parent Mercurial repository, and make commands operate on them as a
group. External Mercurial and Subversion projects are currently
supported.
Subrepositories are made of three components:
1. Nested repository checkouts. They can appear anywhere in the
parent working directory, and are Mercurial clones or Subversion
checkouts.
2. Nested repository references. They are defined in ``.hgsub`` and
tell where the subrepository checkouts come from. Mercurial
subrepositories are referenced like:
path/to/nested = https://example.com/nested/repo/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. Subversion repositories are defined with:
path/to/nested = [svn]https://example.com/nested/trunk/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`` 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 subrepo from the parent repository, delete its reference
from ``.hgsub``. Then, the subrepo tree will show up as a set of
unknown files in :hg:`status`, and you can delete the files.
Interaction with Mercurial Commands
-----------------------------------
:add: add does not recurse in subrepos unless -S/--subrepos is
specified. 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. It does this by first
attempting to commit all modified subrepositories, then recording
their state and finally committing 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. Subversion subrepositories are currently silently
ignored.
:incoming: incoming does not recurse in subrepos unless -S/--subrepos
is specified. Subversion subrepositories are currently silently
ignored.
:outgoing: outgoing does not recurse in subrepos unless -S/--subrepos
is specified. 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.
: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.