Mercurial > hg
view mercurial/help/subrepos.txt @ 23923:ab6fd3205dad stable
largefiles: fix commit of a directory with no largefile changes (issue4330)
When a directory is named in the commit file list, the previous behavior was to
walk the list, and if no normal files in the directory were also named, add the
corresponding standin for each largefile in that directory. The directory is
then dropped from the list, so that committing a directory with no normal file
changes works. It then added the corresponding standin directory for the first
largefile seen, by prefixing it with '.hglf/'.
The latter is unnecessary since each affected largefile is explicitly referenced
by its standin in the list. It also caused an abort if there were no changed
largefiles in the directory, because none of its standins changed:
abort: .hglf/foo/bar: no match under directory!
This list of files is used to tweak a matcher in lfutil.updatestandinsbymatch(),
which is what is passed to commit().
The status() call that is ultimately done in the commit code with this matcher
seems to have some OS specific differences. It is not necessary to append '.'
for Windows to run the largefiles tests cleanly. But if '.' is not added to the
list, the match function isn't called on Linux, so status() would miss any
normal files that were also in a named directory. The commit then proceeds
without those normal files, or says "nothing changed" if there were no changed
largefiles in the directory. This is not filesystem specific, as VFAT on Linux
had the same behavior as when run on ext4. It is also not an issue with
lfilesrepo.status(), since that only calls the overridden implementation when
paths are passed to commit. I dont have access to an OS X machine ATM to test
there.
Maybe there's a better way to do this. But since the standin directory for the
first largefile was previously being added, and that caused the same walk in
status(), there's no preformance change to this. There is no danger of
erroneously committing files in '.', because the original match function is
called, and if it fails, the lfutil.updatestandinsbymatch() tweaked matcher only
indicates a match if the file is in the list of standins- and '.' never is. The
added tests confirm this.
author | Matt Harbison <matt_harbison@yahoo.com> |
---|---|
date | Sun, 18 Jan 2015 15:15:40 -0500 |
parents | cb42050f2dad |
children | 07c1a7d1ef69 |
line wrap: on
line source
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. :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. Git and 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. Git subrepositories do not support --include/--exclude. 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. :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.