Show More
@@ -0,0 +1,216 b'' | |||
|
1 | # bzr support for the convert extension | |
|
2 | # This module is for handling 'bzr', that was formerly known as Bazaar-NG; | |
|
3 | # it cannot access 'bar' repositories, but they were never used very much | |
|
4 | ||
|
5 | import os | |
|
6 | from mercurial import demandimport | |
|
7 | # these do not work with demandimport, blacklist | |
|
8 | demandimport.ignore.extend([ | |
|
9 | 'bzrlib.transactions', | |
|
10 | 'bzrlib.urlutils', | |
|
11 | ]) | |
|
12 | ||
|
13 | from mercurial.i18n import _ | |
|
14 | from mercurial import util | |
|
15 | from common import NoRepo, commit, converter_source | |
|
16 | ||
|
17 | try: | |
|
18 | # bazaar imports | |
|
19 | from bzrlib import branch, revision, errors | |
|
20 | from bzrlib.revisionspec import RevisionSpec | |
|
21 | except ImportError: | |
|
22 | pass | |
|
23 | ||
|
24 | class bzr_source(converter_source): | |
|
25 | """Reads Bazaar repositories by using the Bazaar Python libraries""" | |
|
26 | ||
|
27 | def __init__(self, ui, path, rev=None): | |
|
28 | super(bzr_source, self).__init__(ui, path, rev=rev) | |
|
29 | ||
|
30 | try: | |
|
31 | # access bzrlib stuff | |
|
32 | branch | |
|
33 | except NameError: | |
|
34 | raise NoRepo('Bazaar modules could not be loaded') | |
|
35 | ||
|
36 | if not os.path.exists(os.path.join(path, '.bzr')): | |
|
37 | raise NoRepo('%s does not look like a Bazaar repo' % path) | |
|
38 | ||
|
39 | path = os.path.abspath(path) | |
|
40 | self.branch = branch.Branch.open(path) | |
|
41 | self.sourcerepo = self.branch.repository | |
|
42 | self._parentids = {} | |
|
43 | ||
|
44 | def before(self): | |
|
45 | """Before the conversion begins, acquire a read lock | |
|
46 | for all the operations that might need it. Fortunately | |
|
47 | read locks don't block other reads or writes to the | |
|
48 | repository, so this shouldn't have any impact on the usage of | |
|
49 | the source repository. | |
|
50 | ||
|
51 | The alternative would be locking on every operation that | |
|
52 | needs locks (there are currently two: getting the file and | |
|
53 | getting the parent map) and releasing immediately after, | |
|
54 | but this approach can take even 40% longer.""" | |
|
55 | self.sourcerepo.lock_read() | |
|
56 | ||
|
57 | def after(self): | |
|
58 | self.sourcerepo.unlock() | |
|
59 | ||
|
60 | def getheads(self): | |
|
61 | if not self.rev: | |
|
62 | return [self.branch.last_revision()] | |
|
63 | try: | |
|
64 | r = RevisionSpec.from_string(self.rev) | |
|
65 | info = r.in_history(self.branch) | |
|
66 | except errors.BzrError: | |
|
67 | raise util.Abort(_('%s is not a valid revision in current branch') | |
|
68 | % self.rev) | |
|
69 | return [info.rev_id] | |
|
70 | ||
|
71 | def getfile(self, name, rev): | |
|
72 | revtree = self.sourcerepo.revision_tree(rev) | |
|
73 | fileid = revtree.path2id(name) | |
|
74 | if fileid is None: | |
|
75 | # the file is not available anymore - was deleted | |
|
76 | raise IOError(_('%s is not available in %s anymore') % | |
|
77 | (name, rev)) | |
|
78 | sio = revtree.get_file(fileid) | |
|
79 | return sio.read() | |
|
80 | ||
|
81 | def getmode(self, name, rev): | |
|
82 | return self._modecache[(name, rev)] | |
|
83 | ||
|
84 | def getchanges(self, version): | |
|
85 | # set up caches: modecache and revtree | |
|
86 | self._modecache = {} | |
|
87 | self._revtree = self.sourcerepo.revision_tree(version) | |
|
88 | # get the parentids from the cache | |
|
89 | parentids = self._parentids.pop(version) | |
|
90 | # only diff against first parent id | |
|
91 | prevtree = self.sourcerepo.revision_tree(parentids[0]) | |
|
92 | return self._gettreechanges(self._revtree, prevtree) | |
|
93 | ||
|
94 | def getcommit(self, version): | |
|
95 | rev = self.sourcerepo.get_revision(version) | |
|
96 | # populate parent id cache | |
|
97 | if not rev.parent_ids: | |
|
98 | parents = [] | |
|
99 | self._parentids[version] = (revision.NULL_REVISION,) | |
|
100 | else: | |
|
101 | parents = self._filterghosts(rev.parent_ids) | |
|
102 | self._parentids[version] = parents | |
|
103 | ||
|
104 | return commit(parents=parents, | |
|
105 | # bzr uses 1 second timezone precision | |
|
106 | date='%d %d' % (rev.timestamp, rev.timezone / 3600), | |
|
107 | author=self.recode(rev.committer), | |
|
108 | # bzr returns bytestrings or unicode, depending on the content | |
|
109 | desc=self.recode(rev.message), | |
|
110 | rev=version) | |
|
111 | ||
|
112 | def gettags(self): | |
|
113 | if not self.branch.supports_tags(): | |
|
114 | return {} | |
|
115 | tagdict = self.branch.tags.get_tag_dict() | |
|
116 | bytetags = {} | |
|
117 | for name, rev in tagdict.iteritems(): | |
|
118 | bytetags[self.recode(name)] = rev | |
|
119 | return bytetags | |
|
120 | ||
|
121 | def getchangedfiles(self, rev, i): | |
|
122 | self._modecache = {} | |
|
123 | curtree = self.sourcerepo.revision_tree(rev) | |
|
124 | parentids = self._parentids.pop(rev) | |
|
125 | if i is not None: | |
|
126 | parentid = parentids[i] | |
|
127 | else: | |
|
128 | # no parent id, get the empty revision | |
|
129 | parentid = revision.NULL_REVISION | |
|
130 | ||
|
131 | prevtree = self.sourcerepo.revision_tree(parentid) | |
|
132 | changes = [e[0] for e in self._gettreechanges(curtree, prevtree)[0]] | |
|
133 | return changes | |
|
134 | ||
|
135 | def _gettreechanges(self, current, origin): | |
|
136 | revid = current._revision_id; | |
|
137 | changes = [] | |
|
138 | renames = {} | |
|
139 | for (fileid, paths, changed_content, versioned, parent, name, | |
|
140 | kind, executable) in current.iter_changes(origin): | |
|
141 | ||
|
142 | if paths[0] == u'' or paths[1] == u'': | |
|
143 | # ignore changes to tree root | |
|
144 | continue | |
|
145 | ||
|
146 | # bazaar tracks directories, mercurial does not, so | |
|
147 | # we have to rename the directory contents | |
|
148 | if kind[1] == 'directory': | |
|
149 | if None not in paths and paths[0] != paths[1]: | |
|
150 | # neither an add nor an delete - a move | |
|
151 | # rename all directory contents manually | |
|
152 | subdir = origin.inventory.path2id(paths[0]) | |
|
153 | # get all child-entries of the directory | |
|
154 | for name, entry in origin.inventory.iter_entries(subdir): | |
|
155 | # hg does not track directory renames | |
|
156 | if entry.kind == 'directory': | |
|
157 | continue | |
|
158 | frompath = self.recode(paths[0] + '/' + name) | |
|
159 | topath = self.recode(paths[1] + '/' + name) | |
|
160 | # register the files as changed | |
|
161 | changes.append((frompath, revid)) | |
|
162 | changes.append((topath, revid)) | |
|
163 | # add to mode cache | |
|
164 | mode = ((entry.executable and 'x') or (entry.kind == 'symlink' and 's') | |
|
165 | or '') | |
|
166 | self._modecache[(topath, revid)] = mode | |
|
167 | # register the change as move | |
|
168 | renames[topath] = frompath | |
|
169 | ||
|
170 | # no futher changes, go to the next change | |
|
171 | continue | |
|
172 | ||
|
173 | # we got unicode paths, need to convert them | |
|
174 | path, topath = [self.recode(part) for part in paths] | |
|
175 | ||
|
176 | if topath is None: | |
|
177 | # file deleted | |
|
178 | changes.append((path, revid)) | |
|
179 | continue | |
|
180 | ||
|
181 | # renamed | |
|
182 | if path and path != topath: | |
|
183 | renames[topath] = path | |
|
184 | ||
|
185 | # populate the mode cache | |
|
186 | kind, executable = [e[1] for e in (kind, executable)] | |
|
187 | mode = ((executable and 'x') or (kind == 'symlink' and 's') | |
|
188 | or '') | |
|
189 | self._modecache[(topath, revid)] = mode | |
|
190 | changes.append((topath, revid)) | |
|
191 | ||
|
192 | return changes, renames | |
|
193 | ||
|
194 | def _filterghosts(self, ids): | |
|
195 | """Filters out ghost revisions which hg does not support, see | |
|
196 | <http://bazaar-vcs.org/GhostRevision> | |
|
197 | """ | |
|
198 | parentmap = self.sourcerepo.get_parent_map(ids) | |
|
199 | parents = tuple(parent for parent in ids if parent in parentmap) | |
|
200 | return parents | |
|
201 | ||
|
202 | def recode(self, s, encoding=None): | |
|
203 | """This version of recode tries to encode unicode to bytecode, | |
|
204 | and preferably using the UTF-8 codec. | |
|
205 | Other types than Unicode are silently returned, this is by | |
|
206 | intention, e.g. the None-type is not going to be encoded but instead | |
|
207 | just passed through | |
|
208 | """ | |
|
209 | if not encoding: | |
|
210 | encoding = self.encoding or 'utf-8' | |
|
211 | ||
|
212 | if isinstance(s, unicode): | |
|
213 | return s.encode(encoding) | |
|
214 | else: | |
|
215 | # leave it alone | |
|
216 | return s |
@@ -0,0 +1,18 b'' | |||
|
1 | # this file holds the definitions that are used in various bzr tests | |
|
2 | ||
|
3 | "$TESTDIR/hghave" bzr || exit 80 | |
|
4 | ||
|
5 | echo '[extensions]' >> $HGRCPATH | |
|
6 | echo 'convert = ' >> $HGRCPATH | |
|
7 | echo 'hgext.graphlog = ' >> $HGRCPATH | |
|
8 | ||
|
9 | glog() | |
|
10 | { | |
|
11 | hg glog --template '#rev# "#desc|firstline#" files: #files#\n' "$@" | |
|
12 | } | |
|
13 | ||
|
14 | manifest() | |
|
15 | { | |
|
16 | echo "% manifest of $2" | |
|
17 | hg -R $1 manifest -v -r $2 | |
|
18 | } |
@@ -0,0 +1,81 b'' | |||
|
1 | #!/bin/sh | |
|
2 | ||
|
3 | source "$TESTDIR/bzr-definitions" | |
|
4 | ||
|
5 | echo % create and rename on the same file in the same step | |
|
6 | mkdir test-createandrename | |
|
7 | cd test-createandrename | |
|
8 | bzr init -q source | |
|
9 | cd source | |
|
10 | echo a > a | |
|
11 | bzr add -q a | |
|
12 | bzr commit -q -m 'Initial add: a' | |
|
13 | bzr mv a b | |
|
14 | echo a2 >> a | |
|
15 | bzr add -q a | |
|
16 | bzr commit -q -m 'rename a into b, create a' | |
|
17 | cd .. | |
|
18 | hg convert source source-hg | |
|
19 | glog -R source-hg | |
|
20 | echo "% test --rev option" | |
|
21 | hg convert -r 1 source source-1-hg | |
|
22 | glog -R source-1-hg | |
|
23 | cd .. | |
|
24 | ||
|
25 | echo % merge | |
|
26 | mkdir test-merge | |
|
27 | cd test-merge | |
|
28 | ||
|
29 | cat > helper.py <<EOF | |
|
30 | import sys | |
|
31 | from bzrlib import workingtree | |
|
32 | wt = workingtree.WorkingTree.open('.') | |
|
33 | ||
|
34 | message, stamp = sys.argv[1:] | |
|
35 | wt.commit(message, timestamp=int(stamp)) | |
|
36 | EOF | |
|
37 | ||
|
38 | bzr init -q source | |
|
39 | cd source | |
|
40 | echo content > a | |
|
41 | echo content2 > b | |
|
42 | bzr add -q a b | |
|
43 | bzr commit -q -m 'Initial add' | |
|
44 | cd .. | |
|
45 | bzr branch -q source source-improve | |
|
46 | cd source | |
|
47 | echo more >> a | |
|
48 | python ../helper.py 'Editing a' 100 | |
|
49 | cd ../source-improve | |
|
50 | echo content3 >> b | |
|
51 | python ../helper.py 'Editing b' 200 | |
|
52 | cd ../source | |
|
53 | bzr merge -q ../source-improve | |
|
54 | bzr commit -q -m 'Merged improve branch' | |
|
55 | cd .. | |
|
56 | hg convert --datesort source source-hg | |
|
57 | glog -R source-hg | |
|
58 | cd .. | |
|
59 | ||
|
60 | echo % symlinks and executable files | |
|
61 | mkdir test-symlinks | |
|
62 | cd test-symlinks | |
|
63 | bzr init -q source | |
|
64 | cd source | |
|
65 | touch program | |
|
66 | chmod +x program | |
|
67 | ln -s program altname | |
|
68 | bzr add -q altname program | |
|
69 | bzr commit -q -m 'Initial setup' | |
|
70 | touch newprog | |
|
71 | chmod +x newprog | |
|
72 | rm altname | |
|
73 | ln -s newprog altname | |
|
74 | chmod -x program | |
|
75 | bzr add -q newprog | |
|
76 | bzr commit -q -m 'Symlink changed, x bits changed' | |
|
77 | cd .. | |
|
78 | hg convert source source-hg | |
|
79 | manifest source-hg 0 | |
|
80 | manifest source-hg tip | |
|
81 | cd .. |
@@ -0,0 +1,93 b'' | |||
|
1 | #!/bin/sh | |
|
2 | ||
|
3 | source "$TESTDIR/bzr-definitions" | |
|
4 | ||
|
5 | echo % empty directory | |
|
6 | mkdir test-empty | |
|
7 | cd test-empty | |
|
8 | bzr init -q source | |
|
9 | cd source | |
|
10 | echo content > a | |
|
11 | bzr add -q a | |
|
12 | bzr commit -q -m 'Initial add' | |
|
13 | mkdir empty | |
|
14 | bzr add -q empty | |
|
15 | bzr commit -q -m 'Empty directory added' | |
|
16 | echo content > empty/something | |
|
17 | bzr add -q empty/something | |
|
18 | bzr commit -q -m 'Added file into directory' | |
|
19 | cd .. | |
|
20 | hg convert source source-hg | |
|
21 | manifest source-hg 1 | |
|
22 | manifest source-hg tip | |
|
23 | cd .. | |
|
24 | ||
|
25 | echo % directory renames | |
|
26 | mkdir test-dir-rename | |
|
27 | cd test-dir-rename | |
|
28 | bzr init -q source | |
|
29 | cd source | |
|
30 | mkdir tpyo | |
|
31 | echo content > tpyo/something | |
|
32 | bzr add -q tpyo | |
|
33 | bzr commit -q -m 'Added directory' | |
|
34 | bzr mv tpyo typo | |
|
35 | bzr commit -q -m 'Oops, typo' | |
|
36 | cd .. | |
|
37 | hg convert source source-hg | |
|
38 | manifest source-hg 0 | |
|
39 | manifest source-hg tip | |
|
40 | cd .. | |
|
41 | ||
|
42 | echo % nested directory renames | |
|
43 | mkdir test-nested-dir-rename | |
|
44 | cd test-nested-dir-rename | |
|
45 | bzr init -q source | |
|
46 | cd source | |
|
47 | mkdir -p firstlevel/secondlevel/thirdlevel | |
|
48 | echo content > firstlevel/secondlevel/file | |
|
49 | echo this_needs_to_be_there_too > firstlevel/secondlevel/thirdlevel/stuff | |
|
50 | bzr add -q firstlevel | |
|
51 | bzr commit -q -m 'Added nested directories' | |
|
52 | bzr mv firstlevel/secondlevel secondlevel | |
|
53 | bzr commit -q -m 'Moved secondlevel one level up' | |
|
54 | cd .. | |
|
55 | hg convert source source-hg | |
|
56 | manifest source-hg tip | |
|
57 | cd .. | |
|
58 | ||
|
59 | echo % directory remove | |
|
60 | mkdir test-dir-remove | |
|
61 | cd test-dir-remove | |
|
62 | bzr init -q source | |
|
63 | cd source | |
|
64 | mkdir src | |
|
65 | echo content > src/sourcecode | |
|
66 | bzr add -q src | |
|
67 | bzr commit -q -m 'Added directory' | |
|
68 | bzr rm -q src | |
|
69 | bzr commit -q -m 'Removed directory' | |
|
70 | cd .. | |
|
71 | hg convert source source-hg | |
|
72 | manifest source-hg 0 | |
|
73 | manifest source-hg tip | |
|
74 | cd .. | |
|
75 | ||
|
76 | echo % directory replace | |
|
77 | mkdir test-dir-replace | |
|
78 | cd test-dir-replace | |
|
79 | bzr init -q source | |
|
80 | cd source | |
|
81 | mkdir first second | |
|
82 | echo content > first/file | |
|
83 | echo morecontent > first/dummy | |
|
84 | echo othercontent > second/something | |
|
85 | bzr add -q first second | |
|
86 | bzr commit -q -m 'Initial layout' | |
|
87 | bzr mv first/file second/file | |
|
88 | bzr mv first third | |
|
89 | bzr commit -q -m 'Some conflicting moves' | |
|
90 | cd .. | |
|
91 | hg convert source source-hg | |
|
92 | manifest source-hg tip | |
|
93 | cd .. |
@@ -0,0 +1,59 b'' | |||
|
1 | % empty directory | |
|
2 | initializing destination source-hg repository | |
|
3 | scanning source... | |
|
4 | sorting... | |
|
5 | converting... | |
|
6 | 2 Initial add | |
|
7 | 1 Empty directory added | |
|
8 | 0 Added file into directory | |
|
9 | % manifest of 1 | |
|
10 | 644 a | |
|
11 | % manifest of tip | |
|
12 | 644 a | |
|
13 | 644 empty/something | |
|
14 | % directory renames | |
|
15 | tpyo => typo | |
|
16 | initializing destination source-hg repository | |
|
17 | scanning source... | |
|
18 | sorting... | |
|
19 | converting... | |
|
20 | 1 Added directory | |
|
21 | 0 Oops, typo | |
|
22 | % manifest of 0 | |
|
23 | 644 tpyo/something | |
|
24 | % manifest of tip | |
|
25 | 644 typo/something | |
|
26 | % nested directory renames | |
|
27 | firstlevel/secondlevel => secondlevel | |
|
28 | initializing destination source-hg repository | |
|
29 | scanning source... | |
|
30 | sorting... | |
|
31 | converting... | |
|
32 | 1 Added nested directories | |
|
33 | 0 Moved secondlevel one level up | |
|
34 | % manifest of tip | |
|
35 | 644 secondlevel/file | |
|
36 | 644 secondlevel/thirdlevel/stuff | |
|
37 | % directory remove | |
|
38 | initializing destination source-hg repository | |
|
39 | scanning source... | |
|
40 | sorting... | |
|
41 | converting... | |
|
42 | 1 Added directory | |
|
43 | 0 Removed directory | |
|
44 | % manifest of 0 | |
|
45 | 644 src/sourcecode | |
|
46 | % manifest of tip | |
|
47 | % directory replace | |
|
48 | first/file => second/file | |
|
49 | first => third | |
|
50 | initializing destination source-hg repository | |
|
51 | scanning source... | |
|
52 | sorting... | |
|
53 | converting... | |
|
54 | 1 Initial layout | |
|
55 | 0 Some conflicting moves | |
|
56 | % manifest of tip | |
|
57 | 644 second/file | |
|
58 | 644 second/something | |
|
59 | 644 third/dummy |
@@ -0,0 +1,27 b'' | |||
|
1 | #!/bin/sh | |
|
2 | ||
|
3 | source "$TESTDIR/bzr-definitions" | |
|
4 | ||
|
5 | cat > ghostcreator.py <<EOF | |
|
6 | import sys | |
|
7 | from bzrlib import workingtree | |
|
8 | wt = workingtree.WorkingTree.open('.') | |
|
9 | ||
|
10 | message, ghostrev = sys.argv[1:] | |
|
11 | wt.set_parent_ids(wt.get_parent_ids() + [ghostrev]) | |
|
12 | wt.commit(message) | |
|
13 | EOF | |
|
14 | ||
|
15 | echo % ghost revisions | |
|
16 | mkdir test-ghost-revisions | |
|
17 | cd test-ghost-revisions | |
|
18 | bzr init -q source | |
|
19 | cd source | |
|
20 | echo content > somefile | |
|
21 | bzr add -q somefile | |
|
22 | bzr commit -q -m 'Initial layout setup' | |
|
23 | echo morecontent >> somefile | |
|
24 | python ../../ghostcreator.py 'Commit with ghost revision' ghostrev | |
|
25 | cd .. | |
|
26 | hg convert source source-hg | |
|
27 | glog -R source-hg |
@@ -0,0 +1,11 b'' | |||
|
1 | % ghost revisions | |
|
2 | initializing destination source-hg repository | |
|
3 | scanning source... | |
|
4 | sorting... | |
|
5 | converting... | |
|
6 | 1 Initial layout setup | |
|
7 | 0 Commit with ghost revision | |
|
8 | o 1 "Commit with ghost revision" files: somefile | |
|
9 | | | |
|
10 | o 0 "Initial layout setup" files: somefile | |
|
11 |
@@ -0,0 +1,37 b'' | |||
|
1 | #!/bin/sh | |
|
2 | ||
|
3 | source "$TESTDIR/bzr-definitions" | |
|
4 | ||
|
5 | echo % test multiple merges at once | |
|
6 | mkdir test-multimerge | |
|
7 | cd test-multimerge | |
|
8 | bzr init -q source | |
|
9 | cd source | |
|
10 | echo content > file | |
|
11 | bzr add -q file | |
|
12 | bzr commit -q -m 'Initial add' | |
|
13 | cd .. | |
|
14 | bzr branch -q source source-branch1 | |
|
15 | cd source-branch1 | |
|
16 | echo morecontent >> file | |
|
17 | echo evenmorecontent > file-branch1 | |
|
18 | bzr add -q file-branch1 | |
|
19 | bzr commit -q -m 'Added branch1 file' | |
|
20 | cd ../source | |
|
21 | echo content > file-parent | |
|
22 | bzr add -q file-parent | |
|
23 | bzr commit -q -m 'Added parent file' | |
|
24 | cd .. | |
|
25 | bzr branch -q source source-branch2 | |
|
26 | cd source-branch2 | |
|
27 | echo somecontent > file-branch2 | |
|
28 | bzr add -q file-branch2 | |
|
29 | bzr commit -q -m 'Added brach2 file' | |
|
30 | cd ../source | |
|
31 | bzr merge -q ../source-branch1 | |
|
32 | bzr merge -q --force ../source-branch2 | |
|
33 | bzr commit -q -m 'Merged branches' | |
|
34 | cd .. | |
|
35 | hg convert --datesort source source-hg | |
|
36 | glog -R source-hg | |
|
37 | manifest source-hg tip |
@@ -0,0 +1,27 b'' | |||
|
1 | % test multiple merges at once | |
|
2 | initializing destination source-hg repository | |
|
3 | scanning source... | |
|
4 | sorting... | |
|
5 | converting... | |
|
6 | 4 Initial add | |
|
7 | 3 Added branch1 file | |
|
8 | 2 Added parent file | |
|
9 | 1 Added brach2 file | |
|
10 | 0 Merged branches | |
|
11 | o 5 "(octopus merge fixup)" files: | |
|
12 | |\ | |
|
13 | | o 4 "Merged branches" files: file-branch2 | |
|
14 | | |\ | |
|
15 | o---+ 3 "Added brach2 file" files: file-branch2 | |
|
16 | / / | |
|
17 | | o 2 "Added parent file" files: file-parent | |
|
18 | | | | |
|
19 | o | 1 "Added branch1 file" files: file file-branch1 | |
|
20 | |/ | |
|
21 | o 0 "Initial add" files: file | |
|
22 | ||
|
23 | % manifest of tip | |
|
24 | 644 file | |
|
25 | 644 file-branch1 | |
|
26 | 644 file-branch2 | |
|
27 | 644 file-parent |
@@ -0,0 +1,26 b'' | |||
|
1 | #!/bin/sh | |
|
2 | ||
|
3 | source "$TESTDIR/bzr-definitions" | |
|
4 | ||
|
5 | cat > treeset.py <<EOF | |
|
6 | import sys | |
|
7 | from bzrlib import workingtree | |
|
8 | wt = workingtree.WorkingTree.open('.') | |
|
9 | ||
|
10 | message, rootid = sys.argv[1:] | |
|
11 | wt.set_root_id('tree_root-%s' % rootid) | |
|
12 | wt.commit(message) | |
|
13 | EOF | |
|
14 | ||
|
15 | echo % change the id of the tree root | |
|
16 | mkdir test-change-treeroot-id | |
|
17 | cd test-change-treeroot-id | |
|
18 | bzr init -q source | |
|
19 | cd source | |
|
20 | echo content > file | |
|
21 | bzr add -q file | |
|
22 | bzr commit -q -m 'Initial add' | |
|
23 | python ../../treeset.py 'Changed root' new | |
|
24 | cd .. | |
|
25 | hg convert source source-hg | |
|
26 | manifest source-hg tip |
@@ -0,0 +1,9 b'' | |||
|
1 | % change the id of the tree root | |
|
2 | initializing destination source-hg repository | |
|
3 | scanning source... | |
|
4 | sorting... | |
|
5 | converting... | |
|
6 | 1 Initial add | |
|
7 | 0 Changed root | |
|
8 | % manifest of tip | |
|
9 | 644 file |
@@ -0,0 +1,51 b'' | |||
|
1 | % create and rename on the same file in the same step | |
|
2 | a => b | |
|
3 | initializing destination source-hg repository | |
|
4 | scanning source... | |
|
5 | sorting... | |
|
6 | converting... | |
|
7 | 1 Initial add: a | |
|
8 | 0 rename a into b, create a | |
|
9 | o 1 "rename a into b, create a" files: a b | |
|
10 | | | |
|
11 | o 0 "Initial add: a" files: a | |
|
12 | ||
|
13 | % test --rev option | |
|
14 | initializing destination source-1-hg repository | |
|
15 | scanning source... | |
|
16 | sorting... | |
|
17 | converting... | |
|
18 | 0 Initial add: a | |
|
19 | o 0 "Initial add: a" files: a | |
|
20 | ||
|
21 | % merge | |
|
22 | initializing destination source-hg repository | |
|
23 | scanning source... | |
|
24 | sorting... | |
|
25 | converting... | |
|
26 | 3 Initial add | |
|
27 | 2 Editing a | |
|
28 | 1 Editing b | |
|
29 | 0 Merged improve branch | |
|
30 | o 3 "Merged improve branch" files: | |
|
31 | |\ | |
|
32 | | o 2 "Editing b" files: b | |
|
33 | | | | |
|
34 | o | 1 "Editing a" files: a | |
|
35 | |/ | |
|
36 | o 0 "Initial add" files: a b | |
|
37 | ||
|
38 | % symlinks and executable files | |
|
39 | initializing destination source-hg repository | |
|
40 | scanning source... | |
|
41 | sorting... | |
|
42 | converting... | |
|
43 | 1 Initial setup | |
|
44 | 0 Symlink changed, x bits changed | |
|
45 | % manifest of 0 | |
|
46 | 644 altname | |
|
47 | 755 * program | |
|
48 | % manifest of tip | |
|
49 | 644 altname | |
|
50 | 755 * newprog | |
|
51 | 644 program |
@@ -23,6 +23,7 b' def convert(ui, src, dest=None, revmapfi' | |||
|
23 | 23 | - Subversion [svn] |
|
24 | 24 | - Monotone [mtn] |
|
25 | 25 | - GNU Arch [gnuarch] |
|
26 | - Bazaar [bzr] | |
|
26 | 27 | |
|
27 | 28 | Accepted destination formats [identifiers]: |
|
28 | 29 | - Mercurial [hg] |
@@ -13,6 +13,7 b' from hg import mercurial_source, mercuri' | |||
|
13 | 13 | from subversion import debugsvnlog, svn_source, svn_sink |
|
14 | 14 | from monotone import monotone_source |
|
15 | 15 | from gnuarch import gnuarch_source |
|
16 | from bzr import bzr_source | |
|
16 | 17 | import filemap |
|
17 | 18 | |
|
18 | 19 | import os, shutil |
@@ -35,6 +36,7 b' source_converters = [' | |||
|
35 | 36 | ('darcs', darcs_source), |
|
36 | 37 | ('mtn', monotone_source), |
|
37 | 38 | ('gnuarch', gnuarch_source), |
|
39 | ('bzr', bzr_source), | |
|
38 | 40 | ] |
|
39 | 41 | |
|
40 | 42 | sink_converters = [ |
@@ -24,6 +24,9 b' def matchoutput(cmd, regexp, ignorestatu' | |||
|
24 | 24 | def has_baz(): |
|
25 | 25 | return matchoutput('baz --version 2>&1', r'baz Bazaar version') |
|
26 | 26 | |
|
27 | def has_bzr(): | |
|
28 | return matchoutput('bzr --version 2>&1', r'Bazaar \(bzr\)') | |
|
29 | ||
|
27 | 30 | def has_cvs(): |
|
28 | 31 | re = r'Concurrent Versions System.*?server' |
|
29 | 32 | return matchoutput('cvs --version 2>&1', re) |
@@ -146,6 +149,7 b' def has_pygments():' | |||
|
146 | 149 | |
|
147 | 150 | checks = { |
|
148 | 151 | "baz": (has_baz, "GNU Arch baz client"), |
|
152 | "bzr": (has_bzr, "Canonical's Bazaar client"), | |
|
149 | 153 | "cvs": (has_cvs, "cvs client/server"), |
|
150 | 154 | "cvsps": (has_cvsps, "cvsps utility"), |
|
151 | 155 | "darcs": (has_darcs, "darcs client"), |
General Comments 0
You need to be logged in to leave comments.
Login now