--- a/hgext/overlay/__init__.py
+++ b/hgext/overlay/__init__.py
@@ -133,25 +133,29 @@ def _overlayrev(sourcerepo, sourceurl, s
memctx = context.memctx(destrepo, parents, sourcectx.description(),
files, filectxfn, user=sourcectx.user(),
date=sourcectx.date(), extra=extra)
return memctx.commit()
-def _dooverlay(sourcerepo, sourceurl, sourcerevs, destrepo, destctx, prefix):
+def _dooverlay(sourcerepo, sourceurl, sourcerevs, destrepo, destctx, prefix,
+ noncontiguous):
"""Overlay changesets from one repository into another.
``sourcerevs`` (iterable of revs) from ``sourcerepo`` will effectively
be replayed into ``destrepo`` on top of ``destctx``. File paths will be
added to the directory ``prefix``.
``sourcerevs`` may include revisions that have already been overlayed.
If so, overlay will resume at the first revision not yet processed.
+
+ ``noncontigous`` removes the restriction that sourcerevs must be a
+ contiguous DAG.
"""
assert prefix
prefix = prefix.rstrip('/') + '/'
ui = destrepo.ui
sourcerevs.sort()
@@ -160,18 +164,19 @@ def _dooverlay(sourcerepo, sourceurl, so
left.remove(sourcerevs.last())
for ctx in sourcerepo[sourcerevs.last()].ancestors():
if not left:
break
try:
left.remove(ctx.rev())
except KeyError:
- raise error.Abort(_('source revisions must be part of contiguous '
- 'DAG range'))
+ if not noncontiguous:
+ raise error.Abort(
+ _('source revisions must be part of contiguous DAG range'))
if left:
raise error.Abort(_('source revisions must be part of same DAG head'))
sourcerevs = list(sourcerevs)
sourcecl = sourcerepo.changelog
allsourcehexes = set(hex(sourcecl.node(rev)) for rev in
@@ -204,16 +209,17 @@ def _dooverlay(sourcerepo, sourceurl, so
(short(lastsourcectx.node()), short(ctx.node()),
idx, len(sourcerevs))))
sourcerevs = sourcerevs[idx:]
break
except ValueError:
# Else the changeset in the destination isn't in the incoming set.
# This is OK iff the destination changeset is a conversion of
# the parent of the first incoming changeset.
+ # TODO: This assumption doesn't hold with noncontiguous=True
firstsourcectx = sourcerepo[sourcerevs[0]]
if firstsourcectx.p1().hex() == overlayed:
break
raise error.Abort(_('first source changeset (%s) is not a child '
'of last overlayed changeset (%s)') % (
short(firstsourcectx.node()), short(bin(overlayed))))
@@ -282,34 +288,36 @@ def _mirrorrepo(ui, repo, url):
return mirrorrepo
@command('overlay', [
('d', 'dest', '', _('destination changeset on top of which to overlay '
'changesets')),
('', 'into', '', _('directory in destination in which to add files')),
+ ('', 'noncontiguous', False, _('allow non continuous dag heads')),
], _('[-d REV] SOURCEURL [REVS]'))
-def overlay(ui, repo, sourceurl, revs=None, dest=None, into=None):
+def overlay(ui, repo, sourceurl, revs=None, dest=None, into=None,
+ noncontiguous=False):
"""Integrate contents of another repository.
This command essentially replays changesets from another repository into
this one. Unlike a simple pull + rebase, the files from the remote
repository are "overlayed" or unioned with the contents of the destination
repository.
The functionality of this command is nearly identical to what ``hg
transplant`` provides. However, the internal mechanism varies
substantially.
There are currently several restrictions to what can be imported:
* The imported changesets must be in a single DAG head
* The imported changesets (as evaluated by ``REVS``) must be a contiguous
- DAG range.
+ DAG range (Unless --noncontiguous is passed).
* Importing merges is not supported.
* The state of the files in the destination directory/changeset must
exactly match the last imported changeset.
That last point is important: it means that this command can effectively
only be used for unidirectional syncing. In other words, the source
repository must be the single source of all changes to the destination
directory.
@@ -336,9 +344,10 @@ def overlay(ui, repo, sourceurl, revs=No
if dest:
destctx = repo[dest]
else:
destctx = repo['tip']
# Backdoor for testing to force static URL.
sourceurl = ui.config('overlay', 'sourceurl', sourceurl)
- _dooverlay(sourcerepo, sourceurl, sourcerevs, repo, destctx, into)
+ _dooverlay(sourcerepo, sourceurl, sourcerevs, repo, destctx, into,
+ noncontiguous)