##// END OF EJS Templates
convert: add default constructor for converter_sink
Bryan O'Sullivan -
r5440:b4ae8535 default
parent child Browse files
Show More
@@ -1,181 +1,182
1 # common code for the convert extension
1 # common code for the convert extension
2 import base64
2 import base64
3 import cPickle as pickle
3 import cPickle as pickle
4
4
5 def encodeargs(args):
5 def encodeargs(args):
6 def encodearg(s):
6 def encodearg(s):
7 lines = base64.encodestring(s)
7 lines = base64.encodestring(s)
8 lines = [l.splitlines()[0] for l in lines]
8 lines = [l.splitlines()[0] for l in lines]
9 return ''.join(lines)
9 return ''.join(lines)
10
10
11 s = pickle.dumps(args)
11 s = pickle.dumps(args)
12 return encodearg(s)
12 return encodearg(s)
13
13
14 def decodeargs(s):
14 def decodeargs(s):
15 s = base64.decodestring(s)
15 s = base64.decodestring(s)
16 return pickle.loads(s)
16 return pickle.loads(s)
17
17
18 class NoRepo(Exception): pass
18 class NoRepo(Exception): pass
19
19
20 SKIPREV = 'SKIP'
20 SKIPREV = 'SKIP'
21
21
22 class commit(object):
22 class commit(object):
23 def __init__(self, author, date, desc, parents, branch=None, rev=None,
23 def __init__(self, author, date, desc, parents, branch=None, rev=None,
24 extra={}):
24 extra={}):
25 self.author = author
25 self.author = author
26 self.date = date
26 self.date = date
27 self.desc = desc
27 self.desc = desc
28 self.parents = parents
28 self.parents = parents
29 self.branch = branch
29 self.branch = branch
30 self.rev = rev
30 self.rev = rev
31 self.extra = extra
31 self.extra = extra
32
32
33 class converter_source(object):
33 class converter_source(object):
34 """Conversion source interface"""
34 """Conversion source interface"""
35
35
36 def __init__(self, ui, path, rev=None):
36 def __init__(self, ui, path, rev=None):
37 """Initialize conversion source (or raise NoRepo("message")
37 """Initialize conversion source (or raise NoRepo("message")
38 exception if path is not a valid repository)"""
38 exception if path is not a valid repository)"""
39 self.ui = ui
39 self.ui = ui
40 self.path = path
40 self.path = path
41 self.rev = rev
41 self.rev = rev
42
42
43 self.encoding = 'utf-8'
43 self.encoding = 'utf-8'
44
44
45 def before(self):
45 def before(self):
46 pass
46 pass
47
47
48 def after(self):
48 def after(self):
49 pass
49 pass
50
50
51 def setrevmap(self, revmap, order):
51 def setrevmap(self, revmap, order):
52 """set the map of already-converted revisions
52 """set the map of already-converted revisions
53
53
54 order is a list with the keys from revmap in the order they
54 order is a list with the keys from revmap in the order they
55 appear in the revision map file."""
55 appear in the revision map file."""
56 pass
56 pass
57
57
58 def getheads(self):
58 def getheads(self):
59 """Return a list of this repository's heads"""
59 """Return a list of this repository's heads"""
60 raise NotImplementedError()
60 raise NotImplementedError()
61
61
62 def getfile(self, name, rev):
62 def getfile(self, name, rev):
63 """Return file contents as a string"""
63 """Return file contents as a string"""
64 raise NotImplementedError()
64 raise NotImplementedError()
65
65
66 def getmode(self, name, rev):
66 def getmode(self, name, rev):
67 """Return file mode, eg. '', 'x', or 'l'"""
67 """Return file mode, eg. '', 'x', or 'l'"""
68 raise NotImplementedError()
68 raise NotImplementedError()
69
69
70 def getchanges(self, version):
70 def getchanges(self, version):
71 """Returns a tuple of (files, copies)
71 """Returns a tuple of (files, copies)
72 Files is a sorted list of (filename, id) tuples for all files changed
72 Files is a sorted list of (filename, id) tuples for all files changed
73 in version, where id is the source revision id of the file.
73 in version, where id is the source revision id of the file.
74
74
75 copies is a dictionary of dest: source
75 copies is a dictionary of dest: source
76 """
76 """
77 raise NotImplementedError()
77 raise NotImplementedError()
78
78
79 def getcommit(self, version):
79 def getcommit(self, version):
80 """Return the commit object for version"""
80 """Return the commit object for version"""
81 raise NotImplementedError()
81 raise NotImplementedError()
82
82
83 def gettags(self):
83 def gettags(self):
84 """Return the tags as a dictionary of name: revision"""
84 """Return the tags as a dictionary of name: revision"""
85 raise NotImplementedError()
85 raise NotImplementedError()
86
86
87 def recode(self, s, encoding=None):
87 def recode(self, s, encoding=None):
88 if not encoding:
88 if not encoding:
89 encoding = self.encoding or 'utf-8'
89 encoding = self.encoding or 'utf-8'
90
90
91 if isinstance(s, unicode):
91 if isinstance(s, unicode):
92 return s.encode("utf-8")
92 return s.encode("utf-8")
93 try:
93 try:
94 return s.decode(encoding).encode("utf-8")
94 return s.decode(encoding).encode("utf-8")
95 except:
95 except:
96 try:
96 try:
97 return s.decode("latin-1").encode("utf-8")
97 return s.decode("latin-1").encode("utf-8")
98 except:
98 except:
99 return s.decode(encoding, "replace").encode("utf-8")
99 return s.decode(encoding, "replace").encode("utf-8")
100
100
101 def getchangedfiles(self, rev, i):
101 def getchangedfiles(self, rev, i):
102 """Return the files changed by rev compared to parent[i].
102 """Return the files changed by rev compared to parent[i].
103
103
104 i is an index selecting one of the parents of rev. The return
104 i is an index selecting one of the parents of rev. The return
105 value should be the list of files that are different in rev and
105 value should be the list of files that are different in rev and
106 this parent.
106 this parent.
107
107
108 If rev has no parents, i is None.
108 If rev has no parents, i is None.
109
109
110 This function is only needed to support --filemap
110 This function is only needed to support --filemap
111 """
111 """
112 raise NotImplementedError()
112 raise NotImplementedError()
113
113
114 class converter_sink(object):
114 class converter_sink(object):
115 """Conversion sink (target) interface"""
115 """Conversion sink (target) interface"""
116
116
117 def __init__(self, ui, path):
117 def __init__(self, ui, path):
118 """Initialize conversion sink (or raise NoRepo("message")
118 """Initialize conversion sink (or raise NoRepo("message")
119 exception if path is not a valid repository)"""
119 exception if path is not a valid repository)"""
120 raise NotImplementedError()
120 self.path = path
121 self.ui = ui
121
122
122 def getheads(self):
123 def getheads(self):
123 """Return a list of this repository's heads"""
124 """Return a list of this repository's heads"""
124 raise NotImplementedError()
125 raise NotImplementedError()
125
126
126 def revmapfile(self):
127 def revmapfile(self):
127 """Path to a file that will contain lines
128 """Path to a file that will contain lines
128 source_rev_id sink_rev_id
129 source_rev_id sink_rev_id
129 mapping equivalent revision identifiers for each system."""
130 mapping equivalent revision identifiers for each system."""
130 raise NotImplementedError()
131 raise NotImplementedError()
131
132
132 def authorfile(self):
133 def authorfile(self):
133 """Path to a file that will contain lines
134 """Path to a file that will contain lines
134 srcauthor=dstauthor
135 srcauthor=dstauthor
135 mapping equivalent authors identifiers for each system."""
136 mapping equivalent authors identifiers for each system."""
136 return None
137 return None
137
138
138 def putfile(self, f, e, data):
139 def putfile(self, f, e, data):
139 """Put file for next putcommit().
140 """Put file for next putcommit().
140 f: path to file
141 f: path to file
141 e: '', 'x', or 'l' (regular file, executable, or symlink)
142 e: '', 'x', or 'l' (regular file, executable, or symlink)
142 data: file contents"""
143 data: file contents"""
143 raise NotImplementedError()
144 raise NotImplementedError()
144
145
145 def delfile(self, f):
146 def delfile(self, f):
146 """Delete file for next putcommit().
147 """Delete file for next putcommit().
147 f: path to file"""
148 f: path to file"""
148 raise NotImplementedError()
149 raise NotImplementedError()
149
150
150 def putcommit(self, files, parents, commit):
151 def putcommit(self, files, parents, commit):
151 """Create a revision with all changed files listed in 'files'
152 """Create a revision with all changed files listed in 'files'
152 and having listed parents. 'commit' is a commit object containing
153 and having listed parents. 'commit' is a commit object containing
153 at a minimum the author, date, and message for this changeset.
154 at a minimum the author, date, and message for this changeset.
154 Called after putfile() and delfile() calls. Note that the sink
155 Called after putfile() and delfile() calls. Note that the sink
155 repository is not told to update itself to a particular revision
156 repository is not told to update itself to a particular revision
156 (or even what that revision would be) before it receives the
157 (or even what that revision would be) before it receives the
157 file data."""
158 file data."""
158 raise NotImplementedError()
159 raise NotImplementedError()
159
160
160 def puttags(self, tags):
161 def puttags(self, tags):
161 """Put tags into sink.
162 """Put tags into sink.
162 tags: {tagname: sink_rev_id, ...}"""
163 tags: {tagname: sink_rev_id, ...}"""
163 raise NotImplementedError()
164 raise NotImplementedError()
164
165
165 def setbranch(self, branch, pbranch, parents):
166 def setbranch(self, branch, pbranch, parents):
166 """Set the current branch name. Called before the first putfile
167 """Set the current branch name. Called before the first putfile
167 on the branch.
168 on the branch.
168 branch: branch name for subsequent commits
169 branch: branch name for subsequent commits
169 pbranch: branch name of parent commit
170 pbranch: branch name of parent commit
170 parents: destination revisions of parent"""
171 parents: destination revisions of parent"""
171 pass
172 pass
172
173
173 def setfilemapmode(self, active):
174 def setfilemapmode(self, active):
174 """Tell the destination that we're using a filemap
175 """Tell the destination that we're using a filemap
175
176
176 Some converter_sources (svn in particular) can claim that a file
177 Some converter_sources (svn in particular) can claim that a file
177 was changed in a revision, even if there was no change. This method
178 was changed in a revision, even if there was no change. This method
178 tells the destination that we're using a filemap and that it should
179 tells the destination that we're using a filemap and that it should
179 filter empty revisions.
180 filter empty revisions.
180 """
181 """
181 pass
182 pass
@@ -1,248 +1,247
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
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
4 # the whitespace from the ends of commit messages, but new versions
5 # do. Changesets created by those older versions, then converted, may
5 # do. Changesets created by those older versions, then converted, may
6 # thus have different hashes for changesets that are otherwise
6 # thus have different hashes for changesets that are otherwise
7 # identical.
7 # identical.
8
8
9
9
10 import os, time
10 import os, time
11 from mercurial.i18n import _
11 from mercurial.i18n import _
12 from mercurial.node import *
12 from mercurial.node import *
13 from mercurial import hg, lock, revlog, util
13 from mercurial import hg, lock, revlog, util
14
14
15 from common import NoRepo, commit, converter_source, converter_sink
15 from common import NoRepo, commit, converter_source, converter_sink
16
16
17 class mercurial_sink(converter_sink):
17 class mercurial_sink(converter_sink):
18 def __init__(self, ui, path):
18 def __init__(self, ui, path):
19 self.path = path
19 converter_sink.__init__(self, ui, path)
20 self.ui = ui
21 self.branchnames = ui.configbool('convert', 'hg.usebranchnames', True)
20 self.branchnames = ui.configbool('convert', 'hg.usebranchnames', True)
22 self.clonebranches = ui.configbool('convert', 'hg.clonebranches', False)
21 self.clonebranches = ui.configbool('convert', 'hg.clonebranches', False)
23 self.tagsbranch = ui.config('convert', 'hg.tagsbranch', 'default')
22 self.tagsbranch = ui.config('convert', 'hg.tagsbranch', 'default')
24 self.lastbranch = None
23 self.lastbranch = None
25 try:
24 try:
26 self.repo = hg.repository(self.ui, path)
25 self.repo = hg.repository(self.ui, path)
27 except:
26 except:
28 raise NoRepo("could not open hg repo %s as sink" % path)
27 raise NoRepo("could not open hg repo %s as sink" % path)
29 self.lock = None
28 self.lock = None
30 self.wlock = None
29 self.wlock = None
31 self.filemapmode = False
30 self.filemapmode = False
32
31
33 def before(self):
32 def before(self):
34 self.wlock = self.repo.wlock()
33 self.wlock = self.repo.wlock()
35 self.lock = self.repo.lock()
34 self.lock = self.repo.lock()
36 self.repo.dirstate.clear()
35 self.repo.dirstate.clear()
37
36
38 def after(self):
37 def after(self):
39 self.repo.dirstate.invalidate()
38 self.repo.dirstate.invalidate()
40 self.lock = None
39 self.lock = None
41 self.wlock = None
40 self.wlock = None
42
41
43 def revmapfile(self):
42 def revmapfile(self):
44 return os.path.join(self.path, ".hg", "shamap")
43 return os.path.join(self.path, ".hg", "shamap")
45
44
46 def authorfile(self):
45 def authorfile(self):
47 return os.path.join(self.path, ".hg", "authormap")
46 return os.path.join(self.path, ".hg", "authormap")
48
47
49 def getheads(self):
48 def getheads(self):
50 h = self.repo.changelog.heads()
49 h = self.repo.changelog.heads()
51 return [ hex(x) for x in h ]
50 return [ hex(x) for x in h ]
52
51
53 def putfile(self, f, e, data):
52 def putfile(self, f, e, data):
54 self.repo.wwrite(f, data, e)
53 self.repo.wwrite(f, data, e)
55 if f not in self.repo.dirstate:
54 if f not in self.repo.dirstate:
56 self.repo.dirstate.normallookup(f)
55 self.repo.dirstate.normallookup(f)
57
56
58 def copyfile(self, source, dest):
57 def copyfile(self, source, dest):
59 self.repo.copy(source, dest)
58 self.repo.copy(source, dest)
60
59
61 def delfile(self, f):
60 def delfile(self, f):
62 try:
61 try:
63 util.unlink(self.repo.wjoin(f))
62 util.unlink(self.repo.wjoin(f))
64 #self.repo.remove([f])
63 #self.repo.remove([f])
65 except OSError:
64 except OSError:
66 pass
65 pass
67
66
68 def setbranch(self, branch, pbranch, parents):
67 def setbranch(self, branch, pbranch, parents):
69 if (not self.clonebranches) or (branch == self.lastbranch):
68 if (not self.clonebranches) or (branch == self.lastbranch):
70 return
69 return
71
70
72 self.lastbranch = branch
71 self.lastbranch = branch
73 self.after()
72 self.after()
74 if not branch:
73 if not branch:
75 branch = 'default'
74 branch = 'default'
76 if not pbranch:
75 if not pbranch:
77 pbranch = 'default'
76 pbranch = 'default'
78
77
79 branchpath = os.path.join(self.path, branch)
78 branchpath = os.path.join(self.path, branch)
80 try:
79 try:
81 self.repo = hg.repository(self.ui, branchpath)
80 self.repo = hg.repository(self.ui, branchpath)
82 except:
81 except:
83 if not parents:
82 if not parents:
84 self.repo = hg.repository(self.ui, branchpath, create=True)
83 self.repo = hg.repository(self.ui, branchpath, create=True)
85 else:
84 else:
86 self.ui.note(_('cloning branch %s to %s\n') % (pbranch, branch))
85 self.ui.note(_('cloning branch %s to %s\n') % (pbranch, branch))
87 hg.clone(self.ui, os.path.join(self.path, pbranch),
86 hg.clone(self.ui, os.path.join(self.path, pbranch),
88 branchpath, rev=parents, update=False,
87 branchpath, rev=parents, update=False,
89 stream=True)
88 stream=True)
90 self.repo = hg.repository(self.ui, branchpath)
89 self.repo = hg.repository(self.ui, branchpath)
91 self.before()
90 self.before()
92
91
93 def putcommit(self, files, parents, commit):
92 def putcommit(self, files, parents, commit):
94 seen = {}
93 seen = {}
95 pl = []
94 pl = []
96 for p in parents:
95 for p in parents:
97 if p not in seen:
96 if p not in seen:
98 pl.append(p)
97 pl.append(p)
99 seen[p] = 1
98 seen[p] = 1
100 parents = pl
99 parents = pl
101 nparents = len(parents)
100 nparents = len(parents)
102 if self.filemapmode and nparents == 1:
101 if self.filemapmode and nparents == 1:
103 m1node = self.repo.changelog.read(bin(parents[0]))[0]
102 m1node = self.repo.changelog.read(bin(parents[0]))[0]
104 parent = parents[0]
103 parent = parents[0]
105
104
106 if len(parents) < 2: parents.append("0" * 40)
105 if len(parents) < 2: parents.append("0" * 40)
107 if len(parents) < 2: parents.append("0" * 40)
106 if len(parents) < 2: parents.append("0" * 40)
108 p2 = parents.pop(0)
107 p2 = parents.pop(0)
109
108
110 text = commit.desc
109 text = commit.desc
111 extra = commit.extra.copy()
110 extra = commit.extra.copy()
112 if self.branchnames and commit.branch:
111 if self.branchnames and commit.branch:
113 extra['branch'] = commit.branch
112 extra['branch'] = commit.branch
114 if commit.rev:
113 if commit.rev:
115 extra['convert_revision'] = commit.rev
114 extra['convert_revision'] = commit.rev
116
115
117 while parents:
116 while parents:
118 p1 = p2
117 p1 = p2
119 p2 = parents.pop(0)
118 p2 = parents.pop(0)
120 a = self.repo.rawcommit(files, text, commit.author, commit.date,
119 a = self.repo.rawcommit(files, text, commit.author, commit.date,
121 bin(p1), bin(p2), extra=extra)
120 bin(p1), bin(p2), extra=extra)
122 self.repo.dirstate.clear()
121 self.repo.dirstate.clear()
123 text = "(octopus merge fixup)\n"
122 text = "(octopus merge fixup)\n"
124 p2 = hg.hex(self.repo.changelog.tip())
123 p2 = hg.hex(self.repo.changelog.tip())
125
124
126 if self.filemapmode and nparents == 1:
125 if self.filemapmode and nparents == 1:
127 man = self.repo.manifest
126 man = self.repo.manifest
128 mnode = self.repo.changelog.read(bin(p2))[0]
127 mnode = self.repo.changelog.read(bin(p2))[0]
129 if not man.cmp(m1node, man.revision(mnode)):
128 if not man.cmp(m1node, man.revision(mnode)):
130 self.repo.rollback()
129 self.repo.rollback()
131 self.repo.dirstate.clear()
130 self.repo.dirstate.clear()
132 return parent
131 return parent
133 return p2
132 return p2
134
133
135 def puttags(self, tags):
134 def puttags(self, tags):
136 try:
135 try:
137 old = self.repo.wfile(".hgtags").read()
136 old = self.repo.wfile(".hgtags").read()
138 oldlines = old.splitlines(1)
137 oldlines = old.splitlines(1)
139 oldlines.sort()
138 oldlines.sort()
140 except:
139 except:
141 oldlines = []
140 oldlines = []
142
141
143 k = tags.keys()
142 k = tags.keys()
144 k.sort()
143 k.sort()
145 newlines = []
144 newlines = []
146 for tag in k:
145 for tag in k:
147 newlines.append("%s %s\n" % (tags[tag], tag))
146 newlines.append("%s %s\n" % (tags[tag], tag))
148
147
149 newlines.sort()
148 newlines.sort()
150
149
151 if newlines != oldlines:
150 if newlines != oldlines:
152 self.ui.status("updating tags\n")
151 self.ui.status("updating tags\n")
153 f = self.repo.wfile(".hgtags", "w")
152 f = self.repo.wfile(".hgtags", "w")
154 f.write("".join(newlines))
153 f.write("".join(newlines))
155 f.close()
154 f.close()
156 if not oldlines: self.repo.add([".hgtags"])
155 if not oldlines: self.repo.add([".hgtags"])
157 date = "%s 0" % int(time.mktime(time.gmtime()))
156 date = "%s 0" % int(time.mktime(time.gmtime()))
158 extra = {}
157 extra = {}
159 if self.tagsbranch != 'default':
158 if self.tagsbranch != 'default':
160 extra['branch'] = self.tagsbranch
159 extra['branch'] = self.tagsbranch
161 try:
160 try:
162 tagparent = self.repo.changectx(self.tagsbranch).node()
161 tagparent = self.repo.changectx(self.tagsbranch).node()
163 except hg.RepoError, inst:
162 except hg.RepoError, inst:
164 tagparent = nullid
163 tagparent = nullid
165 self.repo.rawcommit([".hgtags"], "update tags", "convert-repo",
164 self.repo.rawcommit([".hgtags"], "update tags", "convert-repo",
166 date, tagparent, nullid)
165 date, tagparent, nullid)
167 return hex(self.repo.changelog.tip())
166 return hex(self.repo.changelog.tip())
168
167
169 def setfilemapmode(self, active):
168 def setfilemapmode(self, active):
170 self.filemapmode = active
169 self.filemapmode = active
171
170
172 class mercurial_source(converter_source):
171 class mercurial_source(converter_source):
173 def __init__(self, ui, path, rev=None):
172 def __init__(self, ui, path, rev=None):
174 converter_source.__init__(self, ui, path, rev)
173 converter_source.__init__(self, ui, path, rev)
175 try:
174 try:
176 self.repo = hg.repository(self.ui, path)
175 self.repo = hg.repository(self.ui, path)
177 # try to provoke an exception if this isn't really a hg
176 # try to provoke an exception if this isn't really a hg
178 # repo, but some other bogus compatible-looking url
177 # repo, but some other bogus compatible-looking url
179 self.repo.heads()
178 self.repo.heads()
180 except hg.RepoError:
179 except hg.RepoError:
181 ui.print_exc()
180 ui.print_exc()
182 raise NoRepo("could not open hg repo %s as source" % path)
181 raise NoRepo("could not open hg repo %s as source" % path)
183 self.lastrev = None
182 self.lastrev = None
184 self.lastctx = None
183 self.lastctx = None
185 self._changescache = None
184 self._changescache = None
186
185
187 def changectx(self, rev):
186 def changectx(self, rev):
188 if self.lastrev != rev:
187 if self.lastrev != rev:
189 self.lastctx = self.repo.changectx(rev)
188 self.lastctx = self.repo.changectx(rev)
190 self.lastrev = rev
189 self.lastrev = rev
191 return self.lastctx
190 return self.lastctx
192
191
193 def getheads(self):
192 def getheads(self):
194 if self.rev:
193 if self.rev:
195 return [hex(self.repo.changectx(self.rev).node())]
194 return [hex(self.repo.changectx(self.rev).node())]
196 else:
195 else:
197 return [hex(node) for node in self.repo.heads()]
196 return [hex(node) for node in self.repo.heads()]
198
197
199 def getfile(self, name, rev):
198 def getfile(self, name, rev):
200 try:
199 try:
201 return self.changectx(rev).filectx(name).data()
200 return self.changectx(rev).filectx(name).data()
202 except revlog.LookupError, err:
201 except revlog.LookupError, err:
203 raise IOError(err)
202 raise IOError(err)
204
203
205 def getmode(self, name, rev):
204 def getmode(self, name, rev):
206 m = self.changectx(rev).manifest()
205 m = self.changectx(rev).manifest()
207 return (m.execf(name) and 'x' or '') + (m.linkf(name) and 'l' or '')
206 return (m.execf(name) and 'x' or '') + (m.linkf(name) and 'l' or '')
208
207
209 def getchanges(self, rev):
208 def getchanges(self, rev):
210 ctx = self.changectx(rev)
209 ctx = self.changectx(rev)
211 if self._changescache and self._changescache[0] == rev:
210 if self._changescache and self._changescache[0] == rev:
212 m, a, r = self._changescache[1]
211 m, a, r = self._changescache[1]
213 else:
212 else:
214 m, a, r = self.repo.status(ctx.parents()[0].node(), ctx.node())[:3]
213 m, a, r = self.repo.status(ctx.parents()[0].node(), ctx.node())[:3]
215 changes = [(name, rev) for name in m + a + r]
214 changes = [(name, rev) for name in m + a + r]
216 changes.sort()
215 changes.sort()
217 return (changes, self.getcopies(ctx, m + a))
216 return (changes, self.getcopies(ctx, m + a))
218
217
219 def getcopies(self, ctx, files):
218 def getcopies(self, ctx, files):
220 copies = {}
219 copies = {}
221 for name in files:
220 for name in files:
222 try:
221 try:
223 copies[name] = ctx.filectx(name).renamed()[0]
222 copies[name] = ctx.filectx(name).renamed()[0]
224 except TypeError:
223 except TypeError:
225 pass
224 pass
226 return copies
225 return copies
227
226
228 def getcommit(self, rev):
227 def getcommit(self, rev):
229 ctx = self.changectx(rev)
228 ctx = self.changectx(rev)
230 parents = [hex(p.node()) for p in ctx.parents() if p.node() != nullid]
229 parents = [hex(p.node()) for p in ctx.parents() if p.node() != nullid]
231 return commit(author=ctx.user(), date=util.datestr(ctx.date()),
230 return commit(author=ctx.user(), date=util.datestr(ctx.date()),
232 desc=ctx.description(), parents=parents,
231 desc=ctx.description(), parents=parents,
233 branch=ctx.branch(), extra=ctx.extra())
232 branch=ctx.branch(), extra=ctx.extra())
234
233
235 def gettags(self):
234 def gettags(self):
236 tags = [t for t in self.repo.tagslist() if t[0] != 'tip']
235 tags = [t for t in self.repo.tagslist() if t[0] != 'tip']
237 return dict([(name, hex(node)) for name, node in tags])
236 return dict([(name, hex(node)) for name, node in tags])
238
237
239 def getchangedfiles(self, rev, i):
238 def getchangedfiles(self, rev, i):
240 ctx = self.changectx(rev)
239 ctx = self.changectx(rev)
241 i = i or 0
240 i = i or 0
242 changes = self.repo.status(ctx.parents()[i].node(), ctx.node())[:3]
241 changes = self.repo.status(ctx.parents()[i].node(), ctx.node())[:3]
243
242
244 if i == 0:
243 if i == 0:
245 self._changescache = (rev, changes)
244 self._changescache = (rev, changes)
246
245
247 return changes[0] + changes[1] + changes[2]
246 return changes[0] + changes[1] + changes[2]
248
247
General Comments 0
You need to be logged in to leave comments. Login now