convert: add a mode where mercurial_sink skips empty revisions.
The getchanges function of some converter_source classes can return
some false positives. I.e. they sometimes claim that a file "foo"
was changed in some revision, even though its contents are still the
same.
convert_svn is particularly bad, but I think this can also happen with
convert_cvs and, at least in theory, with mercurial_source.
For regular conversions this is not really a problem - as long as
getfile returns the right contents, we'll get a converted revision
with the right contents. But when we use --filemap, this could lead
to superfluous revisions being converted.
Instead of fixing every converter_source, I decided to change
mercurial_sink to work around this problem.
When --filemap is used, we're interested only in revisions that touch
some specific files. If a revision doesn't change any of these files,
then we're not interested in it (at least for revisions with a single
parent; merges are special).
For mercurial_sink, we abuse this property and rollback a commit if
the manifest text hasn't changed. This avoids duplicating the logic
from localrepo.filecommit to detect unchanged files.
--- a/hgext/convert/__init__.py Thu Oct 04 23:21:37 2007 -0300
+++ b/hgext/convert/__init__.py Thu Oct 04 23:21:37 2007 -0300
@@ -382,6 +382,7 @@
fmap = opts.get('filemap')
if fmap:
srcc = filemap.filemap_source(ui, srcc, fmap)
+ destc.setfilemapmode(True)
if not revmapfile:
try:
--- a/hgext/convert/common.py Thu Oct 04 23:21:37 2007 -0300
+++ b/hgext/convert/common.py Thu Oct 04 23:21:37 2007 -0300
@@ -167,3 +167,13 @@
pbranch: branch name of parent commit
parents: destination revisions of parent"""
pass
+
+ def setfilemapmode(self, active):
+ """Tell the destination that we're using a filemap
+
+ Some converter_sources (svn in particular) can claim that a file
+ was changed in a revision, even if there was no change. This method
+ tells the destination that we're using a filemap and that it should
+ filter empty revisions.
+ """
+ pass
--- a/hgext/convert/hg.py Thu Oct 04 23:21:37 2007 -0300
+++ b/hgext/convert/hg.py Thu Oct 04 23:21:37 2007 -0300
@@ -28,6 +28,7 @@
raise NoRepo("could not open hg repo %s as sink" % path)
self.lock = None
self.wlock = None
+ self.filemapmode = False
def before(self):
self.wlock = self.repo.wlock()
@@ -96,6 +97,10 @@
pl.append(p)
seen[p] = 1
parents = pl
+ nparents = len(parents)
+ if self.filemapmode and nparents == 1:
+ m1node = self.repo.changelog.read(bin(parents[0]))[0]
+ parent = parents[0]
if len(parents) < 2: parents.append("0" * 40)
if len(parents) < 2: parents.append("0" * 40)
@@ -117,6 +122,13 @@
text = "(octopus merge fixup)\n"
p2 = hg.hex(self.repo.changelog.tip())
+ if self.filemapmode and nparents == 1:
+ man = self.repo.manifest
+ mnode = self.repo.changelog.read(bin(p2))[0]
+ if not man.cmp(m1node, man.revision(mnode)):
+ self.repo.rollback()
+ self.repo.dirstate.clear()
+ return parent
return p2
def puttags(self, tags):
@@ -153,6 +165,9 @@
date, tagparent, nullid)
return hex(self.repo.changelog.tip())
+ def setfilemapmode(self, active):
+ self.filemapmode = active
+
class mercurial_source(converter_source):
def __init__(self, ui, path, rev=None):
converter_source.__init__(self, ui, path, rev)