overlay: change content checking in non-contiguous mode (
bug 1375966); r?smacleod
Before this change, non-contiguous mode compared content against the
last overlayed changeset. Since we're skipping changesets in
non-contiguous mode, this check would almost certainly fail. The
(current) goal in non-contiguous mode is to support backouts. The
skipped changeset will be a backout. The first parent of the first
changeset to be overlayed should be the backout. So, for non-contiguous
mode, we change the content check to be against the first parent.
This isn't a complete fix. If the first parent isn't the backout, then
the content check will fail. But this is presumed to be true most of
the time for the current Servo backout system. Perfect is the enemy of
good.
MozReview-Commit-ID: 79AHD6SYztA
--- a/hgext/overlay/__init__.py
+++ b/hgext/overlay/__init__.py
@@ -230,31 +230,42 @@ def _dooverlay(sourcerepo, sourceurl, so
# We don't (yet) support overlaying merge commits.
for rev in sourcerevs:
ctx = sourcerepo[rev]
if len(ctx.parents()) > 1:
raise error.Abort(_('do not support overlaying merges: %s') %
short(ctx.node()))
# If we previously performed an overlay, verify that changeset
- # continuity is uninterrupted. We ensure the parent of the first source
- # changeset matches the last imported changeset and that the state of
- # files in the last imported changeset matches exactly the state of files
- # in the destination changeset. If these conditions don't hold, the repos
- # got out of sync. If we continued, the first overlayed changeset would
- # have a diff that didn't match the source repository. In other words,
- # the history wouldn't be accurate. So prevent that from happening.
+ # continuity is uninterrupted.
+ #
+ # For the default mode of contiguous importing, we verify the last overlayed
+ # changeset is the first parent of the first changeset to be overlayed. We
+ # also verify that files in the destination match the last overlayed
+ # changeset.
+ #
+ # For non-contiguous operation, we skip the parent check because it doesn't
+ # make sense. For file comparisons, we check against the parent of the first
+ # incoming changeset rather than the last overlayed changeset.
+ #
+ # The file content check ensures that repos don't get out of sync. They
+ # ensure that diffs from the source repository match diffs in the
+ # destination repository.
if lastsourcectx:
- if (not noncontiguous and
- sourcerepo[sourcerevs[0]].p1() != lastsourcectx):
- raise error.Abort(_('parent of initial source changeset does not '
- 'match last overlayed changeset (%s)') %
- short(lastsourcectx.node()))
+ if not noncontiguous:
+ if sourcerepo[sourcerevs[0]].p1() != lastsourcectx:
+ raise error.Abort(_('parent of initial source changeset does '
+ 'not match last overlayed changeset (%s)') %
+ short(lastsourcectx.node()))
- _verifymanifestsequal(sourcerepo, lastsourcectx, destrepo, destctx,
+ comparectx = lastsourcectx
+ else:
+ comparectx = sourcerepo[sourcerevs[0]].p1()
+
+ _verifymanifestsequal(sourcerepo, comparectx, destrepo, destctx,
prefix)
# All the validation is done. Proceed with the data conversion.
with destrepo.lock():
with destrepo.transaction('overlay'):
for i, rev in enumerate(sourcerevs):
ui.progress(_('revisions'), i + 1, total=len(sourcerevs))
sourcectx = sourcerepo[rev]
--- a/hgext/overlay/tests/test-overlay-filtered-dag.t
+++ b/hgext/overlay/tests/test-overlay-filtered-dag.t
@@ -48,8 +48,38 @@ A non-contiguous dag range will fail to
Passing --noncontiguous should allow a non-contiguous dag range where some of
the commits have been filtered.
$ hg overlay http://localhost:$HGPORT1 'not keyword("FILTERED")' --into prefix --noncontiguous
af1e0a150cd4 -> 8e52bf8e668a: initial
eb87a779cc67 -> 452dcbcc9fb9: head 1 commit 1
38627e51950d -> ccc09fef5c59: head 1 commit 2
eebf284459b0 -> ed781cf9ab85: head 1 commit 4
+
+Incremental conversion with --noncontiguous works
+
+ $ cd ../repo0
+ $ echo 5 > foo
+ $ hg commit -m 'head 1 commit 5 FILTERED'
+ $ echo 6 > foo
+ $ hg commit -m 'head 1 commit 6'
+
+ $ cd ../dest
+
+ $ hg -q up tip
+
+ $ echo 5 > prefix/foo
+ $ hg commit -m 'out of band change simulating commit 5'
+
+ $ hg overlay http://localhost:$HGPORT1 'not desc("FILTERED")' --into prefix
+ pulling http://localhost:$HGPORT1 into $TESTTMP/dest/.hg/localhost~3a20123
+ searching for changes
+ adding changesets
+ adding manifests
+ adding file changes
+ added 2 changesets with 2 changes to 1 files
+ abort: source revisions must be part of contiguous DAG range
+ [255]
+
+ $ hg overlay http://localhost:$HGPORT1 'not desc("FILTERED")' --into prefix --noncontiguous
+ eebf284459b0 already processed as ed781cf9ab85; skipping 4/5 revisions
+ 8c4d7f24662e -> ee4ce23b43ca: head 1 commit 6
+