##// END OF EJS Templates
convert: correctly detect missing revlog for root revisions
Patrick Mezard -
r7232:c2ac09f8 default
parent child Browse files
Show More
@@ -1,332 +1,336 b''
1 # hg backend for convert extension
1 # hg backend for convert extension
2
2
3 # Notes for hg->hg conversion:
3 # Notes for hg->hg conversion:
4 #
4 #
5 # * Old versions of Mercurial didn't trim the whitespace from the ends
5 # * Old versions of Mercurial didn't trim the whitespace from the ends
6 # of commit messages, but new versions do. Changesets created by
6 # of commit messages, but new versions do. Changesets created by
7 # those older versions, then converted, may thus have different
7 # those older versions, then converted, may thus have different
8 # hashes for changesets that are otherwise identical.
8 # hashes for changesets that are otherwise identical.
9 #
9 #
10 # * By default, the source revision is stored in the converted
10 # * By default, the source revision is stored in the converted
11 # revision. This will cause the converted revision to have a
11 # revision. This will cause the converted revision to have a
12 # different identity than the source. To avoid this, use the
12 # different identity than the source. To avoid this, use the
13 # following option: "--config convert.hg.saverev=false"
13 # following option: "--config convert.hg.saverev=false"
14
14
15
15
16 import os, time
16 import os, time
17 from mercurial.i18n import _
17 from mercurial.i18n import _
18 from mercurial.repo import RepoError
18 from mercurial.repo import RepoError
19 from mercurial.node import bin, hex, nullid
19 from mercurial.node import bin, hex, nullid
20 from mercurial import hg, revlog, util, context
20 from mercurial import hg, revlog, util, context
21
21
22 from common import NoRepo, commit, converter_source, converter_sink
22 from common import NoRepo, commit, converter_source, converter_sink
23
23
24 class mercurial_sink(converter_sink):
24 class mercurial_sink(converter_sink):
25 def __init__(self, ui, path):
25 def __init__(self, ui, path):
26 converter_sink.__init__(self, ui, path)
26 converter_sink.__init__(self, ui, path)
27 self.branchnames = ui.configbool('convert', 'hg.usebranchnames', True)
27 self.branchnames = ui.configbool('convert', 'hg.usebranchnames', True)
28 self.clonebranches = ui.configbool('convert', 'hg.clonebranches', False)
28 self.clonebranches = ui.configbool('convert', 'hg.clonebranches', False)
29 self.tagsbranch = ui.config('convert', 'hg.tagsbranch', 'default')
29 self.tagsbranch = ui.config('convert', 'hg.tagsbranch', 'default')
30 self.lastbranch = None
30 self.lastbranch = None
31 if os.path.isdir(path) and len(os.listdir(path)) > 0:
31 if os.path.isdir(path) and len(os.listdir(path)) > 0:
32 try:
32 try:
33 self.repo = hg.repository(self.ui, path)
33 self.repo = hg.repository(self.ui, path)
34 if not self.repo.local():
34 if not self.repo.local():
35 raise NoRepo(_('%s is not a local Mercurial repo') % path)
35 raise NoRepo(_('%s is not a local Mercurial repo') % path)
36 except RepoError, err:
36 except RepoError, err:
37 ui.print_exc()
37 ui.print_exc()
38 raise NoRepo(err.args[0])
38 raise NoRepo(err.args[0])
39 else:
39 else:
40 try:
40 try:
41 ui.status(_('initializing destination %s repository\n') % path)
41 ui.status(_('initializing destination %s repository\n') % path)
42 self.repo = hg.repository(self.ui, path, create=True)
42 self.repo = hg.repository(self.ui, path, create=True)
43 if not self.repo.local():
43 if not self.repo.local():
44 raise NoRepo(_('%s is not a local Mercurial repo') % path)
44 raise NoRepo(_('%s is not a local Mercurial repo') % path)
45 self.created.append(path)
45 self.created.append(path)
46 except RepoError, err:
46 except RepoError, err:
47 ui.print_exc()
47 ui.print_exc()
48 raise NoRepo("could not create hg repo %s as sink" % path)
48 raise NoRepo("could not create hg repo %s as sink" % path)
49 self.lock = None
49 self.lock = None
50 self.wlock = None
50 self.wlock = None
51 self.filemapmode = False
51 self.filemapmode = False
52
52
53 def before(self):
53 def before(self):
54 self.ui.debug(_('run hg sink pre-conversion action\n'))
54 self.ui.debug(_('run hg sink pre-conversion action\n'))
55 self.wlock = self.repo.wlock()
55 self.wlock = self.repo.wlock()
56 self.lock = self.repo.lock()
56 self.lock = self.repo.lock()
57
57
58 def after(self):
58 def after(self):
59 self.ui.debug(_('run hg sink post-conversion action\n'))
59 self.ui.debug(_('run hg sink post-conversion action\n'))
60 self.lock = None
60 self.lock = None
61 self.wlock = None
61 self.wlock = None
62
62
63 def revmapfile(self):
63 def revmapfile(self):
64 return os.path.join(self.path, ".hg", "shamap")
64 return os.path.join(self.path, ".hg", "shamap")
65
65
66 def authorfile(self):
66 def authorfile(self):
67 return os.path.join(self.path, ".hg", "authormap")
67 return os.path.join(self.path, ".hg", "authormap")
68
68
69 def getheads(self):
69 def getheads(self):
70 h = self.repo.changelog.heads()
70 h = self.repo.changelog.heads()
71 return [ hex(x) for x in h ]
71 return [ hex(x) for x in h ]
72
72
73 def setbranch(self, branch, pbranches):
73 def setbranch(self, branch, pbranches):
74 if not self.clonebranches:
74 if not self.clonebranches:
75 return
75 return
76
76
77 setbranch = (branch != self.lastbranch)
77 setbranch = (branch != self.lastbranch)
78 self.lastbranch = branch
78 self.lastbranch = branch
79 if not branch:
79 if not branch:
80 branch = 'default'
80 branch = 'default'
81 pbranches = [(b[0], b[1] and b[1] or 'default') for b in pbranches]
81 pbranches = [(b[0], b[1] and b[1] or 'default') for b in pbranches]
82 pbranch = pbranches and pbranches[0][1] or 'default'
82 pbranch = pbranches and pbranches[0][1] or 'default'
83
83
84 branchpath = os.path.join(self.path, branch)
84 branchpath = os.path.join(self.path, branch)
85 if setbranch:
85 if setbranch:
86 self.after()
86 self.after()
87 try:
87 try:
88 self.repo = hg.repository(self.ui, branchpath)
88 self.repo = hg.repository(self.ui, branchpath)
89 except:
89 except:
90 self.repo = hg.repository(self.ui, branchpath, create=True)
90 self.repo = hg.repository(self.ui, branchpath, create=True)
91 self.before()
91 self.before()
92
92
93 # pbranches may bring revisions from other branches (merge parents)
93 # pbranches may bring revisions from other branches (merge parents)
94 # Make sure we have them, or pull them.
94 # Make sure we have them, or pull them.
95 missings = {}
95 missings = {}
96 for b in pbranches:
96 for b in pbranches:
97 try:
97 try:
98 self.repo.lookup(b[0])
98 self.repo.lookup(b[0])
99 except:
99 except:
100 missings.setdefault(b[1], []).append(b[0])
100 missings.setdefault(b[1], []).append(b[0])
101
101
102 if missings:
102 if missings:
103 self.after()
103 self.after()
104 for pbranch, heads in missings.iteritems():
104 for pbranch, heads in missings.iteritems():
105 pbranchpath = os.path.join(self.path, pbranch)
105 pbranchpath = os.path.join(self.path, pbranch)
106 prepo = hg.repository(self.ui, pbranchpath)
106 prepo = hg.repository(self.ui, pbranchpath)
107 self.ui.note(_('pulling from %s into %s\n') % (pbranch, branch))
107 self.ui.note(_('pulling from %s into %s\n') % (pbranch, branch))
108 self.repo.pull(prepo, [prepo.lookup(h) for h in heads])
108 self.repo.pull(prepo, [prepo.lookup(h) for h in heads])
109 self.before()
109 self.before()
110
110
111 def putcommit(self, files, copies, parents, commit, source):
111 def putcommit(self, files, copies, parents, commit, source):
112
112
113 files = dict(files)
113 files = dict(files)
114 def getfilectx(repo, memctx, f):
114 def getfilectx(repo, memctx, f):
115 v = files[f]
115 v = files[f]
116 data = source.getfile(f, v)
116 data = source.getfile(f, v)
117 e = source.getmode(f, v)
117 e = source.getmode(f, v)
118 return context.memfilectx(f, data, 'l' in e, 'x' in e, copies.get(f))
118 return context.memfilectx(f, data, 'l' in e, 'x' in e, copies.get(f))
119
119
120 pl = []
120 pl = []
121 for p in parents:
121 for p in parents:
122 if p not in pl:
122 if p not in pl:
123 pl.append(p)
123 pl.append(p)
124 parents = pl
124 parents = pl
125 nparents = len(parents)
125 nparents = len(parents)
126 if self.filemapmode and nparents == 1:
126 if self.filemapmode and nparents == 1:
127 m1node = self.repo.changelog.read(bin(parents[0]))[0]
127 m1node = self.repo.changelog.read(bin(parents[0]))[0]
128 parent = parents[0]
128 parent = parents[0]
129
129
130 if len(parents) < 2: parents.append("0" * 40)
130 if len(parents) < 2: parents.append("0" * 40)
131 if len(parents) < 2: parents.append("0" * 40)
131 if len(parents) < 2: parents.append("0" * 40)
132 p2 = parents.pop(0)
132 p2 = parents.pop(0)
133
133
134 text = commit.desc
134 text = commit.desc
135 extra = commit.extra.copy()
135 extra = commit.extra.copy()
136 if self.branchnames and commit.branch:
136 if self.branchnames and commit.branch:
137 extra['branch'] = commit.branch
137 extra['branch'] = commit.branch
138 if commit.rev:
138 if commit.rev:
139 extra['convert_revision'] = commit.rev
139 extra['convert_revision'] = commit.rev
140
140
141 while parents:
141 while parents:
142 p1 = p2
142 p1 = p2
143 p2 = parents.pop(0)
143 p2 = parents.pop(0)
144 ctx = context.memctx(self.repo, (p1, p2), text, files.keys(), getfilectx,
144 ctx = context.memctx(self.repo, (p1, p2), text, files.keys(), getfilectx,
145 commit.author, commit.date, extra)
145 commit.author, commit.date, extra)
146 a = self.repo.commitctx(ctx)
146 a = self.repo.commitctx(ctx)
147 text = "(octopus merge fixup)\n"
147 text = "(octopus merge fixup)\n"
148 p2 = hex(self.repo.changelog.tip())
148 p2 = hex(self.repo.changelog.tip())
149
149
150 if self.filemapmode and nparents == 1:
150 if self.filemapmode and nparents == 1:
151 man = self.repo.manifest
151 man = self.repo.manifest
152 mnode = self.repo.changelog.read(bin(p2))[0]
152 mnode = self.repo.changelog.read(bin(p2))[0]
153 if not man.cmp(m1node, man.revision(mnode)):
153 if not man.cmp(m1node, man.revision(mnode)):
154 self.repo.rollback()
154 self.repo.rollback()
155 return parent
155 return parent
156 return p2
156 return p2
157
157
158 def puttags(self, tags):
158 def puttags(self, tags):
159 try:
159 try:
160 parentctx = self.repo[self.tagsbranch]
160 parentctx = self.repo[self.tagsbranch]
161 tagparent = parentctx.node()
161 tagparent = parentctx.node()
162 except RepoError, inst:
162 except RepoError, inst:
163 parentctx = None
163 parentctx = None
164 tagparent = nullid
164 tagparent = nullid
165
165
166 try:
166 try:
167 oldlines = util.sort(parentctx['.hgtags'].data().splitlines(1))
167 oldlines = util.sort(parentctx['.hgtags'].data().splitlines(1))
168 except:
168 except:
169 oldlines = []
169 oldlines = []
170
170
171 newlines = util.sort([("%s %s\n" % (tags[tag], tag)) for tag in tags])
171 newlines = util.sort([("%s %s\n" % (tags[tag], tag)) for tag in tags])
172
172
173 if newlines == oldlines:
173 if newlines == oldlines:
174 return None
174 return None
175 data = "".join(newlines)
175 data = "".join(newlines)
176
176
177 def getfilectx(repo, memctx, f):
177 def getfilectx(repo, memctx, f):
178 return context.memfilectx(f, data, False, False, None)
178 return context.memfilectx(f, data, False, False, None)
179
179
180 self.ui.status(_("updating tags\n"))
180 self.ui.status(_("updating tags\n"))
181 date = "%s 0" % int(time.mktime(time.gmtime()))
181 date = "%s 0" % int(time.mktime(time.gmtime()))
182 extra = {'branch': self.tagsbranch}
182 extra = {'branch': self.tagsbranch}
183 ctx = context.memctx(self.repo, (tagparent, None), "update tags",
183 ctx = context.memctx(self.repo, (tagparent, None), "update tags",
184 [".hgtags"], getfilectx, "convert-repo", date,
184 [".hgtags"], getfilectx, "convert-repo", date,
185 extra)
185 extra)
186 self.repo.commitctx(ctx)
186 self.repo.commitctx(ctx)
187 return hex(self.repo.changelog.tip())
187 return hex(self.repo.changelog.tip())
188
188
189 def setfilemapmode(self, active):
189 def setfilemapmode(self, active):
190 self.filemapmode = active
190 self.filemapmode = active
191
191
192 class mercurial_source(converter_source):
192 class mercurial_source(converter_source):
193 def __init__(self, ui, path, rev=None):
193 def __init__(self, ui, path, rev=None):
194 converter_source.__init__(self, ui, path, rev)
194 converter_source.__init__(self, ui, path, rev)
195 self.ignoreerrors = ui.configbool('convert', 'hg.ignoreerrors', False)
195 self.ignoreerrors = ui.configbool('convert', 'hg.ignoreerrors', False)
196 self.ignored = {}
196 self.ignored = {}
197 self.saverev = ui.configbool('convert', 'hg.saverev', True)
197 self.saverev = ui.configbool('convert', 'hg.saverev', True)
198 try:
198 try:
199 self.repo = hg.repository(self.ui, path)
199 self.repo = hg.repository(self.ui, path)
200 # try to provoke an exception if this isn't really a hg
200 # try to provoke an exception if this isn't really a hg
201 # repo, but some other bogus compatible-looking url
201 # repo, but some other bogus compatible-looking url
202 if not self.repo.local():
202 if not self.repo.local():
203 raise RepoError()
203 raise RepoError()
204 except RepoError:
204 except RepoError:
205 ui.print_exc()
205 ui.print_exc()
206 raise NoRepo("%s is not a local Mercurial repo" % path)
206 raise NoRepo("%s is not a local Mercurial repo" % path)
207 self.lastrev = None
207 self.lastrev = None
208 self.lastctx = None
208 self.lastctx = None
209 self._changescache = None
209 self._changescache = None
210 self.convertfp = None
210 self.convertfp = None
211 # Restrict converted revisions to startrev descendants
211 # Restrict converted revisions to startrev descendants
212 startnode = ui.config('convert', 'hg.startrev')
212 startnode = ui.config('convert', 'hg.startrev')
213 if startnode is not None:
213 if startnode is not None:
214 try:
214 try:
215 startnode = self.repo.lookup(startnode)
215 startnode = self.repo.lookup(startnode)
216 except repo.RepoError:
216 except repo.RepoError:
217 raise util.Abort(_('%s is not a valid start revision')
217 raise util.Abort(_('%s is not a valid start revision')
218 % startnode)
218 % startnode)
219 startrev = self.repo.changelog.rev(startnode)
219 startrev = self.repo.changelog.rev(startnode)
220 children = {startnode: 1}
220 children = {startnode: 1}
221 for rev in self.repo.changelog.descendants(startrev):
221 for rev in self.repo.changelog.descendants(startrev):
222 children[self.repo.changelog.node(rev)] = 1
222 children[self.repo.changelog.node(rev)] = 1
223 self.keep = children.__contains__
223 self.keep = children.__contains__
224 else:
224 else:
225 self.keep = util.always
225 self.keep = util.always
226
226
227 def changectx(self, rev):
227 def changectx(self, rev):
228 if self.lastrev != rev:
228 if self.lastrev != rev:
229 self.lastctx = self.repo[rev]
229 self.lastctx = self.repo[rev]
230 self.lastrev = rev
230 self.lastrev = rev
231 return self.lastctx
231 return self.lastctx
232
232
233 def parents(self, ctx):
233 def parents(self, ctx):
234 return [p.node() for p in ctx.parents()
234 return [p.node() for p in ctx.parents()
235 if p and self.keep(p.node())]
235 if p and self.keep(p.node())]
236
236
237 def getheads(self):
237 def getheads(self):
238 if self.rev:
238 if self.rev:
239 heads = [self.repo[self.rev].node()]
239 heads = [self.repo[self.rev].node()]
240 else:
240 else:
241 heads = self.repo.heads()
241 heads = self.repo.heads()
242 return [hex(h) for h in heads if self.keep(h)]
242 return [hex(h) for h in heads if self.keep(h)]
243
243
244 def getfile(self, name, rev):
244 def getfile(self, name, rev):
245 try:
245 try:
246 return self.changectx(rev)[name].data()
246 return self.changectx(rev)[name].data()
247 except revlog.LookupError, err:
247 except revlog.LookupError, err:
248 raise IOError(err)
248 raise IOError(err)
249
249
250 def getmode(self, name, rev):
250 def getmode(self, name, rev):
251 return self.changectx(rev).manifest().flags(name)
251 return self.changectx(rev).manifest().flags(name)
252
252
253 def getchanges(self, rev):
253 def getchanges(self, rev):
254 ctx = self.changectx(rev)
254 ctx = self.changectx(rev)
255 parents = self.parents(ctx)
255 parents = self.parents(ctx)
256 if not parents:
256 if not parents:
257 files = util.sort(ctx.manifest().keys())
257 files = util.sort(ctx.manifest().keys())
258 if self.ignoreerrors:
259 # calling getcopies() is a simple way to detect missing
260 # revlogs and populate self.ignored
261 self.getcopies(ctx, files)
258 return [(f, rev) for f in files if f not in self.ignored], {}
262 return [(f, rev) for f in files if f not in self.ignored], {}
259 if self._changescache and self._changescache[0] == rev:
263 if self._changescache and self._changescache[0] == rev:
260 m, a, r = self._changescache[1]
264 m, a, r = self._changescache[1]
261 else:
265 else:
262 m, a, r = self.repo.status(parents[0], ctx.node())[:3]
266 m, a, r = self.repo.status(parents[0], ctx.node())[:3]
263 # getcopies() detects missing revlogs early, run it before
267 # getcopies() detects missing revlogs early, run it before
264 # filtering the changes.
268 # filtering the changes.
265 copies = self.getcopies(ctx, m + a)
269 copies = self.getcopies(ctx, m + a)
266 changes = [(name, rev) for name in m + a + r
270 changes = [(name, rev) for name in m + a + r
267 if name not in self.ignored]
271 if name not in self.ignored]
268 return util.sort(changes), copies
272 return util.sort(changes), copies
269
273
270 def getcopies(self, ctx, files):
274 def getcopies(self, ctx, files):
271 copies = {}
275 copies = {}
272 for name in files:
276 for name in files:
273 if name in self.ignored:
277 if name in self.ignored:
274 continue
278 continue
275 try:
279 try:
276 copysource, copynode = ctx.filectx(name).renamed()
280 copysource, copynode = ctx.filectx(name).renamed()
277 if copysource in self.ignored or not self.keep(copynode):
281 if copysource in self.ignored or not self.keep(copynode):
278 continue
282 continue
279 copies[name] = copysource
283 copies[name] = copysource
280 except TypeError:
284 except TypeError:
281 pass
285 pass
282 except revlog.LookupError, e:
286 except revlog.LookupError, e:
283 if not self.ignoreerrors:
287 if not self.ignoreerrors:
284 raise
288 raise
285 self.ignored[name] = 1
289 self.ignored[name] = 1
286 self.ui.warn(_('ignoring: %s\n') % e)
290 self.ui.warn(_('ignoring: %s\n') % e)
287 return copies
291 return copies
288
292
289 def getcommit(self, rev):
293 def getcommit(self, rev):
290 ctx = self.changectx(rev)
294 ctx = self.changectx(rev)
291 parents = [hex(p) for p in self.parents(ctx)]
295 parents = [hex(p) for p in self.parents(ctx)]
292 if self.saverev:
296 if self.saverev:
293 crev = rev
297 crev = rev
294 else:
298 else:
295 crev = None
299 crev = None
296 return commit(author=ctx.user(), date=util.datestr(ctx.date()),
300 return commit(author=ctx.user(), date=util.datestr(ctx.date()),
297 desc=ctx.description(), rev=crev, parents=parents,
301 desc=ctx.description(), rev=crev, parents=parents,
298 branch=ctx.branch(), extra=ctx.extra())
302 branch=ctx.branch(), extra=ctx.extra())
299
303
300 def gettags(self):
304 def gettags(self):
301 tags = [t for t in self.repo.tagslist() if t[0] != 'tip']
305 tags = [t for t in self.repo.tagslist() if t[0] != 'tip']
302 return dict([(name, hex(node)) for name, node in tags
306 return dict([(name, hex(node)) for name, node in tags
303 if self.keep(node)])
307 if self.keep(node)])
304
308
305 def getchangedfiles(self, rev, i):
309 def getchangedfiles(self, rev, i):
306 ctx = self.changectx(rev)
310 ctx = self.changectx(rev)
307 parents = self.parents(ctx)
311 parents = self.parents(ctx)
308 if not parents and i is None:
312 if not parents and i is None:
309 i = 0
313 i = 0
310 changes = [], ctx.manifest().keys(), []
314 changes = [], ctx.manifest().keys(), []
311 else:
315 else:
312 i = i or 0
316 i = i or 0
313 changes = self.repo.status(parents[i], ctx.node())[:3]
317 changes = self.repo.status(parents[i], ctx.node())[:3]
314 changes = [[f for f in l if f not in self.ignored] for l in changes]
318 changes = [[f for f in l if f not in self.ignored] for l in changes]
315
319
316 if i == 0:
320 if i == 0:
317 self._changescache = (rev, changes)
321 self._changescache = (rev, changes)
318
322
319 return changes[0] + changes[1] + changes[2]
323 return changes[0] + changes[1] + changes[2]
320
324
321 def converted(self, rev, destrev):
325 def converted(self, rev, destrev):
322 if self.convertfp is None:
326 if self.convertfp is None:
323 self.convertfp = open(os.path.join(self.path, '.hg', 'shamap'),
327 self.convertfp = open(os.path.join(self.path, '.hg', 'shamap'),
324 'a')
328 'a')
325 self.convertfp.write('%s %s\n' % (destrev, rev))
329 self.convertfp.write('%s %s\n' % (destrev, rev))
326 self.convertfp.flush()
330 self.convertfp.flush()
327
331
328 def before(self):
332 def before(self):
329 self.ui.debug(_('run hg source pre-conversion action\n'))
333 self.ui.debug(_('run hg source pre-conversion action\n'))
330
334
331 def after(self):
335 def after(self):
332 self.ui.debug(_('run hg source post-conversion action\n'))
336 self.ui.debug(_('run hg source post-conversion action\n'))
@@ -1,46 +1,46 b''
1 created new head
1 created new head
2 merging baz and foo to baz
2 merging baz and foo to baz
3 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
3 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
4 (branch merge, don't forget to commit)
4 (branch merge, don't forget to commit)
5 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
5 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
6 merging foo and baz to baz
6 merging foo and baz to baz
7 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
7 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
8 (branch merge, don't forget to commit)
8 (branch merge, don't forget to commit)
9 created new head
9 created new head
10 initializing destination new repository
10 initializing destination new repository
11 scanning source...
11 scanning source...
12 sorting...
12 sorting...
13 converting...
13 converting...
14 5 add foo bar
14 5 add foo bar
15 4 change foo
15 4 change foo
16 3 make bar and baz copies of foo
16 3 make bar and baz copies of foo
17 2 merge local copy
17 2 merge local copy
18 1 merge remote copy
18 1 merge remote copy
19 0 mark baz executable
19 0 mark baz executable
20 comparing with ../orig
20 comparing with ../orig
21 searching for changes
21 searching for changes
22 no changes found
22 no changes found
23 % init broken repository
23 % init broken repository
24 created new head
24 created new head
25 % break it
25 % break it
26 initializing destination fixed repository
26 initializing destination fixed repository
27 scanning source...
27 scanning source...
28 sorting...
28 sorting...
29 converting...
29 converting...
30 4 init
30 4 init
31 ignoring: data/b.i@1e88685f5dde: no match found
31 3 changebagain
32 3 changebagain
32 ignoring: data/b.i@4b3c32ced4f8: no match found
33 2 changeall
33 2 changeall
34 1 merge
34 1 merge
35 0 moveb
35 0 moveb
36 checking changesets
36 checking changesets
37 checking manifests
37 checking manifests
38 crosschecking files in changesets and manifests
38 crosschecking files in changesets and manifests
39 checking files
39 checking files
40 3 files, 5 changesets, 5 total revisions
40 3 files, 5 changesets, 5 total revisions
41 % manifest -r 0
41 % manifest -r 0
42 a
42 a
43 % manifest -r tip
43 % manifest -r tip
44 a
44 a
45 c
45 c
46 d
46 d
General Comments 0
You need to be logged in to leave comments. Login now