|
|
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.
|
|
|
Subversion subrepositories are currently silently
|
|
|
ignored.
|
|
|
|
|
|
:addremove: addremove does not recurse into subrepos unless
|
|
|
-S/--subrepos is specified. However, if you specify the full
|
|
|
path of a directory in a subrepo, addremove will be performed on
|
|
|
it even without -S/--subrepos being specified. Git and
|
|
|
Subversion subrepositories will print a warning and continue.
|
|
|
|
|
|
:archive: archive does not recurse in subrepositories unless
|
|
|
-S/--subrepos is specified.
|
|
|
|
|
|
:cat: Git subrepositories only support exact file matches.
|
|
|
Subversion subrepositories are currently ignored.
|
|
|
|
|
|
: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. The --addremove
|
|
|
option also honors the -S/--subrepos option. However, Git and
|
|
|
Subversion subrepositories will print a warning and abort.
|
|
|
|
|
|
: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.
|
|
|
|
|
|
:files: files does not recurse into subrepos unless -S/--subrepos is
|
|
|
specified. However, if you specify the full path of a file or
|
|
|
directory in a subrepo, it will be displayed even without
|
|
|
-S/--subrepos being specified. 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.
|
|
|
|
|
|
:serve: serve does not recurse into subrepositories unless
|
|
|
-S/--subrepos is specified. Git and Subversion subrepositories
|
|
|
are currently silently ignored.
|
|
|
|
|
|
: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.
|
|
|
|
|
|
:remove: remove does not recurse into subrepositories unless
|
|
|
-S/--subrepos is specified. However, if you specify a file or
|
|
|
directory path in a subrepo, it will be removed even without
|
|
|
-S/--subrepos. Git and 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.
|
|
|
|
|
|
|