changeset 167:3cd6a7354207

fetch: Add support for an authormap which can rename authors, intended for repository conversion.
author Graham Booker <gbooker@cod3r.com>
date Tue, 30 Dec 2008 20:13:32 -0600
parents db88e528e8e6
children 4f26fa049452
files __init__.py fetch_command.py hg_delta_editor.py
diffstat 3 files changed, 62 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/__init__.py
+++ b/__init__.py
@@ -44,6 +44,7 @@ cmdtable = {
         (svn,
          [('u', 'svn-url', '', 'Path to the Subversion server.'),
           ('', 'stupid', False, 'Be stupid and use diffy replay.'),
+          ('A', 'authors', '', 'username mapping filename'),
           ],
          svncommand.generate_help(),
          ),
@@ -51,7 +52,8 @@ cmdtable = {
         (svn_fetch,
          [('S', 'skipto-rev', '0', 'Skip commits before this revision.'),
           ('', 'stupid', False, 'Be stupid and use diffy replay.'),
-          ('T', 'tag-locations', 'tags', 'Relative path to Subversion tags.')
+          ('T', 'tag-locations', 'tags', 'Relative path to Subversion tags.'),
+          ('A', 'authors', '', 'username mapping filename'),
          ],
          'hg svnclone source [dest]'),
 }
--- a/fetch_command.py
+++ b/fetch_command.py
@@ -23,6 +23,7 @@ def print_your_svn_is_old_message(ui): #
 @util.register_subcommand('pull')
 def fetch_revisions(ui, svn_url, hg_repo_path, skipto_rev=0, stupid=None,
                     tag_locations='tags',
+                    authors=None,
                     **opts):
     """Pull new revisions from Subversion.
     """
@@ -47,7 +48,8 @@ def fetch_revisions(ui, svn_url, hg_repo
                                                  ui_=ui,
                                                  subdir=svn.subdir,
                                                  author_host=author_host,
-                                                 tag_locations=tag_locations)
+                                                 tag_locations=tag_locations,
+                                                 authors=authors)
     if os.path.exists(hg_editor.uuid_file):
         uuid = open(hg_editor.uuid_file).read()
         assert uuid == svn.uuid
--- a/hg_delta_editor.py
+++ b/hg_delta_editor.py
@@ -60,7 +60,8 @@ class HgChangeReceiver(delta.Editor):
 
     def __init__(self, path=None, repo=None, ui_=None,
                  subdir='', author_host='',
-                 tag_locations=['tags']):
+                 tag_locations=['tags'],
+                 authors=None):
         """path is the path to the target hg repo.
 
         subdir is the subdirectory of the edits *on the svn server*.
@@ -105,6 +106,13 @@ class HgChangeReceiver(delta.Editor):
 
         self.clear_current_info()
         self.author_host = author_host
+        self.authors = {}
+        if os.path.exists(self.authors_file):
+            self.readauthors(self.authors_file)
+        if authors and os.path.exists(authors):
+            self.readauthors(authors)
+        if self.authors:
+            self.writeauthors()
 
     def __setup_repo(self, repo_path):
         """Verify the repo is going to work out for us.
@@ -388,8 +396,7 @@ class HgChangeReceiver(delta.Editor):
                                          rev.message or ' ',
                                          files,
                                          del_all_files,
-                                         '%s%s' % (rev.author,
-                                                   self.author_host),
+                                         self.authorforsvnauthor(rev.author),
                                          date,
                                          {'branch': 'closed-branches'})
             new_hash = self.repo.commitctx(current_ctx)
@@ -437,7 +444,7 @@ class HgChangeReceiver(delta.Editor):
                                          rev.message or '...',
                                          files.keys(),
                                          filectxfn,
-                                         '%s%s' %(rev.author, self.author_host),
+                                         self.authorforsvnauthor(rev.author),
                                          date,
                                          extra)
             new_hash = self.repo.commitctx(current_ctx)
@@ -464,8 +471,7 @@ class HgChangeReceiver(delta.Editor):
                                          rev.message or ' ',
                                          [],
                                          del_all_files,
-                                         '%s%s' % (rev.author,
-                                                   self.author_host),
+                                         self.authorforsvnauthor(rev.author),
                                          date,
                                          extra)
             new_hash = self.repo.commitctx(current_ctx)
@@ -475,6 +481,46 @@ class HgChangeReceiver(delta.Editor):
                 self.add_to_revmap(rev.revnum, branch, new_hash)
         self.clear_current_info()
 
+    def authorforsvnauthor(self, author):
+	    if(author in self.authors):
+	        return self.authors[author]
+	    return '%s%s' %(author, self.author_host)
+
+    def readauthors(self, authorfile):
+        self.ui.status(
+            ('Reading authormap %s\n')
+            % authorfile)
+        f = open(authorfile, 'r')
+        for line in f:
+            if line.strip() == '':
+                continue
+            try:
+                srcauth, dstauth = line.split('=', 1)
+                srcauth = srcauth.strip()
+                dstauth = dstauth.strip()
+                if srcauth in self.authors and dstauth != self.authors[srcauth]:
+                    self.ui.status(
+                        ('Overriding mapping for author %s, was %s, now %s\n')
+                        % (srcauth, self.authors[srcauth], dstauth))
+                else:
+                    self.ui.debug(('Mapping author %s to %s\n')
+                        % (srcauth, dstauth))
+                    self.authors[srcauth] = dstauth
+            except IndexError:
+                self.ui.warn(
+                    ('Ignoring bad line in author map file %s: %s\n')
+                    % (authorfile, line.rstrip()))
+        f.close()
+        
+    def writeauthors(self):
+        f = open(self.authors_file, 'w+')
+        self.ui.status(
+            ('Writing author map file %s\n')
+            % self.authors_file)
+        for author in self.authors:
+            f.write("%s=%s\n" % (author, self.authors[author]))
+        f.close()
+
     @property
     def meta_data_dir(self):
         return os.path.join(self.path, '.hg', 'svn')
@@ -514,6 +560,10 @@ class HgChangeReceiver(delta.Editor):
     def url(self):
         return open(self.svn_url_file).read()
 
+    @property
+    def authors_file(self):
+        return self.meta_file_named('authors')
+        
     @stash_exception_on_self
     def delete_entry(self, path, revision_bogus, parent_baton, pool=None):
         br_path, branch = self._path_and_branch_for_path(path)