changeset 7587:766d9cf58b3f

merge with crew
author Benoit Boissinot <benoit.boissinot@ens-lyon.org>
date Sun, 04 Jan 2009 13:52:28 +0100
parents e9d3a11eacad (diff) f9784c425a96 (current diff)
children 489c2cfbdd71
files
diffstat 4 files changed, 87 insertions(+), 53 deletions(-) [+]
line wrap: on
line diff
--- a/hgext/convert/gnuarch.py	Sat Jan 03 21:54:58 2009 +0100
+++ b/hgext/convert/gnuarch.py	Sun Jan 04 13:52:28 2009 +0100
@@ -3,7 +3,8 @@
 from common import NoRepo, commandline, commit, converter_source
 from mercurial.i18n import _
 from mercurial import util
-import os, shutil, tempfile, stat
+import os, shutil, tempfile, stat, locale
+from email.Parser import Parser
 
 class gnuarch_source(converter_source, commandline):
 
@@ -13,6 +14,7 @@
             self.summary = ''
             self.date = None
             self.author = ''
+            self.continuationof = None
             self.add_files = []
             self.mod_files = []
             self.del_files = []
@@ -46,38 +48,74 @@
         self.parents = {}
         self.tags = {}
         self.modecache = {}
+        self.catlogparser = Parser()
+        self.locale = locale.getpreferredencoding()
+        self.archives = []
 
     def before(self):
+        # Get registered archives
+        self.archives = [i.rstrip('\n')
+                         for i in self.runlines0('archives', '-n')]
+
         if self.execmd == 'tla':
             output = self.run0('tree-version', self.path)
         else:
             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', 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 = self.runlines0('cat-log', '-d', self.path, 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)
@@ -136,7 +174,7 @@
     def getcommit(self, rev):
         changes = self.changes[rev]
         return commit(author = changes.author, date = changes.date,
-                      desc = changes.summary, parents = self.parents[rev])
+                      desc = changes.summary, parents = self.parents[rev], rev=rev)
 
     def gettags(self):
         return self.tags
@@ -151,26 +189,19 @@
         return os.system(cmdline)
 
     def _update(self, rev):
-        if rev == '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)
-            revision = '%s--%s' % (self.treeversion, rev)
-            changeset, status = self.runlines('replay', '-d', self.tmppath,
-                                              revision)
-            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))
-                rev_a = '%s--%s' % (self.treeversion, old_rev)
-                rev_b = '%s--%s' % (self.treeversion, 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
@@ -218,8 +249,7 @@
 
     def _obtainrevision(self, rev):
         self.ui.debug(_('obtaining revision %s...\n') % rev)
-        revision = '%s--%s' % (self.treeversion, rev)
-        output = self._execute('get', revision, self.tmppath)
+        output = self._execute('get', rev, self.tmppath)
         self.checkexit(output)
         self.ui.debug(_('analysing revision %s...\n') % rev)
         files = self._readcontents(self.tmppath)
@@ -231,20 +261,17 @@
         return path
 
     def _parsecatlog(self, data, rev):
-        summary = []
-        for l in data:
-            l = l.strip()
-            if summary:
-                summary.append(l)
-            elif l.startswith('Summary:'):
-                summary.append(l[len('Summary: '):])
-            elif l.startswith('Standard-date:'):
-                date = l[len('Standard-date: '):]
-                strdate = util.strdate(date, '%Y-%m-%d %H:%M:%S')
-                self.changes[rev].date = util.datestr(strdate)
-            elif l.startswith('Creator:'):
-                self.changes[rev].author = l[len('Creator: '):]
-        self.changes[rev].summary = '\n'.join(summary)
+        try:
+            catlog = self.catlogparser.parsestr(data)
+            self.changes[rev].date = util.datestr(
+                util.strdate(catlog['Standard-date'],
+                             '%Y-%m-%d %H:%M:%S'))
+            self.changes[rev].author = catlog['Creator']
+            self.changes[rev].summary = catlog['Summary']
+            if catlog.has_key('Continuation-of'):
+                self.changes[rev].continuationof = catlog['Continuation-of']
+	except Exception, err:
+            raise util.Abort(_('could not parse cat-log of %s') % rev)
 
     def _parsechangeset(self, data, rev):
         for l in data:
Binary file tests/tampered.hg has changed
--- a/tests/test-audit-path	Sat Jan 03 21:54:58 2009 +0100
+++ b/tests/test-audit-path	Sun Jan 04 13:52:28 2009 +0100
@@ -41,4 +41,8 @@
 hg manifest -r3
 hg update -Cr3
 
+echo % attack /tmp/test
+hg manifest -r4
+hg update -Cr4 2>&1 | sed -e "s|$HGTMP|[HGTMP]|"
+
 exit 0
--- a/tests/test-audit-path.out	Sat Jan 03 21:54:58 2009 +0100
+++ b/tests/test-audit-path.out	Sun Jan 04 13:52:28 2009 +0100
@@ -10,7 +10,7 @@
 adding changesets
 adding manifests
 adding file changes
-added 4 changesets with 5 changes to 5 files (+3 heads)
+added 5 changesets with 6 changes to 6 files (+4 heads)
 (run 'hg heads' to see heads, 'hg merge' to merge)
 % attack .hg/test
 .hg/test
@@ -25,3 +25,6 @@
 % attack ../test
 ../test
 abort: path contains illegal component: ../test
+% attack /tmp/test
+/tmp/test
+abort: No such file or directory: [HGTMP]/test-audit-path/target//tmp/test