[PATCH 5 of 8] convert: track files and copies for revisions that were filtered out
Yury Sulsky
yury.sulsky at gmail.com
Mon Nov 28 00:26:01 CST 2011
# HG changeset patch
# User Yury Sulsky <yury.sulsky at gmail.com>
# Date 1322459840 18000
# Node ID 2325d1fa02ac96bc8d4a31eab98ee736edc0f501
# Parent ca6bd3a18621286746cc7a83f23f871d49c8ed62
convert: track files and copies for revisions that were filtered out
diff -r ca6bd3a18621 -r 2325d1fa02ac hgext/convert/filtermap.py
--- a/hgext/convert/filtermap.py Mon Nov 28 00:51:10 2011 -0500
+++ b/hgext/convert/filtermap.py Mon Nov 28 00:57:20 2011 -0500
@@ -23,7 +23,7 @@
"""Return True if we want to keep this revision"""
return True
- def __init__(self, ui, baseconverter):
+ def __init__(self, ui, baseconverter, trackchanges):
super(filtermap_base, self).__init__(ui)
self.base = baseconverter
self.commits = {}
@@ -38,6 +38,8 @@
self.origparents = {}
self.children = {}
self.seenchildren = {}
+ self.skippedchanges = {}
+ self.trackingchanges = trackchanges
def before(self):
self.base.before()
@@ -51,7 +53,7 @@
# To avoid calling getcommit for every revision that has already
# been converted, we rebuild only the parentmap, delaying the
# rebuild of wantedancestors until we need it (i.e. until a
- # merge).
+ # merge or if we are tracking changes).
#
# We assume the order argument lists the revisions in
# topological order, so that we can infer which revisions were
@@ -83,6 +85,7 @@
self.parentmap.clear()
self.wantedancestors.clear()
self.seenchildren.clear()
+ self.skippedchanges.clear()
for rev, wanted, arg in self.convertedorder:
if rev not in self.origparents:
self.origparents[rev] = self.getcommit(rev).parents
@@ -124,12 +127,40 @@
del self.wantedancestors[r]
del self.parentmap[r]
del self.seenchildren[r]
+ if self.trackingchanges:
+ del self.skippedchanges[r]
if self._rebuilt:
del self.children[r]
+ def _trackedchanges(self, rev, parents):
+ changes = self.base.getchanges(rev)
+ if not self.trackingchanges or not parents:
+ return changes
+
+ files, copies = set(), {}
+ # The case of a convergent copy takes care of itself because
+ # the destination file should be present in the merge node's
+ # list of changed files
+ for p in parents:
+ pf, pc = self.skippedchanges[p]
+ copies.update(pc)
+ files.update([(f, rev) for (f, prev) in pf])
+
+ cf, cc = changes
+ copies.update(cc); files.update(cf)
+
+ for dest in copies:
+ if dest in files:
+ del copies[dest]
+
+ return files, copies
+
def mark_not_wanted(self, rev, p):
# Mark rev as not interesting and update data structures.
+ if self.trackingchanges:
+ self.skippedchanges[rev] = self._trackedchanges(rev, p and [p])
+
if p is None:
# A root revision. Use SKIPREV to indicate that it doesn't
# map to any revision in the restricted graph. Put SKIPREV
@@ -145,6 +176,9 @@
def mark_wanted(self, rev, parents):
# Mark rev ss wanted and update data structures.
+ if self.trackingchanges:
+ self.skippedchanges[rev] = [], {}
+
# rev will be in the restricted graph, so children of rev in
# the original graph should still have rev as a parent in the
# restricted graph.
@@ -160,7 +194,7 @@
def getchanges(self, rev):
parents = self.commits[rev].parents
- if len(parents) > 1:
+ if len(parents) > 1 or self.trackingchanges:
self.rebuild()
# To decide whether we're interested in rev we:
@@ -223,7 +257,7 @@
self.mark_wanted(rev, parents)
self.convertedorder.append((rev, True, None))
- files, copies = self.base.getchanges(rev)
+ files, copies = self._trackedchanges(rev, parents)
# Flatten copies if this is a root node
if copies and not mparents:
@@ -266,7 +300,11 @@
class filtermap_source(filtermap_base):
def __init__(self, ui, base, filemap):
- super(filtermap_source, self).__init__(ui, base)
+ # If we only filter by files, there's no need to track
+ # changes. Revisions are only removed if they don't touch
+ # files that we care about.
+ trackchanges = False
+ super(filtermap_source, self).__init__(ui, base, trackchanges)
self.filemapper = filemapper(ui, filemap)
def wanted(self, rev, i):
More information about the Mercurial-devel
mailing list