##// END OF EJS Templates
convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan -
r5013:6c1029aa default
parent child Browse files
Show More
@@ -8,7 +8,7 b''
8 from common import NoRepo, converter_source, converter_sink
8 from common import NoRepo, converter_source, converter_sink
9 from cvs import convert_cvs
9 from cvs import convert_cvs
10 from git import convert_git
10 from git import convert_git
11 from hg import convert_mercurial
11 from hg import mercurial_source, mercurial_sink
12 from subversion import convert_svn
12 from subversion import convert_svn
13
13
14 import os, shutil
14 import os, shutil
@@ -16,7 +16,8 b' from mercurial import hg, ui, util, comm'
16
16
17 commands.norepo += " convert"
17 commands.norepo += " convert"
18
18
19 converters = [convert_cvs, convert_git, convert_svn, convert_mercurial]
19 converters = [convert_cvs, convert_git, convert_svn, mercurial_source,
20 mercurial_sink]
20
21
21 def convertsource(ui, path, **opts):
22 def convertsource(ui, path, **opts):
22 for c in converters:
23 for c in converters:
@@ -1,18 +1,26 b''
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")
@@ -95,3 +103,57 b' class convert_mercurial(converter_sink):'
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])
General Comments 0
You need to be logged in to leave comments. Login now