# HG changeset patch # User Edouard Gomez # Date 2009-01-04 01:36:48 # Node ID 075b7ef0f84d70b13e4fe6e1ef9e679fa079f91f # Parent 28563e94c47107b3bfdf03e019dcd015bd05d7a2 convert/gnuarch: follow continuation-of revisions Built on top of previous patches: - continuation-of parsing - registered archives retrieval - use of fully qualified revisions This allows the converter scanning for more source revisions following the tree versions 'leaked' through the continuation-of informations. Coupled with the registered archives retrieval, this makes possible to decide to follow such a hint or stop scanning for more revisions. This also implies some changes in the retrieval of some base-0 revisions when they're continuation-of other revisions, in that case a 'replay' will work where a simple 'get' fails because the dir exists already. I found the code dealing with 'replay' quite good as it has already a fallback to 'get' in the error path. diff --git a/hgext/convert/gnuarch.py b/hgext/convert/gnuarch.py --- a/hgext/convert/gnuarch.py +++ b/hgext/convert/gnuarch.py @@ -63,32 +63,59 @@ class gnuarch_source(converter_source, c output = self.run0('tree-version', '-d', self.path) self.treeversion = output.strip() - self.ui.status(_('analyzing tree version %s...\n') % self.treeversion) - # Get name of temporary directory version = self.treeversion.split('/') self.tmppath = os.path.join(tempfile.gettempdir(), 'hg-%s' % version[1]) # Generate parents dictionary - child = [] - output, status = self.runlines('revisions', '-f', self.treeversion) - self.checkexit(status, 'archive registered?') - for l in output: - rev = l.strip() - self.changes[rev] = self.gnuarch_rev(rev) + self.parents[None] = [] + treeversion = self.treeversion + child = None + while treeversion: + self.ui.status(_('analyzing tree version %s...\n') % treeversion) + + archive = treeversion.split('/')[0] + if archive not in self.archives: + self.ui.status(_('tree analysis stopped because it points to an unregistered archive %s...\n') % archive) + break + + # Get the complete list of revisions for that tree version + output, status = self.runlines('revisions', '-r', '-f', treeversion) + self.checkexit(status, 'failed retrieveing revisions for %s' % treeversion) + + # No new iteration unless a revision has a continuation-of header + treeversion = None + + for l in output: + rev = l.strip() + self.changes[rev] = self.gnuarch_rev(rev) + self.parents[rev] = [] - # Read author, date and summary - catlog, status = self.run('cat-log', '-d', self.path, rev) - if status: - catlog = self.run0('cat-archive-log', rev) - self._parsecatlog(catlog, rev) + # Read author, date and summary + catlog, status = self.run('cat-log', '-d', self.path, rev) + if status: + catlog = self.run0('cat-archive-log', rev) + self._parsecatlog(catlog, rev) + + # Populate the parents map + self.parents[child].append(rev) - self.parents[rev] = child - child = [rev] - if rev == self.rev: - break - self.parents[None] = child + # Keep track of the current revision as the child of the next + # revision scanned + child = rev + + # Check if we have to follow the usual incremental history + # or if we have to 'jump' to a different treeversion given + # by the continuation-of header. + if self.changes[rev].continuationof: + treeversion = '--'.join(self.changes[rev].continuationof.split('--')[:-1]) + break + + # If we reached a base-0 revision w/o any continuation-of + # header, it means the tree history ends here. + if rev[-6:] == 'base-0': + break def after(self): self.ui.debug(_('cleaning up %s\n') % self.tmppath) @@ -162,23 +189,19 @@ class gnuarch_source(converter_source, c return os.system(cmdline) def _update(self, rev): - if rev[-6:] == 'base-0': - # Initialise 'base-0' revision + self.ui.debug(_('applying revision %s...\n') % rev) + changeset, status = self.runlines('replay', '-d', self.tmppath, + rev) + if status: + # Something went wrong while merging (baz or tla + # issue?), get latest revision and try from there + shutil.rmtree(self.tmppath, ignore_errors=True) self._obtainrevision(rev) else: - self.ui.debug(_('applying revision %s...\n') % rev) - changeset, status = self.runlines('replay', '-d', self.tmppath, - rev) - if status: - # Something went wrong while merging (baz or tla - # issue?), get latest revision and try from there - shutil.rmtree(self.tmppath, ignore_errors=True) - self._obtainrevision(rev) - else: - old_rev = self.parents[rev][0] - self.ui.debug(_('computing changeset between %s and %s...\n') - % (old_rev, rev)) - self._parsechangeset(changeset, rev) + old_rev = self.parents[rev][0] + self.ui.debug(_('computing changeset between %s and %s...\n') + % (old_rev, rev)) + self._parsechangeset(changeset, rev) def _getfile(self, name, rev): mode = os.lstat(os.path.join(self.tmppath, name)).st_mode