Show More
@@ -8,7 +8,7 | |||||
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 |
|
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 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, |
|
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 | |||||
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 |
|
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 |
|
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 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