hgext/convert/hg.py
changeset 5013 6c1029aacc9a
parent 5011 89fbb0a5e8e3
child 5014 914054ca532e
equal deleted inserted replaced
5012:be25decfdb13 5013:6c1029aacc9a
     1 # hg backend for convert extension
     1 # hg backend for convert extension
     2 
     2 
       
     3 # Note for hg->hg conversion: Old versions of Mercurial didn't trim
       
     4 # the whitespace from the ends of commit messages, but new versions
       
     5 # do.  Changesets created by those older versions, then converted, may
       
     6 # thus have different hashes for changesets that are otherwise
       
     7 # identical.
       
     8 
       
     9 
     3 import os, time
    10 import os, time
     4 from mercurial import hg
    11 from mercurial.node import *
       
    12 from mercurial import hg, revlog, util
     5 
    13 
     6 from common import NoRepo, converter_sink
    14 from common import NoRepo, commit, converter_source, converter_sink
     7 
    15 
     8 class convert_mercurial(converter_sink):
    16 class mercurial_sink(converter_sink):
     9     def __init__(self, ui, path):
    17     def __init__(self, ui, path):
    10         self.path = path
    18         self.path = path
    11         self.ui = ui
    19         self.ui = ui
    12         try:
    20         try:
    13             self.repo = hg.repository(self.ui, path)
    21             self.repo = hg.repository(self.ui, path)
    14         except:
    22         except:
    15             raise NoRepo("could open hg repo %s" % path)
    23             raise NoRepo("could not open hg repo %s as sink" % path)
    16 
    24 
    17     def revmapfile(self):
    25     def revmapfile(self):
    18         return os.path.join(self.path, ".hg", "shamap")
    26         return os.path.join(self.path, ".hg", "shamap")
    19 
    27 
    20     def authorfile(self):
    28     def authorfile(self):
    93             if not oldlines: self.repo.add([".hgtags"])
   101             if not oldlines: self.repo.add([".hgtags"])
    94             date = "%s 0" % int(time.mktime(time.gmtime()))
   102             date = "%s 0" % int(time.mktime(time.gmtime()))
    95             self.repo.rawcommit([".hgtags"], "update tags", "convert-repo",
   103             self.repo.rawcommit([".hgtags"], "update tags", "convert-repo",
    96                                 date, self.repo.changelog.tip(), hg.nullid)
   104                                 date, self.repo.changelog.tip(), hg.nullid)
    97             return hg.hex(self.repo.changelog.tip())
   105             return hg.hex(self.repo.changelog.tip())
       
   106 
       
   107 class mercurial_source(converter_source):
       
   108     def __init__(self, ui, path, rev=None):
       
   109         converter_source.__init__(self, ui, path, rev)
       
   110         self.repo = hg.repository(self.ui, path)
       
   111         self.lastrev = None
       
   112         self.lastctx = None
       
   113 
       
   114     def changectx(self, rev):
       
   115         if self.lastrev != rev:
       
   116             self.lastctx = self.repo.changectx(rev)
       
   117             self.lastrev = rev
       
   118         return self.lastctx
       
   119 
       
   120     def getheads(self):
       
   121         return [hex(node) for node in self.repo.heads()]
       
   122 
       
   123     def getfile(self, name, rev):
       
   124         try:
       
   125             return self.changectx(rev).filectx(name).data()
       
   126         except revlog.LookupError, err:
       
   127             raise IOError(err)
       
   128 
       
   129     def getmode(self, name, rev):
       
   130         m = self.changectx(rev).manifest()
       
   131         return (m.execf(name) and 'x' or '') + (m.linkf(name) and 'l' or '')
       
   132 
       
   133     def getchanges(self, rev):
       
   134         ctx = self.changectx(rev)
       
   135         m, a, r = self.repo.status(ctx.parents()[0].node(), ctx.node())[:3]
       
   136         changes = [(name, rev) for name in m + a + r]
       
   137         changes.sort()
       
   138         return changes
       
   139 
       
   140     def getcopies(self, ctx):
       
   141         added = self.repo.status(ctx.parents()[0].node(), ctx.node())[1]
       
   142         copies = {}
       
   143         for name in added:
       
   144             try:
       
   145                 copies[name] = ctx.filectx(name).renamed()[0]
       
   146             except TypeError:
       
   147                 pass
       
   148         return copies
       
   149         
       
   150     def getcommit(self, rev):
       
   151         ctx = self.changectx(rev)
       
   152         parents = [hex(p.node()) for p in ctx.parents() if p.node() != nullid]
       
   153         return commit(author=ctx.user(), date=util.datestr(ctx.date()),
       
   154                       desc=ctx.description(), parents=parents,
       
   155                       branch=ctx.branch(), copies=self.getcopies(ctx))
       
   156 
       
   157     def gettags(self):
       
   158         tags = [t for t in self.repo.tagslist() if t[0] != 'tip']
       
   159         return dict([(name, hex(node)) for name, node in tags])