##// END OF EJS Templates
convert/bzr: warn when source is a lightweight checkout (issue1647)
Patrick Mezard -
r8470:dd24488c default
parent child Browse files
Show More
@@ -1,238 +1,259 b''
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, incorporated herein by reference.
6 # GNU General Public License version 2, incorporated herein by reference.
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 ])
17 ])
18
18
19 from mercurial.i18n import _
19 from mercurial.i18n import _
20 from mercurial import util
20 from mercurial import util
21 from common import NoRepo, commit, converter_source
21 from common import NoRepo, commit, converter_source
22
22
23 try:
23 try:
24 # bazaar imports
24 # bazaar imports
25 from bzrlib import branch, revision, errors
25 from bzrlib import branch, revision, errors
26 from bzrlib.revisionspec import RevisionSpec
26 from bzrlib.revisionspec import RevisionSpec
27 except ImportError:
27 except ImportError:
28 pass
28 pass
29
29
30 supportedkinds = ('file', 'symlink')
30 supportedkinds = ('file', 'symlink')
31
31
32 class bzr_source(converter_source):
32 class bzr_source(converter_source):
33 """Reads Bazaar repositories by using the Bazaar Python libraries"""
33 """Reads Bazaar repositories by using the Bazaar Python libraries"""
34
34
35 def __init__(self, ui, path, rev=None):
35 def __init__(self, ui, path, rev=None):
36 super(bzr_source, self).__init__(ui, path, rev=rev)
36 super(bzr_source, self).__init__(ui, path, rev=rev)
37
37
38 if not os.path.exists(os.path.join(path, '.bzr')):
38 if not os.path.exists(os.path.join(path, '.bzr')):
39 raise NoRepo('%s does not look like a Bazaar repo' % path)
39 raise NoRepo('%s does not look like a Bazaar repo' % path)
40
40
41 try:
41 try:
42 # access bzrlib stuff
42 # access bzrlib stuff
43 branch
43 branch
44 except NameError:
44 except NameError:
45 raise NoRepo('Bazaar modules could not be loaded')
45 raise NoRepo('Bazaar modules could not be loaded')
46
46
47 path = os.path.abspath(path)
47 path = os.path.abspath(path)
48 self._checkrepotype(path)
48 self.branch = branch.Branch.open(path)
49 self.branch = branch.Branch.open(path)
49 self.sourcerepo = self.branch.repository
50 self.sourcerepo = self.branch.repository
50 self._parentids = {}
51 self._parentids = {}
51
52
53 def _checkrepotype(self, path):
54 # Lightweight checkouts detection is informational but probably
55 # fragile at API level. It should not terminate the conversion.
56 try:
57 from bzrlib import bzrdir
58 dir = bzrdir.BzrDir.open_containing(path)[0]
59 try:
60 tree = dir.open_workingtree(recommend_upgrade=False)
61 branch = tree.branch
62 except (errors.NoWorkingTree, errors.NotLocalUrl), e:
63 tree = None
64 branch = dir.open_branch()
65 if (tree is not None and tree.bzrdir.root_transport.base !=
66 branch.bzrdir.root_transport.base):
67 self.ui.warn(_('warning: lightweight checkouts may cause '
68 'conversion failures, try with a regular '
69 'branch instead.\n'))
70 except:
71 self.ui.note(_('bzr source type could not be determined\n'))
72
52 def before(self):
73 def before(self):
53 """Before the conversion begins, acquire a read lock
74 """Before the conversion begins, acquire a read lock
54 for all the operations that might need it. Fortunately
75 for all the operations that might need it. Fortunately
55 read locks don't block other reads or writes to the
76 read locks don't block other reads or writes to the
56 repository, so this shouldn't have any impact on the usage of
77 repository, so this shouldn't have any impact on the usage of
57 the source repository.
78 the source repository.
58
79
59 The alternative would be locking on every operation that
80 The alternative would be locking on every operation that
60 needs locks (there are currently two: getting the file and
81 needs locks (there are currently two: getting the file and
61 getting the parent map) and releasing immediately after,
82 getting the parent map) and releasing immediately after,
62 but this approach can take even 40% longer."""
83 but this approach can take even 40% longer."""
63 self.sourcerepo.lock_read()
84 self.sourcerepo.lock_read()
64
85
65 def after(self):
86 def after(self):
66 self.sourcerepo.unlock()
87 self.sourcerepo.unlock()
67
88
68 def getheads(self):
89 def getheads(self):
69 if not self.rev:
90 if not self.rev:
70 return [self.branch.last_revision()]
91 return [self.branch.last_revision()]
71 try:
92 try:
72 r = RevisionSpec.from_string(self.rev)
93 r = RevisionSpec.from_string(self.rev)
73 info = r.in_history(self.branch)
94 info = r.in_history(self.branch)
74 except errors.BzrError:
95 except errors.BzrError:
75 raise util.Abort(_('%s is not a valid revision in current branch')
96 raise util.Abort(_('%s is not a valid revision in current branch')
76 % self.rev)
97 % self.rev)
77 return [info.rev_id]
98 return [info.rev_id]
78
99
79 def getfile(self, name, rev):
100 def getfile(self, name, rev):
80 revtree = self.sourcerepo.revision_tree(rev)
101 revtree = self.sourcerepo.revision_tree(rev)
81 fileid = revtree.path2id(name)
102 fileid = revtree.path2id(name)
82 kind = None
103 kind = None
83 if fileid is not None:
104 if fileid is not None:
84 kind = revtree.kind(fileid)
105 kind = revtree.kind(fileid)
85 if kind not in supportedkinds:
106 if kind not in supportedkinds:
86 # the file is not available anymore - was deleted
107 # the file is not available anymore - was deleted
87 raise IOError(_('%s is not available in %s anymore') %
108 raise IOError(_('%s is not available in %s anymore') %
88 (name, rev))
109 (name, rev))
89 if kind == 'symlink':
110 if kind == 'symlink':
90 target = revtree.get_symlink_target(fileid)
111 target = revtree.get_symlink_target(fileid)
91 if target is None:
112 if target is None:
92 raise util.Abort(_('%s.%s symlink has no target')
113 raise util.Abort(_('%s.%s symlink has no target')
93 % (name, rev))
114 % (name, rev))
94 return target
115 return target
95 else:
116 else:
96 sio = revtree.get_file(fileid)
117 sio = revtree.get_file(fileid)
97 return sio.read()
118 return sio.read()
98
119
99 def getmode(self, name, rev):
120 def getmode(self, name, rev):
100 return self._modecache[(name, rev)]
121 return self._modecache[(name, rev)]
101
122
102 def getchanges(self, version):
123 def getchanges(self, version):
103 # set up caches: modecache and revtree
124 # set up caches: modecache and revtree
104 self._modecache = {}
125 self._modecache = {}
105 self._revtree = self.sourcerepo.revision_tree(version)
126 self._revtree = self.sourcerepo.revision_tree(version)
106 # get the parentids from the cache
127 # get the parentids from the cache
107 parentids = self._parentids.pop(version)
128 parentids = self._parentids.pop(version)
108 # only diff against first parent id
129 # only diff against first parent id
109 prevtree = self.sourcerepo.revision_tree(parentids[0])
130 prevtree = self.sourcerepo.revision_tree(parentids[0])
110 return self._gettreechanges(self._revtree, prevtree)
131 return self._gettreechanges(self._revtree, prevtree)
111
132
112 def getcommit(self, version):
133 def getcommit(self, version):
113 rev = self.sourcerepo.get_revision(version)
134 rev = self.sourcerepo.get_revision(version)
114 # populate parent id cache
135 # populate parent id cache
115 if not rev.parent_ids:
136 if not rev.parent_ids:
116 parents = []
137 parents = []
117 self._parentids[version] = (revision.NULL_REVISION,)
138 self._parentids[version] = (revision.NULL_REVISION,)
118 else:
139 else:
119 parents = self._filterghosts(rev.parent_ids)
140 parents = self._filterghosts(rev.parent_ids)
120 self._parentids[version] = parents
141 self._parentids[version] = parents
121
142
122 return commit(parents=parents,
143 return commit(parents=parents,
123 date='%d %d' % (rev.timestamp, -rev.timezone),
144 date='%d %d' % (rev.timestamp, -rev.timezone),
124 author=self.recode(rev.committer),
145 author=self.recode(rev.committer),
125 # bzr returns bytestrings or unicode, depending on the content
146 # bzr returns bytestrings or unicode, depending on the content
126 desc=self.recode(rev.message),
147 desc=self.recode(rev.message),
127 rev=version)
148 rev=version)
128
149
129 def gettags(self):
150 def gettags(self):
130 if not self.branch.supports_tags():
151 if not self.branch.supports_tags():
131 return {}
152 return {}
132 tagdict = self.branch.tags.get_tag_dict()
153 tagdict = self.branch.tags.get_tag_dict()
133 bytetags = {}
154 bytetags = {}
134 for name, rev in tagdict.iteritems():
155 for name, rev in tagdict.iteritems():
135 bytetags[self.recode(name)] = rev
156 bytetags[self.recode(name)] = rev
136 return bytetags
157 return bytetags
137
158
138 def getchangedfiles(self, rev, i):
159 def getchangedfiles(self, rev, i):
139 self._modecache = {}
160 self._modecache = {}
140 curtree = self.sourcerepo.revision_tree(rev)
161 curtree = self.sourcerepo.revision_tree(rev)
141 if i is not None:
162 if i is not None:
142 parentid = self._parentids[rev][i]
163 parentid = self._parentids[rev][i]
143 else:
164 else:
144 # no parent id, get the empty revision
165 # no parent id, get the empty revision
145 parentid = revision.NULL_REVISION
166 parentid = revision.NULL_REVISION
146
167
147 prevtree = self.sourcerepo.revision_tree(parentid)
168 prevtree = self.sourcerepo.revision_tree(parentid)
148 changes = [e[0] for e in self._gettreechanges(curtree, prevtree)[0]]
169 changes = [e[0] for e in self._gettreechanges(curtree, prevtree)[0]]
149 return changes
170 return changes
150
171
151 def _gettreechanges(self, current, origin):
172 def _gettreechanges(self, current, origin):
152 revid = current._revision_id;
173 revid = current._revision_id;
153 changes = []
174 changes = []
154 renames = {}
175 renames = {}
155 for (fileid, paths, changed_content, versioned, parent, name,
176 for (fileid, paths, changed_content, versioned, parent, name,
156 kind, executable) in current.iter_changes(origin):
177 kind, executable) in current.iter_changes(origin):
157
178
158 if paths[0] == u'' or paths[1] == u'':
179 if paths[0] == u'' or paths[1] == u'':
159 # ignore changes to tree root
180 # ignore changes to tree root
160 continue
181 continue
161
182
162 # bazaar tracks directories, mercurial does not, so
183 # bazaar tracks directories, mercurial does not, so
163 # we have to rename the directory contents
184 # we have to rename the directory contents
164 if kind[1] == 'directory':
185 if kind[1] == 'directory':
165 if kind[0] not in (None, 'directory'):
186 if kind[0] not in (None, 'directory'):
166 # Replacing 'something' with a directory, record it
187 # Replacing 'something' with a directory, record it
167 # so it can be removed.
188 # so it can be removed.
168 changes.append((self.recode(paths[0]), revid))
189 changes.append((self.recode(paths[0]), revid))
169
190
170 if None not in paths and paths[0] != paths[1]:
191 if None not in paths and paths[0] != paths[1]:
171 # neither an add nor an delete - a move
192 # neither an add nor an delete - a move
172 # rename all directory contents manually
193 # rename all directory contents manually
173 subdir = origin.inventory.path2id(paths[0])
194 subdir = origin.inventory.path2id(paths[0])
174 # get all child-entries of the directory
195 # get all child-entries of the directory
175 for name, entry in origin.inventory.iter_entries(subdir):
196 for name, entry in origin.inventory.iter_entries(subdir):
176 # hg does not track directory renames
197 # hg does not track directory renames
177 if entry.kind == 'directory':
198 if entry.kind == 'directory':
178 continue
199 continue
179 frompath = self.recode(paths[0] + '/' + name)
200 frompath = self.recode(paths[0] + '/' + name)
180 topath = self.recode(paths[1] + '/' + name)
201 topath = self.recode(paths[1] + '/' + name)
181 # register the files as changed
202 # register the files as changed
182 changes.append((frompath, revid))
203 changes.append((frompath, revid))
183 changes.append((topath, revid))
204 changes.append((topath, revid))
184 # add to mode cache
205 # add to mode cache
185 mode = ((entry.executable and 'x') or (entry.kind == 'symlink' and 's')
206 mode = ((entry.executable and 'x') or (entry.kind == 'symlink' and 's')
186 or '')
207 or '')
187 self._modecache[(topath, revid)] = mode
208 self._modecache[(topath, revid)] = mode
188 # register the change as move
209 # register the change as move
189 renames[topath] = frompath
210 renames[topath] = frompath
190
211
191 # no futher changes, go to the next change
212 # no futher changes, go to the next change
192 continue
213 continue
193
214
194 # we got unicode paths, need to convert them
215 # we got unicode paths, need to convert them
195 path, topath = [self.recode(part) for part in paths]
216 path, topath = [self.recode(part) for part in paths]
196
217
197 if topath is None:
218 if topath is None:
198 # file deleted
219 # file deleted
199 changes.append((path, revid))
220 changes.append((path, revid))
200 continue
221 continue
201
222
202 # renamed
223 # renamed
203 if path and path != topath:
224 if path and path != topath:
204 renames[topath] = path
225 renames[topath] = path
205 changes.append((path, revid))
226 changes.append((path, revid))
206
227
207 # populate the mode cache
228 # populate the mode cache
208 kind, executable = [e[1] for e in (kind, executable)]
229 kind, executable = [e[1] for e in (kind, executable)]
209 mode = ((executable and 'x') or (kind == 'symlink' and 'l')
230 mode = ((executable and 'x') or (kind == 'symlink' and 'l')
210 or '')
231 or '')
211 self._modecache[(topath, revid)] = mode
232 self._modecache[(topath, revid)] = mode
212 changes.append((topath, revid))
233 changes.append((topath, revid))
213
234
214 return changes, renames
235 return changes, renames
215
236
216 def _filterghosts(self, ids):
237 def _filterghosts(self, ids):
217 """Filters out ghost revisions which hg does not support, see
238 """Filters out ghost revisions which hg does not support, see
218 <http://bazaar-vcs.org/GhostRevision>
239 <http://bazaar-vcs.org/GhostRevision>
219 """
240 """
220 parentmap = self.sourcerepo.get_parent_map(ids)
241 parentmap = self.sourcerepo.get_parent_map(ids)
221 parents = tuple([parent for parent in ids if parent in parentmap])
242 parents = tuple([parent for parent in ids if parent in parentmap])
222 return parents
243 return parents
223
244
224 def recode(self, s, encoding=None):
245 def recode(self, s, encoding=None):
225 """This version of recode tries to encode unicode to bytecode,
246 """This version of recode tries to encode unicode to bytecode,
226 and preferably using the UTF-8 codec.
247 and preferably using the UTF-8 codec.
227 Other types than Unicode are silently returned, this is by
248 Other types than Unicode are silently returned, this is by
228 intention, e.g. the None-type is not going to be encoded but instead
249 intention, e.g. the None-type is not going to be encoded but instead
229 just passed through
250 just passed through
230 """
251 """
231 if not encoding:
252 if not encoding:
232 encoding = self.encoding or 'utf-8'
253 encoding = self.encoding or 'utf-8'
233
254
234 if isinstance(s, unicode):
255 if isinstance(s, unicode):
235 return s.encode(encoding)
256 return s.encode(encoding)
236 else:
257 else:
237 # leave it alone
258 # leave it alone
238 return s
259 return s
@@ -1,121 +1,127 b''
1 #!/bin/sh
1 #!/bin/sh
2
2
3 . "$TESTDIR/bzr-definitions"
3 . "$TESTDIR/bzr-definitions"
4
4
5 echo % create and rename on the same file in the same step
5 echo % create and rename on the same file in the same step
6 mkdir test-createandrename
6 mkdir test-createandrename
7 cd test-createandrename
7 cd test-createandrename
8 bzr init -q source
8 bzr init -q source
9 cd source
9 cd source
10 echo a > a
10 echo a > a
11 echo c > c
11 echo c > c
12 echo e > e
12 echo e > e
13 bzr add -q a c e
13 bzr add -q a c e
14 bzr commit -q -m 'Initial add: a, c, e'
14 bzr commit -q -m 'Initial add: a, c, e'
15 bzr mv a b
15 bzr mv a b
16 bzr mv c d
16 bzr mv c d
17 bzr mv e f
17 bzr mv e f
18 echo a2 >> a
18 echo a2 >> a
19 mkdir e
19 mkdir e
20 bzr add -q a e
20 bzr add -q a e
21 bzr commit -q -m 'rename a into b, create a, rename c into d'
21 bzr commit -q -m 'rename a into b, create a, rename c into d'
22 cd ..
22 cd ..
23 hg convert source source-hg
23 hg convert source source-hg
24 glog -R source-hg
24 glog -R source-hg
25 echo "% manifest"
25 echo "% manifest"
26 hg manifest -R source-hg -r tip
26 hg manifest -R source-hg -r tip
27 echo "% test --rev option"
27 echo "% test --rev option"
28 hg convert -r 1 source source-1-hg
28 hg convert -r 1 source source-1-hg
29 glog -R source-1-hg
29 glog -R source-1-hg
30 echo "% test with filemap"
30 echo "% test with filemap"
31 cat > filemap <<EOF
31 cat > filemap <<EOF
32 exclude a
32 exclude a
33 EOF
33 EOF
34 hg convert --filemap filemap source source-filemap-hg
34 hg convert --filemap filemap source source-filemap-hg
35 hg -R source-filemap-hg manifest -r tip
35 hg -R source-filemap-hg manifest -r tip
36
36
37 echo '% convert from lightweight checkout'
38 bzr checkout --lightweight source source-light
39 hg convert source-light source-light-hg
40 echo "% lightweight manifest"
41 hg manifest -R source-light-hg -r tip
42
37 # extract timestamps that look just like hg's {date|isodate}:
43 # extract timestamps that look just like hg's {date|isodate}:
38 # yyyy-mm-dd HH:MM zzzz (no seconds!)
44 # yyyy-mm-dd HH:MM zzzz (no seconds!)
39 echo "% compare timestamps"
45 echo "% compare timestamps"
40 cd source
46 cd source
41 bzr log | \
47 bzr log | \
42 sed '/timestamp/!d;s/.\{15\}\([0-9: -]\{16\}\):.. \(.[0-9]\{4\}\)/\1 \2/' \
48 sed '/timestamp/!d;s/.\{15\}\([0-9: -]\{16\}\):.. \(.[0-9]\{4\}\)/\1 \2/' \
43 > ../bzr-timestamps
49 > ../bzr-timestamps
44 cd ..
50 cd ..
45
51
46 hg -R source-hg log --template "{date|isodate}\n" > hg-timestamps
52 hg -R source-hg log --template "{date|isodate}\n" > hg-timestamps
47 if diff -q bzr-timestamps hg-timestamps ; then
53 if diff -q bzr-timestamps hg-timestamps ; then
48 echo "good: hg timestamps match bzr timestamps"
54 echo "good: hg timestamps match bzr timestamps"
49 else
55 else
50 echo "fail: bzr timestamps are:"
56 echo "fail: bzr timestamps are:"
51 cat bzr-timestamps
57 cat bzr-timestamps
52 echo "but hg timestamps are:"
58 echo "but hg timestamps are:"
53 cat hg-timestamps
59 cat hg-timestamps
54 fi
60 fi
55
61
56 cd ..
62 cd ..
57
63
58 echo % merge
64 echo % merge
59 mkdir test-merge
65 mkdir test-merge
60 cd test-merge
66 cd test-merge
61
67
62 cat > helper.py <<EOF
68 cat > helper.py <<EOF
63 import sys
69 import sys
64 from bzrlib import workingtree
70 from bzrlib import workingtree
65 wt = workingtree.WorkingTree.open('.')
71 wt = workingtree.WorkingTree.open('.')
66
72
67 message, stamp = sys.argv[1:]
73 message, stamp = sys.argv[1:]
68 wt.commit(message, timestamp=int(stamp))
74 wt.commit(message, timestamp=int(stamp))
69 EOF
75 EOF
70
76
71 bzr init -q source
77 bzr init -q source
72 cd source
78 cd source
73 echo content > a
79 echo content > a
74 echo content2 > b
80 echo content2 > b
75 bzr add -q a b
81 bzr add -q a b
76 bzr commit -q -m 'Initial add'
82 bzr commit -q -m 'Initial add'
77 cd ..
83 cd ..
78 bzr branch -q source source-improve
84 bzr branch -q source source-improve
79 cd source
85 cd source
80 echo more >> a
86 echo more >> a
81 python ../helper.py 'Editing a' 100
87 python ../helper.py 'Editing a' 100
82 cd ../source-improve
88 cd ../source-improve
83 echo content3 >> b
89 echo content3 >> b
84 python ../helper.py 'Editing b' 200
90 python ../helper.py 'Editing b' 200
85 cd ../source
91 cd ../source
86 bzr merge -q ../source-improve
92 bzr merge -q ../source-improve
87 bzr commit -q -m 'Merged improve branch'
93 bzr commit -q -m 'Merged improve branch'
88 cd ..
94 cd ..
89 hg convert --datesort source source-hg
95 hg convert --datesort source source-hg
90 glog -R source-hg
96 glog -R source-hg
91 cd ..
97 cd ..
92
98
93 echo % symlinks and executable files
99 echo % symlinks and executable files
94 mkdir test-symlinks
100 mkdir test-symlinks
95 cd test-symlinks
101 cd test-symlinks
96 bzr init -q source
102 bzr init -q source
97 cd source
103 cd source
98 touch program
104 touch program
99 chmod +x program
105 chmod +x program
100 ln -s program altname
106 ln -s program altname
101 mkdir d
107 mkdir d
102 echo a > d/a
108 echo a > d/a
103 ln -s a syma
109 ln -s a syma
104 bzr add -q altname program syma d/a
110 bzr add -q altname program syma d/a
105 bzr commit -q -m 'Initial setup'
111 bzr commit -q -m 'Initial setup'
106 touch newprog
112 touch newprog
107 chmod +x newprog
113 chmod +x newprog
108 rm altname
114 rm altname
109 ln -s newprog altname
115 ln -s newprog altname
110 chmod -x program
116 chmod -x program
111 bzr add -q newprog
117 bzr add -q newprog
112 bzr commit -q -m 'Symlink changed, x bits changed'
118 bzr commit -q -m 'Symlink changed, x bits changed'
113 cd ..
119 cd ..
114 hg convert source source-hg
120 hg convert source source-hg
115 manifest source-hg 0
121 manifest source-hg 0
116 manifest source-hg tip
122 manifest source-hg tip
117 cd source-hg
123 cd source-hg
118 echo % test the symlinks can be recreated
124 echo % test the symlinks can be recreated
119 hg up
125 hg up
120 hg cat syma
126 hg cat syma
121 cd ../..
127 cd ../..
@@ -1,77 +1,90 b''
1 % create and rename on the same file in the same step
1 % create and rename on the same file in the same step
2 a => b
2 a => b
3 c => d
3 c => d
4 e => f
4 e => f
5 initializing destination source-hg repository
5 initializing destination source-hg repository
6 scanning source...
6 scanning source...
7 sorting...
7 sorting...
8 converting...
8 converting...
9 1 Initial add: a, c, e
9 1 Initial add: a, c, e
10 0 rename a into b, create a, rename c into d
10 0 rename a into b, create a, rename c into d
11 o 1 "rename a into b, create a, rename c into d" files: a b c d e f
11 o 1 "rename a into b, create a, rename c into d" files: a b c d e f
12 |
12 |
13 o 0 "Initial add: a, c, e" files: a c e
13 o 0 "Initial add: a, c, e" files: a c e
14
14
15 % manifest
15 % manifest
16 a
16 a
17 b
17 b
18 d
18 d
19 f
19 f
20 % test --rev option
20 % test --rev option
21 initializing destination source-1-hg repository
21 initializing destination source-1-hg repository
22 scanning source...
22 scanning source...
23 sorting...
23 sorting...
24 converting...
24 converting...
25 0 Initial add: a, c, e
25 0 Initial add: a, c, e
26 o 0 "Initial add: a, c, e" files: a c e
26 o 0 "Initial add: a, c, e" files: a c e
27
27
28 % test with filemap
28 % test with filemap
29 initializing destination source-filemap-hg repository
29 initializing destination source-filemap-hg repository
30 scanning source...
30 scanning source...
31 sorting...
31 sorting...
32 converting...
32 converting...
33 1 Initial add: a, c, e
33 1 Initial add: a, c, e
34 0 rename a into b, create a, rename c into d
34 0 rename a into b, create a, rename c into d
35 b
35 b
36 d
36 d
37 f
37 f
38 % convert from lightweight checkout
39 initializing destination source-light-hg repository
40 warning: lightweight checkouts may cause conversion failures, try with a regular branch instead.
41 scanning source...
42 sorting...
43 converting...
44 1 Initial add: a, c, e
45 0 rename a into b, create a, rename c into d
46 % lightweight manifest
47 a
48 b
49 d
50 f
38 % compare timestamps
51 % compare timestamps
39 good: hg timestamps match bzr timestamps
52 good: hg timestamps match bzr timestamps
40 % merge
53 % merge
41 initializing destination source-hg repository
54 initializing destination source-hg repository
42 scanning source...
55 scanning source...
43 sorting...
56 sorting...
44 converting...
57 converting...
45 3 Initial add
58 3 Initial add
46 2 Editing a
59 2 Editing a
47 1 Editing b
60 1 Editing b
48 0 Merged improve branch
61 0 Merged improve branch
49 o 3 "Merged improve branch" files:
62 o 3 "Merged improve branch" files:
50 |\
63 |\
51 | o 2 "Editing b" files: b
64 | o 2 "Editing b" files: b
52 | |
65 | |
53 o | 1 "Editing a" files: a
66 o | 1 "Editing a" files: a
54 |/
67 |/
55 o 0 "Initial add" files: a b
68 o 0 "Initial add" files: a b
56
69
57 % symlinks and executable files
70 % symlinks and executable files
58 initializing destination source-hg repository
71 initializing destination source-hg repository
59 scanning source...
72 scanning source...
60 sorting...
73 sorting...
61 converting...
74 converting...
62 1 Initial setup
75 1 Initial setup
63 0 Symlink changed, x bits changed
76 0 Symlink changed, x bits changed
64 % manifest of 0
77 % manifest of 0
65 644 @ altname
78 644 @ altname
66 644 d/a
79 644 d/a
67 755 * program
80 755 * program
68 644 @ syma
81 644 @ syma
69 % manifest of tip
82 % manifest of tip
70 644 @ altname
83 644 @ altname
71 644 d/a
84 644 d/a
72 755 * newprog
85 755 * newprog
73 644 program
86 644 program
74 644 @ syma
87 644 @ syma
75 % test the symlinks can be recreated
88 % test the symlinks can be recreated
76 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
89 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
77 a No newline at end of file
90 a
General Comments 0
You need to be logged in to leave comments. Login now