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.
        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: cat currently only handles exact file matches in subrepos.
        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.