diff hgext/convert/hg.py @ 7231:8e7130a10f3b

convert: ignore hg source errors with hg.ignoreerrors (issue 1357) This flag makes missing revlog errors to be ignored which allow broken repositories to be fixed by converting them from and to Mercurial.
author Patrick Mezard <pmezard@gmail.com>
date Tue, 21 Oct 2008 21:24:47 +0200
parents 12472a240398
children c2ac09f81ec9
line wrap: on
line diff
--- a/hgext/convert/hg.py	Thu Oct 23 14:56:16 2008 -0500
+++ b/hgext/convert/hg.py	Tue Oct 21 21:24:47 2008 +0200
@@ -192,6 +192,8 @@
 class mercurial_source(converter_source):
     def __init__(self, ui, path, rev=None):
         converter_source.__init__(self, ui, path, rev)
+        self.ignoreerrors = ui.configbool('convert', 'hg.ignoreerrors', False)
+        self.ignored = {}
         self.saverev = ui.configbool('convert', 'hg.saverev', True)
         try:
             self.repo = hg.repository(self.ui, path)
@@ -253,23 +255,35 @@
         parents = self.parents(ctx)
         if not parents:
             files = util.sort(ctx.manifest().keys())
-            return [(f, rev) for f in files], {}
+            return [(f, rev) for f in files if f not in self.ignored], {}
         if self._changescache and self._changescache[0] == rev:
             m, a, r = self._changescache[1]
         else:
             m, a, r = self.repo.status(parents[0], ctx.node())[:3]
-        changes = [(name, rev) for name in m + a + r]
-        return util.sort(changes), self.getcopies(ctx, m + a)
+        # getcopies() detects missing revlogs early, run it before
+        # filtering the changes.
+        copies = self.getcopies(ctx, m + a)
+        changes = [(name, rev) for name in m + a + r 
+                   if name not in self.ignored]
+        return util.sort(changes), copies
 
     def getcopies(self, ctx, files):
         copies = {}
         for name in files:
+            if name in self.ignored:
+                continue
             try:
-                copynode = ctx.filectx(name).renamed()[0]
-                if self.keep(copynode):
-                    copies[name] = copynode
+                copysource, copynode = ctx.filectx(name).renamed()
+                if copysource in self.ignored or not self.keep(copynode):
+                    continue
+                copies[name] = copysource
             except TypeError:
                 pass
+            except revlog.LookupError, e:
+                if not self.ignoreerrors:
+                    raise
+                self.ignored[name] = 1
+                self.ui.warn(_('ignoring: %s\n') % e)
         return copies
 
     def getcommit(self, rev):
@@ -297,6 +311,7 @@
         else:
             i = i or 0
             changes = self.repo.status(parents[i], ctx.node())[:3]
+        changes = [[f for f in l if f not in self.ignored] for l in changes]
 
         if i == 0:
             self._changescache = (rev, changes)