##// END OF EJS Templates
convert/bzr: convert all branches (issue3229) (BC)...
Patrick Mezard -
r16060:f84dda15 default
parent child Browse files
Show More
@@ -1,265 +1,280
1 # bzr.py - bzr support for the convert extension
1 # bzr.py - bzr support for the convert extension
2 #
2 #
3 # Copyright 2008, 2009 Marek Kubica <marek@xivilization.net> and others
3 # Copyright 2008, 2009 Marek Kubica <marek@xivilization.net> and others
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 # This module is for handling 'bzr', that was formerly known as Bazaar-NG;
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
9 # it cannot access 'bar' repositories, but they were never used very much
10
10
11 import os
11 import os
12 from mercurial import demandimport
12 from mercurial import demandimport
13 # these do not work with demandimport, blacklist
13 # these do not work with demandimport, blacklist
14 demandimport.ignore.extend([
14 demandimport.ignore.extend([
15 'bzrlib.transactions',
15 'bzrlib.transactions',
16 'bzrlib.urlutils',
16 'bzrlib.urlutils',
17 'ElementPath',
17 'ElementPath',
18 ])
18 ])
19
19
20 from mercurial.i18n import _
20 from mercurial.i18n import _
21 from mercurial import util
21 from mercurial import util
22 from common import NoRepo, commit, converter_source
22 from common import NoRepo, commit, converter_source
23
23
24 try:
24 try:
25 # bazaar imports
25 # bazaar imports
26 from bzrlib import branch, revision, errors
26 from bzrlib import bzrdir, revision, errors
27 from bzrlib.revisionspec import RevisionSpec
27 from bzrlib.revisionspec import RevisionSpec
28 except ImportError:
28 except ImportError:
29 pass
29 pass
30
30
31 supportedkinds = ('file', 'symlink')
31 supportedkinds = ('file', 'symlink')
32
32
33 class bzr_source(converter_source):
33 class bzr_source(converter_source):
34 """Reads Bazaar repositories by using the Bazaar Python libraries"""
34 """Reads Bazaar repositories by using the Bazaar Python libraries"""
35
35
36 def __init__(self, ui, path, rev=None):
36 def __init__(self, ui, path, rev=None):
37 super(bzr_source, self).__init__(ui, path, rev=rev)
37 super(bzr_source, self).__init__(ui, path, rev=rev)
38
38
39 if not os.path.exists(os.path.join(path, '.bzr')):
39 if not os.path.exists(os.path.join(path, '.bzr')):
40 raise NoRepo(_('%s does not look like a Bazaar repository')
40 raise NoRepo(_('%s does not look like a Bazaar repository')
41 % path)
41 % path)
42
42
43 try:
43 try:
44 # access bzrlib stuff
44 # access bzrlib stuff
45 branch
45 bzrdir
46 except NameError:
46 except NameError:
47 raise NoRepo(_('Bazaar modules could not be loaded'))
47 raise NoRepo(_('Bazaar modules could not be loaded'))
48
48
49 path = os.path.abspath(path)
49 path = os.path.abspath(path)
50 self._checkrepotype(path)
50 self._checkrepotype(path)
51 self.branch = branch.Branch.open(path)
51 try:
52 self.sourcerepo = self.branch.repository
52 self.sourcerepo = bzrdir.BzrDir.open(path).open_repository()
53 except errors.NoRepositoryPresent:
54 raise NoRepo(_('%s does not look like a Bazaar repository')
55 % path)
53 self._parentids = {}
56 self._parentids = {}
54
57
55 def _checkrepotype(self, path):
58 def _checkrepotype(self, path):
56 # Lightweight checkouts detection is informational but probably
59 # Lightweight checkouts detection is informational but probably
57 # fragile at API level. It should not terminate the conversion.
60 # fragile at API level. It should not terminate the conversion.
58 try:
61 try:
59 from bzrlib import bzrdir
62 from bzrlib import bzrdir
60 dir = bzrdir.BzrDir.open_containing(path)[0]
63 dir = bzrdir.BzrDir.open_containing(path)[0]
61 try:
64 try:
62 tree = dir.open_workingtree(recommend_upgrade=False)
65 tree = dir.open_workingtree(recommend_upgrade=False)
63 branch = tree.branch
66 branch = tree.branch
64 except (errors.NoWorkingTree, errors.NotLocalUrl):
67 except (errors.NoWorkingTree, errors.NotLocalUrl):
65 tree = None
68 tree = None
66 branch = dir.open_branch()
69 branch = dir.open_branch()
67 if (tree is not None and tree.bzrdir.root_transport.base !=
70 if (tree is not None and tree.bzrdir.root_transport.base !=
68 branch.bzrdir.root_transport.base):
71 branch.bzrdir.root_transport.base):
69 self.ui.warn(_('warning: lightweight checkouts may cause '
72 self.ui.warn(_('warning: lightweight checkouts may cause '
70 'conversion failures, try with a regular '
73 'conversion failures, try with a regular '
71 'branch instead.\n'))
74 'branch instead.\n'))
72 except:
75 except:
73 self.ui.note(_('bzr source type could not be determined\n'))
76 self.ui.note(_('bzr source type could not be determined\n'))
74
77
75 def before(self):
78 def before(self):
76 """Before the conversion begins, acquire a read lock
79 """Before the conversion begins, acquire a read lock
77 for all the operations that might need it. Fortunately
80 for all the operations that might need it. Fortunately
78 read locks don't block other reads or writes to the
81 read locks don't block other reads or writes to the
79 repository, so this shouldn't have any impact on the usage of
82 repository, so this shouldn't have any impact on the usage of
80 the source repository.
83 the source repository.
81
84
82 The alternative would be locking on every operation that
85 The alternative would be locking on every operation that
83 needs locks (there are currently two: getting the file and
86 needs locks (there are currently two: getting the file and
84 getting the parent map) and releasing immediately after,
87 getting the parent map) and releasing immediately after,
85 but this approach can take even 40% longer."""
88 but this approach can take even 40% longer."""
86 self.sourcerepo.lock_read()
89 self.sourcerepo.lock_read()
87
90
88 def after(self):
91 def after(self):
89 self.sourcerepo.unlock()
92 self.sourcerepo.unlock()
90
93
91 def getheads(self):
94 def getheads(self):
92 if not self.rev:
95 if not self.rev:
93 return [self.branch.last_revision()]
96 heads = sorted([b.last_revision()
94 try:
97 for b in self.sourcerepo.find_branches()])
95 r = RevisionSpec.from_string(self.rev)
98 else:
96 info = r.in_history(self.branch)
99 revid = None
97 except errors.BzrError:
100 for branch in self.sourcerepo.find_branches():
98 raise util.Abort(_('%s is not a valid revision in current branch')
101 try:
99 % self.rev)
102 r = RevisionSpec.from_string(self.rev)
100 return [info.rev_id]
103 info = r.in_history(branch)
104 except errors.BzrError:
105 pass
106 revid = info.rev_id
107 if revid is None:
108 raise util.Abort(_('%s is not a valid revision') % self.rev)
109 heads = [revid]
110 return heads
101
111
102 def getfile(self, name, rev):
112 def getfile(self, name, rev):
103 revtree = self.sourcerepo.revision_tree(rev)
113 revtree = self.sourcerepo.revision_tree(rev)
104 fileid = revtree.path2id(name.decode(self.encoding or 'utf-8'))
114 fileid = revtree.path2id(name.decode(self.encoding or 'utf-8'))
105 kind = None
115 kind = None
106 if fileid is not None:
116 if fileid is not None:
107 kind = revtree.kind(fileid)
117 kind = revtree.kind(fileid)
108 if kind not in supportedkinds:
118 if kind not in supportedkinds:
109 # the file is not available anymore - was deleted
119 # the file is not available anymore - was deleted
110 raise IOError(_('%s is not available in %s anymore') %
120 raise IOError(_('%s is not available in %s anymore') %
111 (name, rev))
121 (name, rev))
112 mode = self._modecache[(name, rev)]
122 mode = self._modecache[(name, rev)]
113 if kind == 'symlink':
123 if kind == 'symlink':
114 target = revtree.get_symlink_target(fileid)
124 target = revtree.get_symlink_target(fileid)
115 if target is None:
125 if target is None:
116 raise util.Abort(_('%s.%s symlink has no target')
126 raise util.Abort(_('%s.%s symlink has no target')
117 % (name, rev))
127 % (name, rev))
118 return target, mode
128 return target, mode
119 else:
129 else:
120 sio = revtree.get_file(fileid)
130 sio = revtree.get_file(fileid)
121 return sio.read(), mode
131 return sio.read(), mode
122
132
123 def getchanges(self, version):
133 def getchanges(self, version):
124 # set up caches: modecache and revtree
134 # set up caches: modecache and revtree
125 self._modecache = {}
135 self._modecache = {}
126 self._revtree = self.sourcerepo.revision_tree(version)
136 self._revtree = self.sourcerepo.revision_tree(version)
127 # get the parentids from the cache
137 # get the parentids from the cache
128 parentids = self._parentids.pop(version)
138 parentids = self._parentids.pop(version)
129 # only diff against first parent id
139 # only diff against first parent id
130 prevtree = self.sourcerepo.revision_tree(parentids[0])
140 prevtree = self.sourcerepo.revision_tree(parentids[0])
131 return self._gettreechanges(self._revtree, prevtree)
141 return self._gettreechanges(self._revtree, prevtree)
132
142
133 def getcommit(self, version):
143 def getcommit(self, version):
134 rev = self.sourcerepo.get_revision(version)
144 rev = self.sourcerepo.get_revision(version)
135 # populate parent id cache
145 # populate parent id cache
136 if not rev.parent_ids:
146 if not rev.parent_ids:
137 parents = []
147 parents = []
138 self._parentids[version] = (revision.NULL_REVISION,)
148 self._parentids[version] = (revision.NULL_REVISION,)
139 else:
149 else:
140 parents = self._filterghosts(rev.parent_ids)
150 parents = self._filterghosts(rev.parent_ids)
141 self._parentids[version] = parents
151 self._parentids[version] = parents
142
152
153 branch = self.recode(rev.properties.get('branch-nick', u'default'))
154 if branch == 'trunk':
155 branch = 'default'
143 return commit(parents=parents,
156 return commit(parents=parents,
144 date='%d %d' % (rev.timestamp, -rev.timezone),
157 date='%d %d' % (rev.timestamp, -rev.timezone),
145 author=self.recode(rev.committer),
158 author=self.recode(rev.committer),
146 desc=self.recode(rev.message),
159 desc=self.recode(rev.message),
160 branch=branch,
147 rev=version)
161 rev=version)
148
162
149 def gettags(self):
163 def gettags(self):
150 if not self.branch.supports_tags():
151 return {}
152 tagdict = self.branch.tags.get_tag_dict()
153 bytetags = {}
164 bytetags = {}
154 for name, rev in tagdict.iteritems():
165 for branch in self.sourcerepo.find_branches():
155 bytetags[self.recode(name)] = rev
166 if not branch.supports_tags():
167 return {}
168 tagdict = branch.tags.get_tag_dict()
169 for name, rev in tagdict.iteritems():
170 bytetags[self.recode(name)] = rev
156 return bytetags
171 return bytetags
157
172
158 def getchangedfiles(self, rev, i):
173 def getchangedfiles(self, rev, i):
159 self._modecache = {}
174 self._modecache = {}
160 curtree = self.sourcerepo.revision_tree(rev)
175 curtree = self.sourcerepo.revision_tree(rev)
161 if i is not None:
176 if i is not None:
162 parentid = self._parentids[rev][i]
177 parentid = self._parentids[rev][i]
163 else:
178 else:
164 # no parent id, get the empty revision
179 # no parent id, get the empty revision
165 parentid = revision.NULL_REVISION
180 parentid = revision.NULL_REVISION
166
181
167 prevtree = self.sourcerepo.revision_tree(parentid)
182 prevtree = self.sourcerepo.revision_tree(parentid)
168 changes = [e[0] for e in self._gettreechanges(curtree, prevtree)[0]]
183 changes = [e[0] for e in self._gettreechanges(curtree, prevtree)[0]]
169 return changes
184 return changes
170
185
171 def _gettreechanges(self, current, origin):
186 def _gettreechanges(self, current, origin):
172 revid = current._revision_id
187 revid = current._revision_id
173 changes = []
188 changes = []
174 renames = {}
189 renames = {}
175 seen = set()
190 seen = set()
176 # Process the entries by reverse lexicographic name order to
191 # Process the entries by reverse lexicographic name order to
177 # handle nested renames correctly, most specific first.
192 # handle nested renames correctly, most specific first.
178 curchanges = sorted(current.iter_changes(origin),
193 curchanges = sorted(current.iter_changes(origin),
179 key=lambda c: c[1][0] or c[1][1],
194 key=lambda c: c[1][0] or c[1][1],
180 reverse=True)
195 reverse=True)
181 for (fileid, paths, changed_content, versioned, parent, name,
196 for (fileid, paths, changed_content, versioned, parent, name,
182 kind, executable) in curchanges:
197 kind, executable) in curchanges:
183
198
184 if paths[0] == u'' or paths[1] == u'':
199 if paths[0] == u'' or paths[1] == u'':
185 # ignore changes to tree root
200 # ignore changes to tree root
186 continue
201 continue
187
202
188 # bazaar tracks directories, mercurial does not, so
203 # bazaar tracks directories, mercurial does not, so
189 # we have to rename the directory contents
204 # we have to rename the directory contents
190 if kind[1] == 'directory':
205 if kind[1] == 'directory':
191 if kind[0] not in (None, 'directory'):
206 if kind[0] not in (None, 'directory'):
192 # Replacing 'something' with a directory, record it
207 # Replacing 'something' with a directory, record it
193 # so it can be removed.
208 # so it can be removed.
194 changes.append((self.recode(paths[0]), revid))
209 changes.append((self.recode(paths[0]), revid))
195
210
196 if kind[0] == 'directory' and None not in paths:
211 if kind[0] == 'directory' and None not in paths:
197 renaming = paths[0] != paths[1]
212 renaming = paths[0] != paths[1]
198 # neither an add nor an delete - a move
213 # neither an add nor an delete - a move
199 # rename all directory contents manually
214 # rename all directory contents manually
200 subdir = origin.inventory.path2id(paths[0])
215 subdir = origin.inventory.path2id(paths[0])
201 # get all child-entries of the directory
216 # get all child-entries of the directory
202 for name, entry in origin.inventory.iter_entries(subdir):
217 for name, entry in origin.inventory.iter_entries(subdir):
203 # hg does not track directory renames
218 # hg does not track directory renames
204 if entry.kind == 'directory':
219 if entry.kind == 'directory':
205 continue
220 continue
206 frompath = self.recode(paths[0] + '/' + name)
221 frompath = self.recode(paths[0] + '/' + name)
207 if frompath in seen:
222 if frompath in seen:
208 # Already handled by a more specific change entry
223 # Already handled by a more specific change entry
209 # This is important when you have:
224 # This is important when you have:
210 # a => b
225 # a => b
211 # a/c => a/c
226 # a/c => a/c
212 # Here a/c must not be renamed into b/c
227 # Here a/c must not be renamed into b/c
213 continue
228 continue
214 seen.add(frompath)
229 seen.add(frompath)
215 if not renaming:
230 if not renaming:
216 continue
231 continue
217 topath = self.recode(paths[1] + '/' + name)
232 topath = self.recode(paths[1] + '/' + name)
218 # register the files as changed
233 # register the files as changed
219 changes.append((frompath, revid))
234 changes.append((frompath, revid))
220 changes.append((topath, revid))
235 changes.append((topath, revid))
221 # add to mode cache
236 # add to mode cache
222 mode = ((entry.executable and 'x')
237 mode = ((entry.executable and 'x')
223 or (entry.kind == 'symlink' and 's')
238 or (entry.kind == 'symlink' and 's')
224 or '')
239 or '')
225 self._modecache[(topath, revid)] = mode
240 self._modecache[(topath, revid)] = mode
226 # register the change as move
241 # register the change as move
227 renames[topath] = frompath
242 renames[topath] = frompath
228
243
229 # no futher changes, go to the next change
244 # no futher changes, go to the next change
230 continue
245 continue
231
246
232 # we got unicode paths, need to convert them
247 # we got unicode paths, need to convert them
233 path, topath = paths
248 path, topath = paths
234 if path is not None:
249 if path is not None:
235 path = self.recode(path)
250 path = self.recode(path)
236 if topath is not None:
251 if topath is not None:
237 topath = self.recode(topath)
252 topath = self.recode(topath)
238 seen.add(path or topath)
253 seen.add(path or topath)
239
254
240 if topath is None:
255 if topath is None:
241 # file deleted
256 # file deleted
242 changes.append((path, revid))
257 changes.append((path, revid))
243 continue
258 continue
244
259
245 # renamed
260 # renamed
246 if path and path != topath:
261 if path and path != topath:
247 renames[topath] = path
262 renames[topath] = path
248 changes.append((path, revid))
263 changes.append((path, revid))
249
264
250 # populate the mode cache
265 # populate the mode cache
251 kind, executable = [e[1] for e in (kind, executable)]
266 kind, executable = [e[1] for e in (kind, executable)]
252 mode = ((executable and 'x') or (kind == 'symlink' and 'l')
267 mode = ((executable and 'x') or (kind == 'symlink' and 'l')
253 or '')
268 or '')
254 self._modecache[(topath, revid)] = mode
269 self._modecache[(topath, revid)] = mode
255 changes.append((topath, revid))
270 changes.append((topath, revid))
256
271
257 return changes, renames
272 return changes, renames
258
273
259 def _filterghosts(self, ids):
274 def _filterghosts(self, ids):
260 """Filters out ghost revisions which hg does not support, see
275 """Filters out ghost revisions which hg does not support, see
261 <http://bazaar-vcs.org/GhostRevision>
276 <http://bazaar-vcs.org/GhostRevision>
262 """
277 """
263 parentmap = self.sourcerepo.get_parent_map(ids)
278 parentmap = self.sourcerepo.get_parent_map(ids)
264 parents = tuple([parent for parent in ids if parent in parentmap])
279 parents = tuple([parent for parent in ids if parent in parentmap])
265 return parents
280 return parents
@@ -1,19 +1,19
1 # this file holds the definitions that are used in various bzr tests
1 # this file holds the definitions that are used in various bzr tests
2
2
3 "$TESTDIR/hghave" bzr || exit 80
3 "$TESTDIR/hghave" bzr || exit 80
4
4
5 TERM=dumb; export TERM
5 TERM=dumb; export TERM
6 echo '[extensions]' >> $HGRCPATH
6 echo '[extensions]' >> $HGRCPATH
7 echo 'convert = ' >> $HGRCPATH
7 echo 'convert = ' >> $HGRCPATH
8 echo 'hgext.graphlog = ' >> $HGRCPATH
8 echo 'hgext.graphlog = ' >> $HGRCPATH
9
9
10 glog()
10 glog()
11 {
11 {
12 hg glog --template '{rev} "{desc|firstline}" files: {files}\n' "$@"
12 hg glog --template '{rev}@{branch} "{desc|firstline}" files: {files}\n' "$@"
13 }
13 }
14
14
15 manifest()
15 manifest()
16 {
16 {
17 echo "% manifest of $2"
17 echo "% manifest of $2"
18 hg -R $1 manifest -v -r $2
18 hg -R $1 manifest -v -r $2
19 }
19 }
@@ -1,36 +1,36
1
1
2 $ . "$TESTDIR/bzr-definitions"
2 $ . "$TESTDIR/bzr-definitions"
3 $ cat > ghostcreator.py <<EOF
3 $ cat > ghostcreator.py <<EOF
4 > import sys
4 > import sys
5 > from bzrlib import workingtree
5 > from bzrlib import workingtree
6 > wt = workingtree.WorkingTree.open('.')
6 > wt = workingtree.WorkingTree.open('.')
7 >
7 >
8 > message, ghostrev = sys.argv[1:]
8 > message, ghostrev = sys.argv[1:]
9 > wt.set_parent_ids(wt.get_parent_ids() + [ghostrev])
9 > wt.set_parent_ids(wt.get_parent_ids() + [ghostrev])
10 > wt.commit(message)
10 > wt.commit(message)
11 > EOF
11 > EOF
12
12
13 ghost revisions
13 ghost revisions
14
14
15 $ mkdir test-ghost-revisions
15 $ mkdir test-ghost-revisions
16 $ cd test-ghost-revisions
16 $ cd test-ghost-revisions
17 $ bzr init -q source
17 $ bzr init -q source
18 $ cd source
18 $ cd source
19 $ echo content > somefile
19 $ echo content > somefile
20 $ bzr add -q somefile
20 $ bzr add -q somefile
21 $ bzr commit -q -m 'Initial layout setup'
21 $ bzr commit -q -m 'Initial layout setup'
22 $ echo morecontent >> somefile
22 $ echo morecontent >> somefile
23 $ python ../../ghostcreator.py 'Commit with ghost revision' ghostrev
23 $ python ../../ghostcreator.py 'Commit with ghost revision' ghostrev
24 $ cd ..
24 $ cd ..
25 $ hg convert source source-hg
25 $ hg convert source source-hg
26 initializing destination source-hg repository
26 initializing destination source-hg repository
27 scanning source...
27 scanning source...
28 sorting...
28 sorting...
29 converting...
29 converting...
30 1 Initial layout setup
30 1 Initial layout setup
31 0 Commit with ghost revision
31 0 Commit with ghost revision
32 $ glog -R source-hg
32 $ glog -R source-hg
33 o 1 "Commit with ghost revision" files: somefile
33 o 1@source "Commit with ghost revision" files: somefile
34 |
34 |
35 o 0 "Initial layout setup" files: somefile
35 o 0@source "Initial layout setup" files: somefile
36
36
@@ -1,68 +1,68
1 N.B. bzr 1.13 has a bug that breaks this test. If you see this
1 N.B. bzr 1.13 has a bug that breaks this test. If you see this
2 test fail, check your bzr version. Upgrading to bzr 1.13.1
2 test fail, check your bzr version. Upgrading to bzr 1.13.1
3 should fix it.
3 should fix it.
4
4
5 $ . "$TESTDIR/bzr-definitions"
5 $ . "$TESTDIR/bzr-definitions"
6
6
7 test multiple merges at once
7 test multiple merges at once
8
8
9 $ mkdir test-multimerge
9 $ mkdir test-multimerge
10 $ cd test-multimerge
10 $ cd test-multimerge
11 $ bzr init -q source
11 $ bzr init -q source
12 $ cd source
12 $ cd source
13 $ echo content > file
13 $ echo content > file
14 $ bzr add -q file
14 $ bzr add -q file
15 $ bzr commit -q -m 'Initial add'
15 $ bzr commit -q -m 'Initial add'
16 $ cd ..
16 $ cd ..
17 $ bzr branch -q source source-branch1
17 $ bzr branch -q source source-branch1
18 $ cd source-branch1
18 $ cd source-branch1
19 $ echo morecontent >> file
19 $ echo morecontent >> file
20 $ echo evenmorecontent > file-branch1
20 $ echo evenmorecontent > file-branch1
21 $ bzr add -q file-branch1
21 $ bzr add -q file-branch1
22 $ bzr commit -q -m 'Added branch1 file'
22 $ bzr commit -q -m 'Added branch1 file'
23 $ cd ../source
23 $ cd ../source
24 $ sleep 1
24 $ sleep 1
25 $ echo content > file-parent
25 $ echo content > file-parent
26 $ bzr add -q file-parent
26 $ bzr add -q file-parent
27 $ bzr commit -q -m 'Added parent file'
27 $ bzr commit -q -m 'Added parent file'
28 $ cd ..
28 $ cd ..
29 $ bzr branch -q source source-branch2
29 $ bzr branch -q source source-branch2
30 $ cd source-branch2
30 $ cd source-branch2
31 $ echo somecontent > file-branch2
31 $ echo somecontent > file-branch2
32 $ bzr add -q file-branch2
32 $ bzr add -q file-branch2
33 $ bzr commit -q -m 'Added brach2 file'
33 $ bzr commit -q -m 'Added brach2 file'
34 $ sleep 1
34 $ sleep 1
35 $ cd ../source
35 $ cd ../source
36 $ bzr merge -q ../source-branch1
36 $ bzr merge -q ../source-branch1
37 $ bzr merge -q --force ../source-branch2
37 $ bzr merge -q --force ../source-branch2
38 $ bzr commit -q -m 'Merged branches'
38 $ bzr commit -q -m 'Merged branches'
39 $ cd ..
39 $ cd ..
40 $ hg convert --datesort source source-hg
40 $ hg convert --datesort source source-hg
41 initializing destination source-hg repository
41 initializing destination source-hg repository
42 scanning source...
42 scanning source...
43 sorting...
43 sorting...
44 converting...
44 converting...
45 4 Initial add
45 4 Initial add
46 3 Added branch1 file
46 3 Added branch1 file
47 2 Added parent file
47 2 Added parent file
48 1 Added brach2 file
48 1 Added brach2 file
49 0 Merged branches
49 0 Merged branches
50 $ glog -R source-hg
50 $ glog -R source-hg
51 o 5 "(octopus merge fixup)" files:
51 o 5@source "(octopus merge fixup)" files:
52 |\
52 |\
53 | o 4 "Merged branches" files: file-branch2
53 | o 4@source "Merged branches" files: file-branch2
54 | |\
54 | |\
55 o---+ 3 "Added brach2 file" files: file-branch2
55 o---+ 3@source-branch2 "Added brach2 file" files: file-branch2
56 / /
56 / /
57 | o 2 "Added parent file" files: file-parent
57 | o 2@source "Added parent file" files: file-parent
58 | |
58 | |
59 o | 1 "Added branch1 file" files: file file-branch1
59 o | 1@source-branch1 "Added branch1 file" files: file file-branch1
60 |/
60 |/
61 o 0 "Initial add" files: file
61 o 0@source "Initial add" files: file
62
62
63 $ manifest source-hg tip
63 $ manifest source-hg tip
64 % manifest of tip
64 % manifest of tip
65 644 file
65 644 file
66 644 file-branch1
66 644 file-branch1
67 644 file-branch2
67 644 file-branch2
68 644 file-parent
68 644 file-parent
@@ -1,210 +1,238
1 $ "$TESTDIR/hghave" symlink execbit || exit 80
1 $ "$TESTDIR/hghave" symlink execbit || exit 80
2
2
3 $ . "$TESTDIR/bzr-definitions"
3 $ . "$TESTDIR/bzr-definitions"
4
4
5 create and rename on the same file in the same step
5 create and rename on the same file in the same step
6
6
7 $ mkdir test-createandrename
7 $ mkdir test-createandrename
8 $ cd test-createandrename
8 $ cd test-createandrename
9 $ bzr init -q source
9 $ bzr init -q source
10 $ cd source
10 $ cd source
11 $ echo a > a
11 $ echo a > a
12 $ echo c > c
12 $ echo c > c
13 $ echo e > e
13 $ echo e > e
14 $ bzr add -q a c e
14 $ bzr add -q a c e
15 $ bzr commit -q -m 'Initial add: a, c, e'
15 $ bzr commit -q -m 'Initial add: a, c, e'
16 $ bzr mv a b
16 $ bzr mv a b
17 a => b
17 a => b
18 $ bzr mv c d
18 $ bzr mv c d
19 c => d
19 c => d
20 $ bzr mv e f
20 $ bzr mv e f
21 e => f
21 e => f
22 $ echo a2 >> a
22 $ echo a2 >> a
23 $ mkdir e
23 $ mkdir e
24 $ bzr add -q a e
24 $ bzr add -q a e
25 $ bzr commit -q -m 'rename a into b, create a, rename c into d'
25 $ bzr commit -q -m 'rename a into b, create a, rename c into d'
26 $ cd ..
26 $ cd ..
27 $ hg convert source source-hg
27 $ hg convert source source-hg
28 initializing destination source-hg repository
28 initializing destination source-hg repository
29 scanning source...
29 scanning source...
30 sorting...
30 sorting...
31 converting...
31 converting...
32 1 Initial add: a, c, e
32 1 Initial add: a, c, e
33 0 rename a into b, create a, rename c into d
33 0 rename a into b, create a, rename c into d
34 $ glog -R source-hg
34 $ glog -R source-hg
35 o 1 "rename a into b, create a, rename c into d" files: a b c d e f
35 o 1@source "rename a into b, create a, rename c into d" files: a b c d e f
36 |
36 |
37 o 0 "Initial add: a, c, e" files: a c e
37 o 0@source "Initial add: a, c, e" files: a c e
38
38
39
39
40 manifest
40 manifest
41
41
42 $ hg manifest -R source-hg -r tip
42 $ hg manifest -R source-hg -r tip
43 a
43 a
44 b
44 b
45 d
45 d
46 f
46 f
47
47
48 test --rev option
48 test --rev option
49
49
50 $ hg convert -r 1 source source-1-hg
50 $ hg convert -r 1 source source-1-hg
51 initializing destination source-1-hg repository
51 initializing destination source-1-hg repository
52 scanning source...
52 scanning source...
53 sorting...
53 sorting...
54 converting...
54 converting...
55 0 Initial add: a, c, e
55 0 Initial add: a, c, e
56 $ glog -R source-1-hg
56 $ glog -R source-1-hg
57 o 0 "Initial add: a, c, e" files: a c e
57 o 0@source "Initial add: a, c, e" files: a c e
58
58
59
59
60 test with filemap
60 test with filemap
61
61
62 $ cat > filemap <<EOF
62 $ cat > filemap <<EOF
63 > exclude a
63 > exclude a
64 > EOF
64 > EOF
65 $ hg convert --filemap filemap source source-filemap-hg
65 $ hg convert --filemap filemap source source-filemap-hg
66 initializing destination source-filemap-hg repository
66 initializing destination source-filemap-hg repository
67 scanning source...
67 scanning source...
68 sorting...
68 sorting...
69 converting...
69 converting...
70 1 Initial add: a, c, e
70 1 Initial add: a, c, e
71 0 rename a into b, create a, rename c into d
71 0 rename a into b, create a, rename c into d
72 $ hg -R source-filemap-hg manifest -r tip
72 $ hg -R source-filemap-hg manifest -r tip
73 b
73 b
74 d
74 d
75 f
75 f
76
76
77 convert from lightweight checkout
77 convert from lightweight checkout
78
78
79 $ bzr checkout --lightweight source source-light
79 $ bzr checkout --lightweight source source-light
80 $ hg convert source-light source-light-hg
80 $ hg convert -s bzr source-light source-light-hg
81 initializing destination source-light-hg repository
81 initializing destination source-light-hg repository
82 warning: lightweight checkouts may cause conversion failures, try with a regular branch instead.
82 warning: lightweight checkouts may cause conversion failures, try with a regular branch instead.
83 scanning source...
83 $TESTTMP/test-createandrename/source-light does not look like a Bazaar repository
84 sorting...
84 abort: source-light: missing or unsupported repository
85 converting...
85 [255]
86 1 Initial add: a, c, e
87 0 rename a into b, create a, rename c into d
88
89 lightweight manifest
90
91 $ hg manifest -R source-light-hg -r tip
92 a
93 b
94 d
95 f
96
86
97 extract timestamps that look just like hg's {date|isodate}:
87 extract timestamps that look just like hg's {date|isodate}:
98 yyyy-mm-dd HH:MM zzzz (no seconds!)
88 yyyy-mm-dd HH:MM zzzz (no seconds!)
99 compare timestamps
89 compare timestamps
100
90
101 $ cd source
91 $ cd source
102 $ bzr log | \
92 $ bzr log | \
103 > sed '/timestamp/!d;s/.\{15\}\([0-9: -]\{16\}\):.. \(.[0-9]\{4\}\)/\1 \2/' \
93 > sed '/timestamp/!d;s/.\{15\}\([0-9: -]\{16\}\):.. \(.[0-9]\{4\}\)/\1 \2/' \
104 > > ../bzr-timestamps
94 > > ../bzr-timestamps
105 $ cd ..
95 $ cd ..
106 $ hg -R source-hg log --template "{date|isodate}\n" > hg-timestamps
96 $ hg -R source-hg log --template "{date|isodate}\n" > hg-timestamps
107 $ diff -u bzr-timestamps hg-timestamps
97 $ diff -u bzr-timestamps hg-timestamps
108 $ cd ..
98 $ cd ..
109
99
110 merge
100 merge
111
101
112 $ mkdir test-merge
102 $ mkdir test-merge
113 $ cd test-merge
103 $ cd test-merge
114 $ cat > helper.py <<EOF
104 $ cat > helper.py <<EOF
115 > import sys
105 > import sys
116 > from bzrlib import workingtree
106 > from bzrlib import workingtree
117 > wt = workingtree.WorkingTree.open('.')
107 > wt = workingtree.WorkingTree.open('.')
118 >
108 >
119 > message, stamp = sys.argv[1:]
109 > message, stamp = sys.argv[1:]
120 > wt.commit(message, timestamp=int(stamp))
110 > wt.commit(message, timestamp=int(stamp))
121 > EOF
111 > EOF
122 $ bzr init -q source
112 $ bzr init -q source
123 $ cd source
113 $ cd source
124 $ echo content > a
114 $ echo content > a
125 $ echo content2 > b
115 $ echo content2 > b
126 $ bzr add -q a b
116 $ bzr add -q a b
127 $ bzr commit -q -m 'Initial add'
117 $ bzr commit -q -m 'Initial add'
128 $ cd ..
118 $ cd ..
129 $ bzr branch -q source source-improve
119 $ bzr branch -q source source-improve
130 $ cd source
120 $ cd source
131 $ echo more >> a
121 $ echo more >> a
132 $ python ../helper.py 'Editing a' 100
122 $ python ../helper.py 'Editing a' 100
133 $ cd ../source-improve
123 $ cd ../source-improve
134 $ echo content3 >> b
124 $ echo content3 >> b
135 $ python ../helper.py 'Editing b' 200
125 $ python ../helper.py 'Editing b' 200
136 $ cd ../source
126 $ cd ../source
137 $ bzr merge -q ../source-improve
127 $ bzr merge -q ../source-improve
138 $ bzr commit -q -m 'Merged improve branch'
128 $ bzr commit -q -m 'Merged improve branch'
139 $ cd ..
129 $ cd ..
140 $ hg convert --datesort source source-hg
130 $ hg convert --datesort source source-hg
141 initializing destination source-hg repository
131 initializing destination source-hg repository
142 scanning source...
132 scanning source...
143 sorting...
133 sorting...
144 converting...
134 converting...
145 3 Initial add
135 3 Initial add
146 2 Editing a
136 2 Editing a
147 1 Editing b
137 1 Editing b
148 0 Merged improve branch
138 0 Merged improve branch
149 $ glog -R source-hg
139 $ glog -R source-hg
150 o 3 "Merged improve branch" files:
140 o 3@source "Merged improve branch" files:
151 |\
141 |\
152 | o 2 "Editing b" files: b
142 | o 2@source-improve "Editing b" files: b
153 | |
143 | |
154 o | 1 "Editing a" files: a
144 o | 1@source "Editing a" files: a
155 |/
145 |/
156 o 0 "Initial add" files: a b
146 o 0@source "Initial add" files: a b
157
147
158 $ cd ..
148 $ cd ..
159
149
160 symlinks and executable files
150 symlinks and executable files
161
151
162 $ mkdir test-symlinks
152 $ mkdir test-symlinks
163 $ cd test-symlinks
153 $ cd test-symlinks
164 $ bzr init -q source
154 $ bzr init -q source
165 $ cd source
155 $ cd source
166 $ touch program
156 $ touch program
167 $ chmod +x program
157 $ chmod +x program
168 $ ln -s program altname
158 $ ln -s program altname
169 $ mkdir d
159 $ mkdir d
170 $ echo a > d/a
160 $ echo a > d/a
171 $ ln -s a syma
161 $ ln -s a syma
172 $ bzr add -q altname program syma d/a
162 $ bzr add -q altname program syma d/a
173 $ bzr commit -q -m 'Initial setup'
163 $ bzr commit -q -m 'Initial setup'
174 $ touch newprog
164 $ touch newprog
175 $ chmod +x newprog
165 $ chmod +x newprog
176 $ rm altname
166 $ rm altname
177 $ ln -s newprog altname
167 $ ln -s newprog altname
178 $ chmod -x program
168 $ chmod -x program
179 $ bzr add -q newprog
169 $ bzr add -q newprog
180 $ bzr commit -q -m 'Symlink changed, x bits changed'
170 $ bzr commit -q -m 'Symlink changed, x bits changed'
181 $ cd ..
171 $ cd ..
182 $ hg convert source source-hg
172 $ hg convert source source-hg
183 initializing destination source-hg repository
173 initializing destination source-hg repository
184 scanning source...
174 scanning source...
185 sorting...
175 sorting...
186 converting...
176 converting...
187 1 Initial setup
177 1 Initial setup
188 0 Symlink changed, x bits changed
178 0 Symlink changed, x bits changed
189 $ manifest source-hg 0
179 $ manifest source-hg 0
190 % manifest of 0
180 % manifest of 0
191 644 @ altname
181 644 @ altname
192 644 d/a
182 644 d/a
193 755 * program
183 755 * program
194 644 @ syma
184 644 @ syma
195 $ manifest source-hg tip
185 $ manifest source-hg tip
196 % manifest of tip
186 % manifest of tip
197 644 @ altname
187 644 @ altname
198 644 d/a
188 644 d/a
199 755 * newprog
189 755 * newprog
200 644 program
190 644 program
201 644 @ syma
191 644 @ syma
202 $ cd source-hg
192 $ cd source-hg
203
193
204 test the symlinks can be recreated
194 test the symlinks can be recreated
205
195
206 $ hg up
196 $ hg up
207 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
197 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
208 $ hg cat syma; echo
198 $ hg cat syma; echo
209 a
199 a
210
200
201 Multiple branches
202
203 $ bzr init-repo -q --no-trees repo
204 $ bzr init -q repo/trunk
205 $ bzr co repo/trunk repo-trunk
206 $ cd repo-trunk
207 $ echo a > a
208 $ bzr add a
209 adding a
210 $ bzr ci -qm adda --commit-time '2012-01-01 00:00:01 +0000'
211 $ bzr switch -b branch
212 Tree is up to date at revision 1.
213 Switched to branch: *repo/branch/ (glob)
214 $ echo b > b
215 $ bzr add b
216 adding b
217 $ bzr ci -qm addb --commit-time '2012-01-01 00:00:02 +0000'
218 $ bzr switch --force ../repo/trunk
219 Updated to revision 1.
220 Switched to branch: */repo/trunk/ (glob)
221 $ echo a >> a
222 $ bzr ci -qm changea --commit-time '2012-01-01 00:00:03 +0000'
223 $ cd ..
224 $ hg convert --datesort repo repo-bzr
225 initializing destination repo-bzr repository
226 scanning source...
227 sorting...
228 converting...
229 2 adda
230 1 addb
231 0 changea
232 $ (cd repo-bzr; glog)
233 o 2@default "changea" files: a
234 |
235 | o 1@branch "addb" files: b
236 |/
237 o 0@default "adda" files: a
238
General Comments 0
You need to be logged in to leave comments. Login now