Mercurial > hg
annotate hgext/convert/bzr.py @ 15461:6ba2fc0a87ab stable
convert/bzr: correctly handle divergent nested renames (issue3089)
With renames like:
a -> b
a/c -> a/c
We were ignoring or duplicating the second one instead of leaving files
unchanged or moving them to their proper destination only.
To avoid this, we process the files in reverse lexicographic order, from most
to least specific change, and ignore files already processed.
v2:
- Add a test
- Change "reverse=1" into "reverse=True"
author | Patrick Mezard <pmezard@gmail.com> |
---|---|
date | Tue, 08 Nov 2011 17:08:58 +0100 |
parents | 516b000fbb7e |
children | f5b6046f6ce8 |
rev | line source |
---|---|
8250
1b60efdb8bc5
convert: add copyright and license headers to back-ends
Martin Geisler <mg@lazybytes.net>
parents:
8166
diff
changeset
|
1 # bzr.py - bzr support for the convert extension |
1b60efdb8bc5
convert: add copyright and license headers to back-ends
Martin Geisler <mg@lazybytes.net>
parents:
8166
diff
changeset
|
2 # |
1b60efdb8bc5
convert: add copyright and license headers to back-ends
Martin Geisler <mg@lazybytes.net>
parents:
8166
diff
changeset
|
3 # Copyright 2008, 2009 Marek Kubica <marek@xivilization.net> and others |
1b60efdb8bc5
convert: add copyright and license headers to back-ends
Martin Geisler <mg@lazybytes.net>
parents:
8166
diff
changeset
|
4 # |
1b60efdb8bc5
convert: add copyright and license headers to back-ends
Martin Geisler <mg@lazybytes.net>
parents:
8166
diff
changeset
|
5 # This software may be used and distributed according to the terms of the |
10263 | 6 # GNU General Public License version 2 or any later version. |
8250
1b60efdb8bc5
convert: add copyright and license headers to back-ends
Martin Geisler <mg@lazybytes.net>
parents:
8166
diff
changeset
|
7 |
7053 | 8 # This module is for handling 'bzr', that was formerly known as Bazaar-NG; |
9 # it cannot access 'bar' repositories, but they were never used very much | |
10 | |
11 import os | |
12 from mercurial import demandimport | |
13 # these do not work with demandimport, blacklist | |
14 demandimport.ignore.extend([ | |
15 'bzrlib.transactions', | |
16 'bzrlib.urlutils', | |
10560
9134725caf1d
Add ElementPath to the list of package ignored by demand import
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
10394
diff
changeset
|
17 'ElementPath', |
7053 | 18 ]) |
19 | |
20 from mercurial.i18n import _ | |
21 from mercurial import util | |
22 from common import NoRepo, commit, converter_source | |
23 | |
24 try: | |
25 # bazaar imports | |
26 from bzrlib import branch, revision, errors | |
27 from bzrlib.revisionspec import RevisionSpec | |
28 except ImportError: | |
29 pass | |
30 | |
8045
e09a2f2ef85d
convert/bzr: fix file rename replaced by a dir case (issue1583)
Patrick Mezard <pmezard@gmail.com>
parents:
8035
diff
changeset
|
31 supportedkinds = ('file', 'symlink') |
e09a2f2ef85d
convert/bzr: fix file rename replaced by a dir case (issue1583)
Patrick Mezard <pmezard@gmail.com>
parents:
8035
diff
changeset
|
32 |
7053 | 33 class bzr_source(converter_source): |
34 """Reads Bazaar repositories by using the Bazaar Python libraries""" | |
35 | |
36 def __init__(self, ui, path, rev=None): | |
37 super(bzr_source, self).__init__(ui, path, rev=rev) | |
38 | |
7973
db3a68fd9387
convert: attempt to check repo type before checking for tool
Matt Mackall <mpm@selenic.com>
parents:
7060
diff
changeset
|
39 if not os.path.exists(os.path.join(path, '.bzr')): |
10939
9f6731b03906
convert: mark strings for translation
Martin Geisler <mg@lazybytes.net>
parents:
10938
diff
changeset
|
40 raise NoRepo(_('%s does not look like a Bazaar repository') |
9f6731b03906
convert: mark strings for translation
Martin Geisler <mg@lazybytes.net>
parents:
10938
diff
changeset
|
41 % path) |
7973
db3a68fd9387
convert: attempt to check repo type before checking for tool
Matt Mackall <mpm@selenic.com>
parents:
7060
diff
changeset
|
42 |
7053 | 43 try: |
44 # access bzrlib stuff | |
45 branch | |
46 except NameError: | |
10939
9f6731b03906
convert: mark strings for translation
Martin Geisler <mg@lazybytes.net>
parents:
10938
diff
changeset
|
47 raise NoRepo(_('Bazaar modules could not be loaded')) |
7053 | 48 |
49 path = os.path.abspath(path) | |
8470
dd24488cba2d
convert/bzr: warn when source is a lightweight checkout (issue1647)
Patrick Mezard <pmezard@gmail.com>
parents:
8434
diff
changeset
|
50 self._checkrepotype(path) |
7053 | 51 self.branch = branch.Branch.open(path) |
52 self.sourcerepo = self.branch.repository | |
53 self._parentids = {} | |
54 | |
8470
dd24488cba2d
convert/bzr: warn when source is a lightweight checkout (issue1647)
Patrick Mezard <pmezard@gmail.com>
parents:
8434
diff
changeset
|
55 def _checkrepotype(self, path): |
dd24488cba2d
convert/bzr: warn when source is a lightweight checkout (issue1647)
Patrick Mezard <pmezard@gmail.com>
parents:
8434
diff
changeset
|
56 # Lightweight checkouts detection is informational but probably |
dd24488cba2d
convert/bzr: warn when source is a lightweight checkout (issue1647)
Patrick Mezard <pmezard@gmail.com>
parents:
8434
diff
changeset
|
57 # fragile at API level. It should not terminate the conversion. |
dd24488cba2d
convert/bzr: warn when source is a lightweight checkout (issue1647)
Patrick Mezard <pmezard@gmail.com>
parents:
8434
diff
changeset
|
58 try: |
dd24488cba2d
convert/bzr: warn when source is a lightweight checkout (issue1647)
Patrick Mezard <pmezard@gmail.com>
parents:
8434
diff
changeset
|
59 from bzrlib import bzrdir |
dd24488cba2d
convert/bzr: warn when source is a lightweight checkout (issue1647)
Patrick Mezard <pmezard@gmail.com>
parents:
8434
diff
changeset
|
60 dir = bzrdir.BzrDir.open_containing(path)[0] |
dd24488cba2d
convert/bzr: warn when source is a lightweight checkout (issue1647)
Patrick Mezard <pmezard@gmail.com>
parents:
8434
diff
changeset
|
61 try: |
dd24488cba2d
convert/bzr: warn when source is a lightweight checkout (issue1647)
Patrick Mezard <pmezard@gmail.com>
parents:
8434
diff
changeset
|
62 tree = dir.open_workingtree(recommend_upgrade=False) |
dd24488cba2d
convert/bzr: warn when source is a lightweight checkout (issue1647)
Patrick Mezard <pmezard@gmail.com>
parents:
8434
diff
changeset
|
63 branch = tree.branch |
12063
516b000fbb7e
cleanup: remove unused variables
Brodie Rao <brodie@bitheap.org>
parents:
11134
diff
changeset
|
64 except (errors.NoWorkingTree, errors.NotLocalUrl): |
8470
dd24488cba2d
convert/bzr: warn when source is a lightweight checkout (issue1647)
Patrick Mezard <pmezard@gmail.com>
parents:
8434
diff
changeset
|
65 tree = None |
dd24488cba2d
convert/bzr: warn when source is a lightweight checkout (issue1647)
Patrick Mezard <pmezard@gmail.com>
parents:
8434
diff
changeset
|
66 branch = dir.open_branch() |
dd24488cba2d
convert/bzr: warn when source is a lightweight checkout (issue1647)
Patrick Mezard <pmezard@gmail.com>
parents:
8434
diff
changeset
|
67 if (tree is not None and tree.bzrdir.root_transport.base != |
dd24488cba2d
convert/bzr: warn when source is a lightweight checkout (issue1647)
Patrick Mezard <pmezard@gmail.com>
parents:
8434
diff
changeset
|
68 branch.bzrdir.root_transport.base): |
dd24488cba2d
convert/bzr: warn when source is a lightweight checkout (issue1647)
Patrick Mezard <pmezard@gmail.com>
parents:
8434
diff
changeset
|
69 self.ui.warn(_('warning: lightweight checkouts may cause ' |
dd24488cba2d
convert/bzr: warn when source is a lightweight checkout (issue1647)
Patrick Mezard <pmezard@gmail.com>
parents:
8434
diff
changeset
|
70 'conversion failures, try with a regular ' |
dd24488cba2d
convert/bzr: warn when source is a lightweight checkout (issue1647)
Patrick Mezard <pmezard@gmail.com>
parents:
8434
diff
changeset
|
71 'branch instead.\n')) |
dd24488cba2d
convert/bzr: warn when source is a lightweight checkout (issue1647)
Patrick Mezard <pmezard@gmail.com>
parents:
8434
diff
changeset
|
72 except: |
dd24488cba2d
convert/bzr: warn when source is a lightweight checkout (issue1647)
Patrick Mezard <pmezard@gmail.com>
parents:
8434
diff
changeset
|
73 self.ui.note(_('bzr source type could not be determined\n')) |
dd24488cba2d
convert/bzr: warn when source is a lightweight checkout (issue1647)
Patrick Mezard <pmezard@gmail.com>
parents:
8434
diff
changeset
|
74 |
7053 | 75 def before(self): |
76 """Before the conversion begins, acquire a read lock | |
77 for all the operations that might need it. Fortunately | |
78 read locks don't block other reads or writes to the | |
79 repository, so this shouldn't have any impact on the usage of | |
80 the source repository. | |
81 | |
82 The alternative would be locking on every operation that | |
83 needs locks (there are currently two: getting the file and | |
84 getting the parent map) and releasing immediately after, | |
85 but this approach can take even 40% longer.""" | |
86 self.sourcerepo.lock_read() | |
87 | |
88 def after(self): | |
89 self.sourcerepo.unlock() | |
90 | |
91 def getheads(self): | |
92 if not self.rev: | |
93 return [self.branch.last_revision()] | |
94 try: | |
95 r = RevisionSpec.from_string(self.rev) | |
96 info = r.in_history(self.branch) | |
97 except errors.BzrError: | |
98 raise util.Abort(_('%s is not a valid revision in current branch') | |
99 % self.rev) | |
100 return [info.rev_id] | |
101 | |
102 def getfile(self, name, rev): | |
103 revtree = self.sourcerepo.revision_tree(rev) | |
8783
6556d4145122
bzr convert: restore paths to source encoding. Closes issue1692.
Brendan Cully <brendan@kublai.com>
parents:
8423
diff
changeset
|
104 fileid = revtree.path2id(name.decode(self.encoding or 'utf-8')) |
8423
eb7be0e752d9
convert/bzr: fix symlinks target (issue1626/2)
Patrick Mezard <pmezard@gmail.com>
parents:
8165
diff
changeset
|
105 kind = None |
eb7be0e752d9
convert/bzr: fix symlinks target (issue1626/2)
Patrick Mezard <pmezard@gmail.com>
parents:
8165
diff
changeset
|
106 if fileid is not None: |
eb7be0e752d9
convert/bzr: fix symlinks target (issue1626/2)
Patrick Mezard <pmezard@gmail.com>
parents:
8165
diff
changeset
|
107 kind = revtree.kind(fileid) |
eb7be0e752d9
convert/bzr: fix symlinks target (issue1626/2)
Patrick Mezard <pmezard@gmail.com>
parents:
8165
diff
changeset
|
108 if kind not in supportedkinds: |
7053 | 109 # the file is not available anymore - was deleted |
110 raise IOError(_('%s is not available in %s anymore') % | |
111 (name, rev)) | |
11134
33010ff1fd6f
convert: merge sources getmode() into getfile()
Patrick Mezard <pmezard@gmail.com>
parents:
10939
diff
changeset
|
112 mode = self._modecache[(name, rev)] |
8423
eb7be0e752d9
convert/bzr: fix symlinks target (issue1626/2)
Patrick Mezard <pmezard@gmail.com>
parents:
8165
diff
changeset
|
113 if kind == 'symlink': |
eb7be0e752d9
convert/bzr: fix symlinks target (issue1626/2)
Patrick Mezard <pmezard@gmail.com>
parents:
8165
diff
changeset
|
114 target = revtree.get_symlink_target(fileid) |
eb7be0e752d9
convert/bzr: fix symlinks target (issue1626/2)
Patrick Mezard <pmezard@gmail.com>
parents:
8165
diff
changeset
|
115 if target is None: |
eb7be0e752d9
convert/bzr: fix symlinks target (issue1626/2)
Patrick Mezard <pmezard@gmail.com>
parents:
8165
diff
changeset
|
116 raise util.Abort(_('%s.%s symlink has no target') |
eb7be0e752d9
convert/bzr: fix symlinks target (issue1626/2)
Patrick Mezard <pmezard@gmail.com>
parents:
8165
diff
changeset
|
117 % (name, rev)) |
11134
33010ff1fd6f
convert: merge sources getmode() into getfile()
Patrick Mezard <pmezard@gmail.com>
parents:
10939
diff
changeset
|
118 return target, mode |
8423
eb7be0e752d9
convert/bzr: fix symlinks target (issue1626/2)
Patrick Mezard <pmezard@gmail.com>
parents:
8165
diff
changeset
|
119 else: |
eb7be0e752d9
convert/bzr: fix symlinks target (issue1626/2)
Patrick Mezard <pmezard@gmail.com>
parents:
8165
diff
changeset
|
120 sio = revtree.get_file(fileid) |
11134
33010ff1fd6f
convert: merge sources getmode() into getfile()
Patrick Mezard <pmezard@gmail.com>
parents:
10939
diff
changeset
|
121 return sio.read(), mode |
7053 | 122 |
123 def getchanges(self, version): | |
124 # set up caches: modecache and revtree | |
125 self._modecache = {} | |
126 self._revtree = self.sourcerepo.revision_tree(version) | |
127 # get the parentids from the cache | |
128 parentids = self._parentids.pop(version) | |
129 # only diff against first parent id | |
130 prevtree = self.sourcerepo.revision_tree(parentids[0]) | |
131 return self._gettreechanges(self._revtree, prevtree) | |
132 | |
133 def getcommit(self, version): | |
134 rev = self.sourcerepo.get_revision(version) | |
135 # populate parent id cache | |
136 if not rev.parent_ids: | |
137 parents = [] | |
138 self._parentids[version] = (revision.NULL_REVISION,) | |
139 else: | |
140 parents = self._filterghosts(rev.parent_ids) | |
141 self._parentids[version] = parents | |
142 | |
143 return commit(parents=parents, | |
8305
7a0fcdd3828f
convert/bzr: handle Bazaar timestamps correctly (issue1652).
Greg Ward <greg-hg@gerg.ca>
parents:
8250
diff
changeset
|
144 date='%d %d' % (rev.timestamp, -rev.timezone), |
7053 | 145 author=self.recode(rev.committer), |
146 # bzr returns bytestrings or unicode, depending on the content | |
147 desc=self.recode(rev.message), | |
148 rev=version) | |
149 | |
150 def gettags(self): | |
151 if not self.branch.supports_tags(): | |
152 return {} | |
153 tagdict = self.branch.tags.get_tag_dict() | |
154 bytetags = {} | |
155 for name, rev in tagdict.iteritems(): | |
156 bytetags[self.recode(name)] = rev | |
157 return bytetags | |
158 | |
159 def getchangedfiles(self, rev, i): | |
160 self._modecache = {} | |
161 curtree = self.sourcerepo.revision_tree(rev) | |
162 if i is not None: | |
8165
78658990c725
convert/bzr: make it work with filemaps (issue1631)
Patrick Mezard <pmezard@gmail.com>
parents:
8148
diff
changeset
|
163 parentid = self._parentids[rev][i] |
7053 | 164 else: |
165 # no parent id, get the empty revision | |
166 parentid = revision.NULL_REVISION | |
167 | |
168 prevtree = self.sourcerepo.revision_tree(parentid) | |
169 changes = [e[0] for e in self._gettreechanges(curtree, prevtree)[0]] | |
170 return changes | |
171 | |
172 def _gettreechanges(self, current, origin): | |
10394
4612cded5176
fix coding style (reported by pylint)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10282
diff
changeset
|
173 revid = current._revision_id |
7053 | 174 changes = [] |
175 renames = {} | |
15461
6ba2fc0a87ab
convert/bzr: correctly handle divergent nested renames (issue3089)
Patrick Mezard <pmezard@gmail.com>
parents:
12063
diff
changeset
|
176 seen = set() |
6ba2fc0a87ab
convert/bzr: correctly handle divergent nested renames (issue3089)
Patrick Mezard <pmezard@gmail.com>
parents:
12063
diff
changeset
|
177 # Process the entries by reverse lexicographic name order to |
6ba2fc0a87ab
convert/bzr: correctly handle divergent nested renames (issue3089)
Patrick Mezard <pmezard@gmail.com>
parents:
12063
diff
changeset
|
178 # handle nested renames correctly, most specific first. |
6ba2fc0a87ab
convert/bzr: correctly handle divergent nested renames (issue3089)
Patrick Mezard <pmezard@gmail.com>
parents:
12063
diff
changeset
|
179 curchanges = sorted(current.iter_changes(origin), |
6ba2fc0a87ab
convert/bzr: correctly handle divergent nested renames (issue3089)
Patrick Mezard <pmezard@gmail.com>
parents:
12063
diff
changeset
|
180 key=lambda c: c[1][0] or c[1][1], |
6ba2fc0a87ab
convert/bzr: correctly handle divergent nested renames (issue3089)
Patrick Mezard <pmezard@gmail.com>
parents:
12063
diff
changeset
|
181 reverse=True) |
7053 | 182 for (fileid, paths, changed_content, versioned, parent, name, |
15461
6ba2fc0a87ab
convert/bzr: correctly handle divergent nested renames (issue3089)
Patrick Mezard <pmezard@gmail.com>
parents:
12063
diff
changeset
|
183 kind, executable) in curchanges: |
7053 | 184 |
185 if paths[0] == u'' or paths[1] == u'': | |
186 # ignore changes to tree root | |
187 continue | |
188 | |
189 # bazaar tracks directories, mercurial does not, so | |
190 # we have to rename the directory contents | |
191 if kind[1] == 'directory': | |
8126
13b36eb14324
convert/bzr: handle files replaced by directories (issue1623)
Patrick Mezard <pmezard@gmail.com>
parents:
8045
diff
changeset
|
192 if kind[0] not in (None, 'directory'): |
13b36eb14324
convert/bzr: handle files replaced by directories (issue1623)
Patrick Mezard <pmezard@gmail.com>
parents:
8045
diff
changeset
|
193 # Replacing 'something' with a directory, record it |
13b36eb14324
convert/bzr: handle files replaced by directories (issue1623)
Patrick Mezard <pmezard@gmail.com>
parents:
8045
diff
changeset
|
194 # so it can be removed. |
13b36eb14324
convert/bzr: handle files replaced by directories (issue1623)
Patrick Mezard <pmezard@gmail.com>
parents:
8045
diff
changeset
|
195 changes.append((self.recode(paths[0]), revid)) |
13b36eb14324
convert/bzr: handle files replaced by directories (issue1623)
Patrick Mezard <pmezard@gmail.com>
parents:
8045
diff
changeset
|
196 |
15461
6ba2fc0a87ab
convert/bzr: correctly handle divergent nested renames (issue3089)
Patrick Mezard <pmezard@gmail.com>
parents:
12063
diff
changeset
|
197 if kind[0] == 'directory' and None not in paths: |
6ba2fc0a87ab
convert/bzr: correctly handle divergent nested renames (issue3089)
Patrick Mezard <pmezard@gmail.com>
parents:
12063
diff
changeset
|
198 renaming = paths[0] != paths[1] |
7053 | 199 # neither an add nor an delete - a move |
200 # rename all directory contents manually | |
201 subdir = origin.inventory.path2id(paths[0]) | |
202 # get all child-entries of the directory | |
203 for name, entry in origin.inventory.iter_entries(subdir): | |
204 # hg does not track directory renames | |
205 if entry.kind == 'directory': | |
206 continue | |
207 frompath = self.recode(paths[0] + '/' + name) | |
15461
6ba2fc0a87ab
convert/bzr: correctly handle divergent nested renames (issue3089)
Patrick Mezard <pmezard@gmail.com>
parents:
12063
diff
changeset
|
208 if frompath in seen: |
6ba2fc0a87ab
convert/bzr: correctly handle divergent nested renames (issue3089)
Patrick Mezard <pmezard@gmail.com>
parents:
12063
diff
changeset
|
209 # Already handled by a more specific change entry |
6ba2fc0a87ab
convert/bzr: correctly handle divergent nested renames (issue3089)
Patrick Mezard <pmezard@gmail.com>
parents:
12063
diff
changeset
|
210 # This is important when you have: |
6ba2fc0a87ab
convert/bzr: correctly handle divergent nested renames (issue3089)
Patrick Mezard <pmezard@gmail.com>
parents:
12063
diff
changeset
|
211 # a => b |
6ba2fc0a87ab
convert/bzr: correctly handle divergent nested renames (issue3089)
Patrick Mezard <pmezard@gmail.com>
parents:
12063
diff
changeset
|
212 # a/c => a/c |
6ba2fc0a87ab
convert/bzr: correctly handle divergent nested renames (issue3089)
Patrick Mezard <pmezard@gmail.com>
parents:
12063
diff
changeset
|
213 # Here a/c must not be renamed into b/c |
6ba2fc0a87ab
convert/bzr: correctly handle divergent nested renames (issue3089)
Patrick Mezard <pmezard@gmail.com>
parents:
12063
diff
changeset
|
214 continue |
6ba2fc0a87ab
convert/bzr: correctly handle divergent nested renames (issue3089)
Patrick Mezard <pmezard@gmail.com>
parents:
12063
diff
changeset
|
215 seen.add(frompath) |
6ba2fc0a87ab
convert/bzr: correctly handle divergent nested renames (issue3089)
Patrick Mezard <pmezard@gmail.com>
parents:
12063
diff
changeset
|
216 if not renaming: |
6ba2fc0a87ab
convert/bzr: correctly handle divergent nested renames (issue3089)
Patrick Mezard <pmezard@gmail.com>
parents:
12063
diff
changeset
|
217 continue |
7053 | 218 topath = self.recode(paths[1] + '/' + name) |
219 # register the files as changed | |
220 changes.append((frompath, revid)) | |
221 changes.append((topath, revid)) | |
222 # add to mode cache | |
10282
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10263
diff
changeset
|
223 mode = ((entry.executable and 'x') |
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10263
diff
changeset
|
224 or (entry.kind == 'symlink' and 's') |
7053 | 225 or '') |
226 self._modecache[(topath, revid)] = mode | |
227 # register the change as move | |
228 renames[topath] = frompath | |
229 | |
230 # no futher changes, go to the next change | |
231 continue | |
232 | |
233 # we got unicode paths, need to convert them | |
234 path, topath = [self.recode(part) for part in paths] | |
15461
6ba2fc0a87ab
convert/bzr: correctly handle divergent nested renames (issue3089)
Patrick Mezard <pmezard@gmail.com>
parents:
12063
diff
changeset
|
235 seen.add(path or topath) |
7053 | 236 |
237 if topath is None: | |
238 # file deleted | |
239 changes.append((path, revid)) | |
240 continue | |
241 | |
242 # renamed | |
243 if path and path != topath: | |
244 renames[topath] = path | |
8035
cb77c0fbec39
convert: remove renamed source files (issue1505)
Xavier ALT <dex@phoenix-ind.net>
parents:
7060
diff
changeset
|
245 changes.append((path, revid)) |
7053 | 246 |
247 # populate the mode cache | |
248 kind, executable = [e[1] for e in (kind, executable)] | |
8148
adce97d28389
convert/bzr: fix symlink handling (issue1626)
Patrick Mezard <pmezard@gmail.com>
parents:
8126
diff
changeset
|
249 mode = ((executable and 'x') or (kind == 'symlink' and 'l') |
7053 | 250 or '') |
251 self._modecache[(topath, revid)] = mode | |
252 changes.append((topath, revid)) | |
253 | |
254 return changes, renames | |
255 | |
256 def _filterghosts(self, ids): | |
257 """Filters out ghost revisions which hg does not support, see | |
258 <http://bazaar-vcs.org/GhostRevision> | |
259 """ | |
260 parentmap = self.sourcerepo.get_parent_map(ids) | |
7060
972cce34f345
convert: fixed python2.3 incompatibility in bzr source (generator expression)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
7053
diff
changeset
|
261 parents = tuple([parent for parent in ids if parent in parentmap]) |
7053 | 262 return parents |
263 | |
264 def recode(self, s, encoding=None): | |
265 """This version of recode tries to encode unicode to bytecode, | |
266 and preferably using the UTF-8 codec. | |
267 Other types than Unicode are silently returned, this is by | |
268 intention, e.g. the None-type is not going to be encoded but instead | |
269 just passed through | |
270 """ | |
271 if not encoding: | |
272 encoding = self.encoding or 'utf-8' | |
273 | |
274 if isinstance(s, unicode): | |
275 return s.encode(encoding) | |
276 else: | |
277 # leave it alone | |
278 return s |