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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 8784
diff changeset
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
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
8 # This module is for handling 'bzr', that was formerly known as Bazaar-NG;
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
9 # it cannot access 'bar' repositories, but they were never used very much
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
10
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
11 import os
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
12 from mercurial import demandimport
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
13 # these do not work with demandimport, blacklist
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
14 demandimport.ignore.extend([
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
15 'bzrlib.transactions',
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
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
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
18 ])
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
19
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
20 from mercurial.i18n import _
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
21 from mercurial import util
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
22 from common import NoRepo, commit, converter_source
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
23
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
24 try:
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
25 # bazaar imports
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
26 from bzrlib import branch, revision, errors
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
27 from bzrlib.revisionspec import RevisionSpec
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
28 except ImportError:
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
29 pass
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
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
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
33 class bzr_source(converter_source):
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
34 """Reads Bazaar repositories by using the Bazaar Python libraries"""
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
35
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
36 def __init__(self, ui, path, rev=None):
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
37 super(bzr_source, self).__init__(ui, path, rev=rev)
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
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
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
43 try:
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
44 # access bzrlib stuff
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
45 branch
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
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
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
48
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
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
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
51 self.branch = branch.Branch.open(path)
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
52 self.sourcerepo = self.branch.repository
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
53 self._parentids = {}
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
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
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
75 def before(self):
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
76 """Before the conversion begins, acquire a read lock
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
77 for all the operations that might need it. Fortunately
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
78 read locks don't block other reads or writes to the
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
79 repository, so this shouldn't have any impact on the usage of
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
80 the source repository.
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
81
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
82 The alternative would be locking on every operation that
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
83 needs locks (there are currently two: getting the file and
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
84 getting the parent map) and releasing immediately after,
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
85 but this approach can take even 40% longer."""
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
86 self.sourcerepo.lock_read()
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
87
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
88 def after(self):
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
89 self.sourcerepo.unlock()
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
90
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
91 def getheads(self):
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
92 if not self.rev:
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
93 return [self.branch.last_revision()]
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
94 try:
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
95 r = RevisionSpec.from_string(self.rev)
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
96 info = r.in_history(self.branch)
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
97 except errors.BzrError:
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
98 raise util.Abort(_('%s is not a valid revision in current branch')
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
99 % self.rev)
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
100 return [info.rev_id]
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
101
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
102 def getfile(self, name, rev):
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
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
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
109 # the file is not available anymore - was deleted
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
110 raise IOError(_('%s is not available in %s anymore') %
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
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
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
122
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
123 def getchanges(self, version):
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
124 # set up caches: modecache and revtree
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
125 self._modecache = {}
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
126 self._revtree = self.sourcerepo.revision_tree(version)
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
127 # get the parentids from the cache
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
128 parentids = self._parentids.pop(version)
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
129 # only diff against first parent id
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
130 prevtree = self.sourcerepo.revision_tree(parentids[0])
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
131 return self._gettreechanges(self._revtree, prevtree)
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
132
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
133 def getcommit(self, version):
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
134 rev = self.sourcerepo.get_revision(version)
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
135 # populate parent id cache
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
136 if not rev.parent_ids:
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
137 parents = []
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
138 self._parentids[version] = (revision.NULL_REVISION,)
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
139 else:
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
140 parents = self._filterghosts(rev.parent_ids)
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
141 self._parentids[version] = parents
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
142
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
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
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
145 author=self.recode(rev.committer),
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
146 # bzr returns bytestrings or unicode, depending on the content
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
147 desc=self.recode(rev.message),
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
148 rev=version)
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
149
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
150 def gettags(self):
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
151 if not self.branch.supports_tags():
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
152 return {}
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
153 tagdict = self.branch.tags.get_tag_dict()
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
154 bytetags = {}
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
155 for name, rev in tagdict.iteritems():
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
156 bytetags[self.recode(name)] = rev
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
157 return bytetags
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
158
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
159 def getchangedfiles(self, rev, i):
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
160 self._modecache = {}
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
161 curtree = self.sourcerepo.revision_tree(rev)
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
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
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
164 else:
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
165 # no parent id, get the empty revision
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
166 parentid = revision.NULL_REVISION
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
167
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
168 prevtree = self.sourcerepo.revision_tree(parentid)
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
169 changes = [e[0] for e in self._gettreechanges(curtree, prevtree)[0]]
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
170 return changes
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
171
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
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
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
174 changes = []
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
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
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
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
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
184
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
185 if paths[0] == u'' or paths[1] == u'':
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
186 # ignore changes to tree root
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
187 continue
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
188
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
189 # bazaar tracks directories, mercurial does not, so
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
190 # we have to rename the directory contents
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
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
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
199 # neither an add nor an delete - a move
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
200 # rename all directory contents manually
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
201 subdir = origin.inventory.path2id(paths[0])
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
202 # get all child-entries of the directory
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
203 for name, entry in origin.inventory.iter_entries(subdir):
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
204 # hg does not track directory renames
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
205 if entry.kind == 'directory':
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
206 continue
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
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
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
218 topath = self.recode(paths[1] + '/' + name)
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
219 # register the files as changed
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
220 changes.append((frompath, revid))
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
221 changes.append((topath, revid))
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
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
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
225 or '')
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
226 self._modecache[(topath, revid)] = mode
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
227 # register the change as move
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
228 renames[topath] = frompath
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
229
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
230 # no futher changes, go to the next change
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
231 continue
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
232
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
233 # we got unicode paths, need to convert them
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
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
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
236
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
237 if topath is None:
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
238 # file deleted
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
239 changes.append((path, revid))
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
240 continue
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
241
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
242 # renamed
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
243 if path and path != topath:
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
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
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
246
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
247 # populate the mode cache
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
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
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
250 or '')
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
251 self._modecache[(topath, revid)] = mode
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
252 changes.append((topath, revid))
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
253
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
254 return changes, renames
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
255
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
256 def _filterghosts(self, ids):
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
257 """Filters out ghost revisions which hg does not support, see
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
258 <http://bazaar-vcs.org/GhostRevision>
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
259 """
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
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
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
262 return parents
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
263
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
264 def recode(self, s, encoding=None):
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
265 """This version of recode tries to encode unicode to bytecode,
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
266 and preferably using the UTF-8 codec.
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
267 Other types than Unicode are silently returned, this is by
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
268 intention, e.g. the None-type is not going to be encoded but instead
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
269 just passed through
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
270 """
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
271 if not encoding:
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
272 encoding = self.encoding or 'utf-8'
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
273
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
274 if isinstance(s, unicode):
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
275 return s.encode(encoding)
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
276 else:
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
277 # leave it alone
209ef5f3534c convert: add bzr source
Marek Kubica <marek@xivilization.net>
parents:
diff changeset
278 return s