##// END OF EJS Templates
convert: also catch missing revlogs when introduced in repo roots...
Mads Kiilerich -
r14151:1fe82c93 default
parent child Browse files
Show More
@@ -1,389 +1,388
1 # hg.py - hg backend for convert extension
1 # hg.py - hg backend for convert extension
2 #
2 #
3 # Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others
3 # Copyright 2005-2009 Matt Mackall <mpm@selenic.com> 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 # Notes for hg->hg conversion:
8 # Notes for hg->hg conversion:
9 #
9 #
10 # * Old versions of Mercurial didn't trim the whitespace from the ends
10 # * Old versions of Mercurial didn't trim the whitespace from the ends
11 # of commit messages, but new versions do. Changesets created by
11 # of commit messages, but new versions do. Changesets created by
12 # those older versions, then converted, may thus have different
12 # those older versions, then converted, may thus have different
13 # hashes for changesets that are otherwise identical.
13 # hashes for changesets that are otherwise identical.
14 #
14 #
15 # * Using "--config convert.hg.saverev=true" will make the source
15 # * Using "--config convert.hg.saverev=true" will make the source
16 # identifier to be stored in the converted revision. This will cause
16 # identifier to be stored in the converted revision. This will cause
17 # the converted revision to have a different identity than the
17 # the converted revision to have a different identity than the
18 # source.
18 # source.
19
19
20
20
21 import os, time, cStringIO
21 import os, time, cStringIO
22 from mercurial.i18n import _
22 from mercurial.i18n import _
23 from mercurial.node import bin, hex, nullid
23 from mercurial.node import bin, hex, nullid
24 from mercurial import hg, util, context, bookmarks, error
24 from mercurial import hg, util, context, bookmarks, error
25
25
26 from common import NoRepo, commit, converter_source, converter_sink
26 from common import NoRepo, commit, converter_source, converter_sink
27
27
28 class mercurial_sink(converter_sink):
28 class mercurial_sink(converter_sink):
29 def __init__(self, ui, path):
29 def __init__(self, ui, path):
30 converter_sink.__init__(self, ui, path)
30 converter_sink.__init__(self, ui, path)
31 self.branchnames = ui.configbool('convert', 'hg.usebranchnames', True)
31 self.branchnames = ui.configbool('convert', 'hg.usebranchnames', True)
32 self.clonebranches = ui.configbool('convert', 'hg.clonebranches', False)
32 self.clonebranches = ui.configbool('convert', 'hg.clonebranches', False)
33 self.tagsbranch = ui.config('convert', 'hg.tagsbranch', 'default')
33 self.tagsbranch = ui.config('convert', 'hg.tagsbranch', 'default')
34 self.lastbranch = None
34 self.lastbranch = None
35 if os.path.isdir(path) and len(os.listdir(path)) > 0:
35 if os.path.isdir(path) and len(os.listdir(path)) > 0:
36 try:
36 try:
37 self.repo = hg.repository(self.ui, path)
37 self.repo = hg.repository(self.ui, path)
38 if not self.repo.local():
38 if not self.repo.local():
39 raise NoRepo(_('%s is not a local Mercurial repository')
39 raise NoRepo(_('%s is not a local Mercurial repository')
40 % path)
40 % path)
41 except error.RepoError, err:
41 except error.RepoError, err:
42 ui.traceback()
42 ui.traceback()
43 raise NoRepo(err.args[0])
43 raise NoRepo(err.args[0])
44 else:
44 else:
45 try:
45 try:
46 ui.status(_('initializing destination %s repository\n') % path)
46 ui.status(_('initializing destination %s repository\n') % path)
47 self.repo = hg.repository(self.ui, path, create=True)
47 self.repo = hg.repository(self.ui, path, create=True)
48 if not self.repo.local():
48 if not self.repo.local():
49 raise NoRepo(_('%s is not a local Mercurial repository')
49 raise NoRepo(_('%s is not a local Mercurial repository')
50 % path)
50 % path)
51 self.created.append(path)
51 self.created.append(path)
52 except error.RepoError:
52 except error.RepoError:
53 ui.traceback()
53 ui.traceback()
54 raise NoRepo(_("could not create hg repository %s as sink")
54 raise NoRepo(_("could not create hg repository %s as sink")
55 % path)
55 % path)
56 self.lock = None
56 self.lock = None
57 self.wlock = None
57 self.wlock = None
58 self.filemapmode = False
58 self.filemapmode = False
59
59
60 def before(self):
60 def before(self):
61 self.ui.debug('run hg sink pre-conversion action\n')
61 self.ui.debug('run hg sink pre-conversion action\n')
62 self.wlock = self.repo.wlock()
62 self.wlock = self.repo.wlock()
63 self.lock = self.repo.lock()
63 self.lock = self.repo.lock()
64
64
65 def after(self):
65 def after(self):
66 self.ui.debug('run hg sink post-conversion action\n')
66 self.ui.debug('run hg sink post-conversion action\n')
67 if self.lock:
67 if self.lock:
68 self.lock.release()
68 self.lock.release()
69 if self.wlock:
69 if self.wlock:
70 self.wlock.release()
70 self.wlock.release()
71
71
72 def revmapfile(self):
72 def revmapfile(self):
73 return os.path.join(self.path, ".hg", "shamap")
73 return os.path.join(self.path, ".hg", "shamap")
74
74
75 def authorfile(self):
75 def authorfile(self):
76 return os.path.join(self.path, ".hg", "authormap")
76 return os.path.join(self.path, ".hg", "authormap")
77
77
78 def getheads(self):
78 def getheads(self):
79 h = self.repo.changelog.heads()
79 h = self.repo.changelog.heads()
80 return [hex(x) for x in h]
80 return [hex(x) for x in h]
81
81
82 def setbranch(self, branch, pbranches):
82 def setbranch(self, branch, pbranches):
83 if not self.clonebranches:
83 if not self.clonebranches:
84 return
84 return
85
85
86 setbranch = (branch != self.lastbranch)
86 setbranch = (branch != self.lastbranch)
87 self.lastbranch = branch
87 self.lastbranch = branch
88 if not branch:
88 if not branch:
89 branch = 'default'
89 branch = 'default'
90 pbranches = [(b[0], b[1] and b[1] or 'default') for b in pbranches]
90 pbranches = [(b[0], b[1] and b[1] or 'default') for b in pbranches]
91 pbranch = pbranches and pbranches[0][1] or 'default'
91 pbranch = pbranches and pbranches[0][1] or 'default'
92
92
93 branchpath = os.path.join(self.path, branch)
93 branchpath = os.path.join(self.path, branch)
94 if setbranch:
94 if setbranch:
95 self.after()
95 self.after()
96 try:
96 try:
97 self.repo = hg.repository(self.ui, branchpath)
97 self.repo = hg.repository(self.ui, branchpath)
98 except:
98 except:
99 self.repo = hg.repository(self.ui, branchpath, create=True)
99 self.repo = hg.repository(self.ui, branchpath, create=True)
100 self.before()
100 self.before()
101
101
102 # pbranches may bring revisions from other branches (merge parents)
102 # pbranches may bring revisions from other branches (merge parents)
103 # Make sure we have them, or pull them.
103 # Make sure we have them, or pull them.
104 missings = {}
104 missings = {}
105 for b in pbranches:
105 for b in pbranches:
106 try:
106 try:
107 self.repo.lookup(b[0])
107 self.repo.lookup(b[0])
108 except:
108 except:
109 missings.setdefault(b[1], []).append(b[0])
109 missings.setdefault(b[1], []).append(b[0])
110
110
111 if missings:
111 if missings:
112 self.after()
112 self.after()
113 for pbranch, heads in missings.iteritems():
113 for pbranch, heads in missings.iteritems():
114 pbranchpath = os.path.join(self.path, pbranch)
114 pbranchpath = os.path.join(self.path, pbranch)
115 prepo = hg.repository(self.ui, pbranchpath)
115 prepo = hg.repository(self.ui, pbranchpath)
116 self.ui.note(_('pulling from %s into %s\n') % (pbranch, branch))
116 self.ui.note(_('pulling from %s into %s\n') % (pbranch, branch))
117 self.repo.pull(prepo, [prepo.lookup(h) for h in heads])
117 self.repo.pull(prepo, [prepo.lookup(h) for h in heads])
118 self.before()
118 self.before()
119
119
120 def _rewritetags(self, source, revmap, data):
120 def _rewritetags(self, source, revmap, data):
121 fp = cStringIO.StringIO()
121 fp = cStringIO.StringIO()
122 for line in data.splitlines():
122 for line in data.splitlines():
123 s = line.split(' ', 1)
123 s = line.split(' ', 1)
124 if len(s) != 2:
124 if len(s) != 2:
125 continue
125 continue
126 revid = revmap.get(source.lookuprev(s[0]))
126 revid = revmap.get(source.lookuprev(s[0]))
127 if not revid:
127 if not revid:
128 continue
128 continue
129 fp.write('%s %s\n' % (revid, s[1]))
129 fp.write('%s %s\n' % (revid, s[1]))
130 return fp.getvalue()
130 return fp.getvalue()
131
131
132 def putcommit(self, files, copies, parents, commit, source, revmap):
132 def putcommit(self, files, copies, parents, commit, source, revmap):
133
133
134 files = dict(files)
134 files = dict(files)
135 def getfilectx(repo, memctx, f):
135 def getfilectx(repo, memctx, f):
136 v = files[f]
136 v = files[f]
137 data, mode = source.getfile(f, v)
137 data, mode = source.getfile(f, v)
138 if f == '.hgtags':
138 if f == '.hgtags':
139 data = self._rewritetags(source, revmap, data)
139 data = self._rewritetags(source, revmap, data)
140 return context.memfilectx(f, data, 'l' in mode, 'x' in mode,
140 return context.memfilectx(f, data, 'l' in mode, 'x' in mode,
141 copies.get(f))
141 copies.get(f))
142
142
143 pl = []
143 pl = []
144 for p in parents:
144 for p in parents:
145 if p not in pl:
145 if p not in pl:
146 pl.append(p)
146 pl.append(p)
147 parents = pl
147 parents = pl
148 nparents = len(parents)
148 nparents = len(parents)
149 if self.filemapmode and nparents == 1:
149 if self.filemapmode and nparents == 1:
150 m1node = self.repo.changelog.read(bin(parents[0]))[0]
150 m1node = self.repo.changelog.read(bin(parents[0]))[0]
151 parent = parents[0]
151 parent = parents[0]
152
152
153 if len(parents) < 2:
153 if len(parents) < 2:
154 parents.append(nullid)
154 parents.append(nullid)
155 if len(parents) < 2:
155 if len(parents) < 2:
156 parents.append(nullid)
156 parents.append(nullid)
157 p2 = parents.pop(0)
157 p2 = parents.pop(0)
158
158
159 text = commit.desc
159 text = commit.desc
160 extra = commit.extra.copy()
160 extra = commit.extra.copy()
161 if self.branchnames and commit.branch:
161 if self.branchnames and commit.branch:
162 extra['branch'] = commit.branch
162 extra['branch'] = commit.branch
163 if commit.rev:
163 if commit.rev:
164 extra['convert_revision'] = commit.rev
164 extra['convert_revision'] = commit.rev
165
165
166 while parents:
166 while parents:
167 p1 = p2
167 p1 = p2
168 p2 = parents.pop(0)
168 p2 = parents.pop(0)
169 ctx = context.memctx(self.repo, (p1, p2), text, files.keys(),
169 ctx = context.memctx(self.repo, (p1, p2), text, files.keys(),
170 getfilectx, commit.author, commit.date, extra)
170 getfilectx, commit.author, commit.date, extra)
171 self.repo.commitctx(ctx)
171 self.repo.commitctx(ctx)
172 text = "(octopus merge fixup)\n"
172 text = "(octopus merge fixup)\n"
173 p2 = hex(self.repo.changelog.tip())
173 p2 = hex(self.repo.changelog.tip())
174
174
175 if self.filemapmode and nparents == 1:
175 if self.filemapmode and nparents == 1:
176 man = self.repo.manifest
176 man = self.repo.manifest
177 mnode = self.repo.changelog.read(bin(p2))[0]
177 mnode = self.repo.changelog.read(bin(p2))[0]
178 closed = 'close' in commit.extra
178 closed = 'close' in commit.extra
179 if not closed and not man.cmp(m1node, man.revision(mnode)):
179 if not closed and not man.cmp(m1node, man.revision(mnode)):
180 self.ui.status(_("filtering out empty revision\n"))
180 self.ui.status(_("filtering out empty revision\n"))
181 self.repo.rollback()
181 self.repo.rollback()
182 return parent
182 return parent
183 return p2
183 return p2
184
184
185 def puttags(self, tags):
185 def puttags(self, tags):
186 try:
186 try:
187 parentctx = self.repo[self.tagsbranch]
187 parentctx = self.repo[self.tagsbranch]
188 tagparent = parentctx.node()
188 tagparent = parentctx.node()
189 except error.RepoError:
189 except error.RepoError:
190 parentctx = None
190 parentctx = None
191 tagparent = nullid
191 tagparent = nullid
192
192
193 try:
193 try:
194 oldlines = sorted(parentctx['.hgtags'].data().splitlines(True))
194 oldlines = sorted(parentctx['.hgtags'].data().splitlines(True))
195 except:
195 except:
196 oldlines = []
196 oldlines = []
197
197
198 newlines = sorted([("%s %s\n" % (tags[tag], tag)) for tag in tags])
198 newlines = sorted([("%s %s\n" % (tags[tag], tag)) for tag in tags])
199 if newlines == oldlines:
199 if newlines == oldlines:
200 return None, None
200 return None, None
201 data = "".join(newlines)
201 data = "".join(newlines)
202 def getfilectx(repo, memctx, f):
202 def getfilectx(repo, memctx, f):
203 return context.memfilectx(f, data, False, False, None)
203 return context.memfilectx(f, data, False, False, None)
204
204
205 self.ui.status(_("updating tags\n"))
205 self.ui.status(_("updating tags\n"))
206 date = "%s 0" % int(time.mktime(time.gmtime()))
206 date = "%s 0" % int(time.mktime(time.gmtime()))
207 extra = {'branch': self.tagsbranch}
207 extra = {'branch': self.tagsbranch}
208 ctx = context.memctx(self.repo, (tagparent, None), "update tags",
208 ctx = context.memctx(self.repo, (tagparent, None), "update tags",
209 [".hgtags"], getfilectx, "convert-repo", date,
209 [".hgtags"], getfilectx, "convert-repo", date,
210 extra)
210 extra)
211 self.repo.commitctx(ctx)
211 self.repo.commitctx(ctx)
212 return hex(self.repo.changelog.tip()), hex(tagparent)
212 return hex(self.repo.changelog.tip()), hex(tagparent)
213
213
214 def setfilemapmode(self, active):
214 def setfilemapmode(self, active):
215 self.filemapmode = active
215 self.filemapmode = active
216
216
217 def putbookmarks(self, updatedbookmark):
217 def putbookmarks(self, updatedbookmark):
218 if not len(updatedbookmark):
218 if not len(updatedbookmark):
219 return
219 return
220
220
221 self.ui.status(_("updating bookmarks\n"))
221 self.ui.status(_("updating bookmarks\n"))
222 for bookmark in updatedbookmark:
222 for bookmark in updatedbookmark:
223 self.repo._bookmarks[bookmark] = bin(updatedbookmark[bookmark])
223 self.repo._bookmarks[bookmark] = bin(updatedbookmark[bookmark])
224 bookmarks.write(self.repo)
224 bookmarks.write(self.repo)
225
225
226
226
227 class mercurial_source(converter_source):
227 class mercurial_source(converter_source):
228 def __init__(self, ui, path, rev=None):
228 def __init__(self, ui, path, rev=None):
229 converter_source.__init__(self, ui, path, rev)
229 converter_source.__init__(self, ui, path, rev)
230 self.ignoreerrors = ui.configbool('convert', 'hg.ignoreerrors', False)
230 self.ignoreerrors = ui.configbool('convert', 'hg.ignoreerrors', False)
231 self.ignored = set()
231 self.ignored = set()
232 self.saverev = ui.configbool('convert', 'hg.saverev', False)
232 self.saverev = ui.configbool('convert', 'hg.saverev', False)
233 try:
233 try:
234 self.repo = hg.repository(self.ui, path)
234 self.repo = hg.repository(self.ui, path)
235 # try to provoke an exception if this isn't really a hg
235 # try to provoke an exception if this isn't really a hg
236 # repo, but some other bogus compatible-looking url
236 # repo, but some other bogus compatible-looking url
237 if not self.repo.local():
237 if not self.repo.local():
238 raise error.RepoError()
238 raise error.RepoError()
239 except error.RepoError:
239 except error.RepoError:
240 ui.traceback()
240 ui.traceback()
241 raise NoRepo(_("%s is not a local Mercurial repository") % path)
241 raise NoRepo(_("%s is not a local Mercurial repository") % path)
242 self.lastrev = None
242 self.lastrev = None
243 self.lastctx = None
243 self.lastctx = None
244 self._changescache = None
244 self._changescache = None
245 self.convertfp = None
245 self.convertfp = None
246 # Restrict converted revisions to startrev descendants
246 # Restrict converted revisions to startrev descendants
247 startnode = ui.config('convert', 'hg.startrev')
247 startnode = ui.config('convert', 'hg.startrev')
248 if startnode is not None:
248 if startnode is not None:
249 try:
249 try:
250 startnode = self.repo.lookup(startnode)
250 startnode = self.repo.lookup(startnode)
251 except error.RepoError:
251 except error.RepoError:
252 raise util.Abort(_('%s is not a valid start revision')
252 raise util.Abort(_('%s is not a valid start revision')
253 % startnode)
253 % startnode)
254 startrev = self.repo.changelog.rev(startnode)
254 startrev = self.repo.changelog.rev(startnode)
255 children = {startnode: 1}
255 children = {startnode: 1}
256 for rev in self.repo.changelog.descendants(startrev):
256 for rev in self.repo.changelog.descendants(startrev):
257 children[self.repo.changelog.node(rev)] = 1
257 children[self.repo.changelog.node(rev)] = 1
258 self.keep = children.__contains__
258 self.keep = children.__contains__
259 else:
259 else:
260 self.keep = util.always
260 self.keep = util.always
261
261
262 def changectx(self, rev):
262 def changectx(self, rev):
263 if self.lastrev != rev:
263 if self.lastrev != rev:
264 self.lastctx = self.repo[rev]
264 self.lastctx = self.repo[rev]
265 self.lastrev = rev
265 self.lastrev = rev
266 return self.lastctx
266 return self.lastctx
267
267
268 def parents(self, ctx):
268 def parents(self, ctx):
269 return [p for p in ctx.parents() if p and self.keep(p.node())]
269 return [p for p in ctx.parents() if p and self.keep(p.node())]
270
270
271 def getheads(self):
271 def getheads(self):
272 if self.rev:
272 if self.rev:
273 heads = [self.repo[self.rev].node()]
273 heads = [self.repo[self.rev].node()]
274 else:
274 else:
275 heads = self.repo.heads()
275 heads = self.repo.heads()
276 return [hex(h) for h in heads if self.keep(h)]
276 return [hex(h) for h in heads if self.keep(h)]
277
277
278 def getfile(self, name, rev):
278 def getfile(self, name, rev):
279 try:
279 try:
280 fctx = self.changectx(rev)[name]
280 fctx = self.changectx(rev)[name]
281 return fctx.data(), fctx.flags()
281 return fctx.data(), fctx.flags()
282 except error.LookupError, err:
282 except error.LookupError, err:
283 raise IOError(err)
283 raise IOError(err)
284
284
285 def getchanges(self, rev):
285 def getchanges(self, rev):
286 ctx = self.changectx(rev)
286 ctx = self.changectx(rev)
287 parents = self.parents(ctx)
287 parents = self.parents(ctx)
288 if not parents:
288 if not parents:
289 files = sorted(ctx.manifest())
289 files = sorted(ctx.manifest())
290 if self.ignoreerrors:
290 # getcopies() is not needed for roots, but it is a simple way to
291 # calling getcopies() is a simple way to detect missing
291 # detect missing revlogs and abort on errors or populate self.ignored
292 # revlogs and populate self.ignored
292 self.getcopies(ctx, parents, files)
293 self.getcopies(ctx, parents, files)
294 return [(f, rev) for f in files if f not in self.ignored], {}
293 return [(f, rev) for f in files if f not in self.ignored], {}
295 if self._changescache and self._changescache[0] == rev:
294 if self._changescache and self._changescache[0] == rev:
296 m, a, r = self._changescache[1]
295 m, a, r = self._changescache[1]
297 else:
296 else:
298 m, a, r = self.repo.status(parents[0].node(), ctx.node())[:3]
297 m, a, r = self.repo.status(parents[0].node(), ctx.node())[:3]
299 # getcopies() detects missing revlogs early, run it before
298 # getcopies() detects missing revlogs early, run it before
300 # filtering the changes.
299 # filtering the changes.
301 copies = self.getcopies(ctx, parents, m + a)
300 copies = self.getcopies(ctx, parents, m + a)
302 changes = [(name, rev) for name in m + a + r
301 changes = [(name, rev) for name in m + a + r
303 if name not in self.ignored]
302 if name not in self.ignored]
304 return sorted(changes), copies
303 return sorted(changes), copies
305
304
306 def getcopies(self, ctx, parents, files):
305 def getcopies(self, ctx, parents, files):
307 copies = {}
306 copies = {}
308 for name in files:
307 for name in files:
309 if name in self.ignored:
308 if name in self.ignored:
310 continue
309 continue
311 try:
310 try:
312 copysource, copynode = ctx.filectx(name).renamed()
311 copysource, copynode = ctx.filectx(name).renamed()
313 if copysource in self.ignored or not self.keep(copynode):
312 if copysource in self.ignored or not self.keep(copynode):
314 continue
313 continue
315 # Ignore copy sources not in parent revisions
314 # Ignore copy sources not in parent revisions
316 found = False
315 found = False
317 for p in parents:
316 for p in parents:
318 if copysource in p:
317 if copysource in p:
319 found = True
318 found = True
320 break
319 break
321 if not found:
320 if not found:
322 continue
321 continue
323 copies[name] = copysource
322 copies[name] = copysource
324 except TypeError:
323 except TypeError:
325 pass
324 pass
326 except error.LookupError, e:
325 except error.LookupError, e:
327 if not self.ignoreerrors:
326 if not self.ignoreerrors:
328 raise
327 raise
329 self.ignored.add(name)
328 self.ignored.add(name)
330 self.ui.warn(_('ignoring: %s\n') % e)
329 self.ui.warn(_('ignoring: %s\n') % e)
331 return copies
330 return copies
332
331
333 def getcommit(self, rev):
332 def getcommit(self, rev):
334 ctx = self.changectx(rev)
333 ctx = self.changectx(rev)
335 parents = [p.hex() for p in self.parents(ctx)]
334 parents = [p.hex() for p in self.parents(ctx)]
336 if self.saverev:
335 if self.saverev:
337 crev = rev
336 crev = rev
338 else:
337 else:
339 crev = None
338 crev = None
340 return commit(author=ctx.user(), date=util.datestr(ctx.date()),
339 return commit(author=ctx.user(), date=util.datestr(ctx.date()),
341 desc=ctx.description(), rev=crev, parents=parents,
340 desc=ctx.description(), rev=crev, parents=parents,
342 branch=ctx.branch(), extra=ctx.extra(),
341 branch=ctx.branch(), extra=ctx.extra(),
343 sortkey=ctx.rev())
342 sortkey=ctx.rev())
344
343
345 def gettags(self):
344 def gettags(self):
346 tags = [t for t in self.repo.tagslist() if t[0] != 'tip']
345 tags = [t for t in self.repo.tagslist() if t[0] != 'tip']
347 return dict([(name, hex(node)) for name, node in tags
346 return dict([(name, hex(node)) for name, node in tags
348 if self.keep(node)])
347 if self.keep(node)])
349
348
350 def getchangedfiles(self, rev, i):
349 def getchangedfiles(self, rev, i):
351 ctx = self.changectx(rev)
350 ctx = self.changectx(rev)
352 parents = self.parents(ctx)
351 parents = self.parents(ctx)
353 if not parents and i is None:
352 if not parents and i is None:
354 i = 0
353 i = 0
355 changes = [], ctx.manifest().keys(), []
354 changes = [], ctx.manifest().keys(), []
356 else:
355 else:
357 i = i or 0
356 i = i or 0
358 changes = self.repo.status(parents[i].node(), ctx.node())[:3]
357 changes = self.repo.status(parents[i].node(), ctx.node())[:3]
359 changes = [[f for f in l if f not in self.ignored] for l in changes]
358 changes = [[f for f in l if f not in self.ignored] for l in changes]
360
359
361 if i == 0:
360 if i == 0:
362 self._changescache = (rev, changes)
361 self._changescache = (rev, changes)
363
362
364 return changes[0] + changes[1] + changes[2]
363 return changes[0] + changes[1] + changes[2]
365
364
366 def converted(self, rev, destrev):
365 def converted(self, rev, destrev):
367 if self.convertfp is None:
366 if self.convertfp is None:
368 self.convertfp = open(os.path.join(self.path, '.hg', 'shamap'),
367 self.convertfp = open(os.path.join(self.path, '.hg', 'shamap'),
369 'a')
368 'a')
370 self.convertfp.write('%s %s\n' % (destrev, rev))
369 self.convertfp.write('%s %s\n' % (destrev, rev))
371 self.convertfp.flush()
370 self.convertfp.flush()
372
371
373 def before(self):
372 def before(self):
374 self.ui.debug('run hg source pre-conversion action\n')
373 self.ui.debug('run hg source pre-conversion action\n')
375
374
376 def after(self):
375 def after(self):
377 self.ui.debug('run hg source post-conversion action\n')
376 self.ui.debug('run hg source post-conversion action\n')
378
377
379 def hasnativeorder(self):
378 def hasnativeorder(self):
380 return True
379 return True
381
380
382 def lookuprev(self, rev):
381 def lookuprev(self, rev):
383 try:
382 try:
384 return hex(self.repo.lookup(rev))
383 return hex(self.repo.lookup(rev))
385 except error.RepoError:
384 except error.RepoError:
386 return None
385 return None
387
386
388 def getbookmarks(self):
387 def getbookmarks(self):
389 return bookmarks.listbookmarks(self.repo)
388 return bookmarks.listbookmarks(self.repo)
@@ -1,364 +1,375
1
1
2 $ HGMERGE=true; export HGMERGE
2 $ HGMERGE=true; export HGMERGE
3 $ echo '[extensions]' >> $HGRCPATH
3 $ echo '[extensions]' >> $HGRCPATH
4 $ echo 'graphlog =' >> $HGRCPATH
4 $ echo 'graphlog =' >> $HGRCPATH
5 $ echo 'convert =' >> $HGRCPATH
5 $ echo 'convert =' >> $HGRCPATH
6 $ glog()
6 $ glog()
7 > {
7 > {
8 > hg glog --template '{rev} "{desc}" files: {files}\n' "$@"
8 > hg glog --template '{rev} "{desc}" files: {files}\n' "$@"
9 > }
9 > }
10 $ hg init source
10 $ hg init source
11 $ cd source
11 $ cd source
12 $ echo foo > foo
12 $ echo foo > foo
13 $ echo baz > baz
13 $ echo baz > baz
14 $ mkdir -p dir/subdir
14 $ mkdir -p dir/subdir
15 $ echo dir/file >> dir/file
15 $ echo dir/file >> dir/file
16 $ echo dir/file2 >> dir/file2
16 $ echo dir/file2 >> dir/file2
17 $ echo dir/file3 >> dir/file3 # to be corrupted in rev 0
17 $ echo dir/subdir/file3 >> dir/subdir/file3
18 $ echo dir/subdir/file3 >> dir/subdir/file3
18 $ echo dir/subdir/file4 >> dir/subdir/file4
19 $ echo dir/subdir/file4 >> dir/subdir/file4
19 $ hg ci -d '0 0' -qAm '0: add foo baz dir/'
20 $ hg ci -d '0 0' -qAm '0: add foo baz dir/'
20 $ echo bar > bar
21 $ echo bar > bar
21 $ echo quux > quux
22 $ echo quux > quux
23 $ echo dir/file4 >> dir/file4 # to be corrupted in rev 1
22 $ hg copy foo copied
24 $ hg copy foo copied
23 $ hg ci -d '1 0' -qAm '1: add bar quux; copy foo to copied'
25 $ hg ci -d '1 0' -qAm '1: add bar quux; copy foo to copied'
24 $ echo >> foo
26 $ echo >> foo
25 $ hg ci -d '2 0' -m '2: change foo'
27 $ hg ci -d '2 0' -m '2: change foo'
26 $ hg up -qC 1
28 $ hg up -qC 1
27 $ echo >> bar
29 $ echo >> bar
28 $ echo >> quux
30 $ echo >> quux
29 $ hg ci -d '3 0' -m '3: change bar quux'
31 $ hg ci -d '3 0' -m '3: change bar quux'
30 created new head
32 created new head
31 $ hg up -qC 2
33 $ hg up -qC 2
32 $ hg merge -qr 3
34 $ hg merge -qr 3
33 $ echo >> bar
35 $ echo >> bar
34 $ echo >> baz
36 $ echo >> baz
35 $ hg ci -d '4 0' -m '4: first merge; change bar baz'
37 $ hg ci -d '4 0' -m '4: first merge; change bar baz'
36 $ echo >> bar
38 $ echo >> bar
37 $ echo 1 >> baz
39 $ echo 1 >> baz
38 $ echo >> quux
40 $ echo >> quux
39 $ hg ci -d '5 0' -m '5: change bar baz quux'
41 $ hg ci -d '5 0' -m '5: change bar baz quux'
40 $ hg up -qC 4
42 $ hg up -qC 4
41 $ echo >> foo
43 $ echo >> foo
42 $ echo 2 >> baz
44 $ echo 2 >> baz
43 $ hg ci -d '6 0' -m '6: change foo baz'
45 $ hg ci -d '6 0' -m '6: change foo baz'
44 created new head
46 created new head
45 $ hg up -qC 5
47 $ hg up -qC 5
46 $ hg merge -qr 6
48 $ hg merge -qr 6
47 $ echo >> bar
49 $ echo >> bar
48 $ hg ci -d '7 0' -m '7: second merge; change bar'
50 $ hg ci -d '7 0' -m '7: second merge; change bar'
49 $ echo >> foo
51 $ echo >> foo
50 $ hg ci -m '8: change foo'
52 $ hg ci -m '8: change foo'
51 $ glog
53 $ glog
52 @ 8 "8: change foo" files: foo
54 @ 8 "8: change foo" files: foo
53 |
55 |
54 o 7 "7: second merge; change bar" files: bar baz
56 o 7 "7: second merge; change bar" files: bar baz
55 |\
57 |\
56 | o 6 "6: change foo baz" files: baz foo
58 | o 6 "6: change foo baz" files: baz foo
57 | |
59 | |
58 o | 5 "5: change bar baz quux" files: bar baz quux
60 o | 5 "5: change bar baz quux" files: bar baz quux
59 |/
61 |/
60 o 4 "4: first merge; change bar baz" files: bar baz
62 o 4 "4: first merge; change bar baz" files: bar baz
61 |\
63 |\
62 | o 3 "3: change bar quux" files: bar quux
64 | o 3 "3: change bar quux" files: bar quux
63 | |
65 | |
64 o | 2 "2: change foo" files: foo
66 o | 2 "2: change foo" files: foo
65 |/
67 |/
66 o 1 "1: add bar quux; copy foo to copied" files: bar copied quux
68 o 1 "1: add bar quux; copy foo to copied" files: bar copied dir/file4 quux
67 |
69 |
68 o 0 "0: add foo baz dir/" files: baz dir/file dir/file2 dir/subdir/file3 dir/subdir/file4 foo
70 o 0 "0: add foo baz dir/" files: baz dir/file dir/file2 dir/file3 dir/subdir/file3 dir/subdir/file4 foo
69
71
70
72
71 final file versions in this repo:
73 final file versions in this repo:
72
74
73 $ hg manifest --debug
75 $ hg manifest --debug
74 9463f52fe115e377cf2878d4fc548117211063f2 644 bar
76 9463f52fe115e377cf2878d4fc548117211063f2 644 bar
75 94c1be4dfde2ee8d78db8bbfcf81210813307c3d 644 baz
77 94c1be4dfde2ee8d78db8bbfcf81210813307c3d 644 baz
76 7711d36246cc83e61fb29cd6d4ef394c63f1ceaf 644 copied
78 7711d36246cc83e61fb29cd6d4ef394c63f1ceaf 644 copied
77 3e20847584beff41d7cd16136b7331ab3d754be0 644 dir/file
79 3e20847584beff41d7cd16136b7331ab3d754be0 644 dir/file
78 75e6d3f8328f5f6ace6bf10b98df793416a09dca 644 dir/file2
80 75e6d3f8328f5f6ace6bf10b98df793416a09dca 644 dir/file2
81 e96dce0bc6a217656a3a410e5e6bec2c4f42bf7c 644 dir/file3
82 6edd55f559cdce67132b12ca09e09cee08b60442 644 dir/file4
79 5fe139720576e18e34bcc9f79174db8897c8afe9 644 dir/subdir/file3
83 5fe139720576e18e34bcc9f79174db8897c8afe9 644 dir/subdir/file3
80 57a1c1511590f3de52874adfa04effe8a77d64af 644 dir/subdir/file4
84 57a1c1511590f3de52874adfa04effe8a77d64af 644 dir/subdir/file4
81 9a7b52012991e4873687192c3e17e61ba3e837a3 644 foo
85 9a7b52012991e4873687192c3e17e61ba3e837a3 644 foo
82 bc3eca3f47023a3e70ca0d8cc95a22a6827db19d 644 quux
86 bc3eca3f47023a3e70ca0d8cc95a22a6827db19d 644 quux
83 $ hg debugrename copied
87 $ hg debugrename copied
84 copied renamed from foo:2ed2a3912a0b24502043eae84ee4b279c18b90dd
88 copied renamed from foo:2ed2a3912a0b24502043eae84ee4b279c18b90dd
85 $ echo
89 $ echo
86
90
87 $ cd ..
91 $ cd ..
88 $ splitrepo()
92 $ splitrepo()
89 > {
93 > {
90 > msg="$1"
94 > msg="$1"
91 > files="$2"
95 > files="$2"
92 > opts=$3
96 > opts=$3
93 > echo "% $files: $msg"
97 > echo "% $files: $msg"
94 > prefix=`echo "$files" | sed -e 's/ /-/g'`
98 > prefix=`echo "$files" | sed -e 's/ /-/g'`
95 > fmap="$prefix.fmap"
99 > fmap="$prefix.fmap"
96 > repo="$prefix.repo"
100 > repo="$prefix.repo"
97 > for i in $files; do
101 > for i in $files; do
98 > echo "include $i" >> "$fmap"
102 > echo "include $i" >> "$fmap"
99 > done
103 > done
100 > hg -q convert $opts --filemap "$fmap" --datesort source "$repo"
104 > hg -q convert $opts --filemap "$fmap" --datesort source "$repo"
101 > hg up -q -R "$repo"
105 > hg up -q -R "$repo"
102 > glog -R "$repo"
106 > glog -R "$repo"
103 > hg -R "$repo" manifest --debug
107 > hg -R "$repo" manifest --debug
104 > }
108 > }
105 $ splitrepo 'skip unwanted merges; use 1st parent in 1st merge, 2nd in 2nd' foo
109 $ splitrepo 'skip unwanted merges; use 1st parent in 1st merge, 2nd in 2nd' foo
106 % foo: skip unwanted merges; use 1st parent in 1st merge, 2nd in 2nd
110 % foo: skip unwanted merges; use 1st parent in 1st merge, 2nd in 2nd
107 @ 3 "8: change foo" files: foo
111 @ 3 "8: change foo" files: foo
108 |
112 |
109 o 2 "6: change foo baz" files: foo
113 o 2 "6: change foo baz" files: foo
110 |
114 |
111 o 1 "2: change foo" files: foo
115 o 1 "2: change foo" files: foo
112 |
116 |
113 o 0 "0: add foo baz dir/" files: foo
117 o 0 "0: add foo baz dir/" files: foo
114
118
115 9a7b52012991e4873687192c3e17e61ba3e837a3 644 foo
119 9a7b52012991e4873687192c3e17e61ba3e837a3 644 foo
116 $ splitrepo 'merges are not merges anymore' bar
120 $ splitrepo 'merges are not merges anymore' bar
117 % bar: merges are not merges anymore
121 % bar: merges are not merges anymore
118 @ 4 "7: second merge; change bar" files: bar
122 @ 4 "7: second merge; change bar" files: bar
119 |
123 |
120 o 3 "5: change bar baz quux" files: bar
124 o 3 "5: change bar baz quux" files: bar
121 |
125 |
122 o 2 "4: first merge; change bar baz" files: bar
126 o 2 "4: first merge; change bar baz" files: bar
123 |
127 |
124 o 1 "3: change bar quux" files: bar
128 o 1 "3: change bar quux" files: bar
125 |
129 |
126 o 0 "1: add bar quux; copy foo to copied" files: bar
130 o 0 "1: add bar quux; copy foo to copied" files: bar
127
131
128 9463f52fe115e377cf2878d4fc548117211063f2 644 bar
132 9463f52fe115e377cf2878d4fc548117211063f2 644 bar
129 $ splitrepo '1st merge is not a merge anymore; 2nd still is' baz
133 $ splitrepo '1st merge is not a merge anymore; 2nd still is' baz
130 % baz: 1st merge is not a merge anymore; 2nd still is
134 % baz: 1st merge is not a merge anymore; 2nd still is
131 @ 4 "7: second merge; change bar" files: baz
135 @ 4 "7: second merge; change bar" files: baz
132 |\
136 |\
133 | o 3 "6: change foo baz" files: baz
137 | o 3 "6: change foo baz" files: baz
134 | |
138 | |
135 o | 2 "5: change bar baz quux" files: baz
139 o | 2 "5: change bar baz quux" files: baz
136 |/
140 |/
137 o 1 "4: first merge; change bar baz" files: baz
141 o 1 "4: first merge; change bar baz" files: baz
138 |
142 |
139 o 0 "0: add foo baz dir/" files: baz
143 o 0 "0: add foo baz dir/" files: baz
140
144
141 94c1be4dfde2ee8d78db8bbfcf81210813307c3d 644 baz
145 94c1be4dfde2ee8d78db8bbfcf81210813307c3d 644 baz
142 $ splitrepo 'we add additional merges when they are interesting' 'foo quux'
146 $ splitrepo 'we add additional merges when they are interesting' 'foo quux'
143 % foo quux: we add additional merges when they are interesting
147 % foo quux: we add additional merges when they are interesting
144 @ 8 "8: change foo" files: foo
148 @ 8 "8: change foo" files: foo
145 |
149 |
146 o 7 "7: second merge; change bar" files:
150 o 7 "7: second merge; change bar" files:
147 |\
151 |\
148 | o 6 "6: change foo baz" files: foo
152 | o 6 "6: change foo baz" files: foo
149 | |
153 | |
150 o | 5 "5: change bar baz quux" files: quux
154 o | 5 "5: change bar baz quux" files: quux
151 |/
155 |/
152 o 4 "4: first merge; change bar baz" files:
156 o 4 "4: first merge; change bar baz" files:
153 |\
157 |\
154 | o 3 "3: change bar quux" files: quux
158 | o 3 "3: change bar quux" files: quux
155 | |
159 | |
156 o | 2 "2: change foo" files: foo
160 o | 2 "2: change foo" files: foo
157 |/
161 |/
158 o 1 "1: add bar quux; copy foo to copied" files: quux
162 o 1 "1: add bar quux; copy foo to copied" files: quux
159 |
163 |
160 o 0 "0: add foo baz dir/" files: foo
164 o 0 "0: add foo baz dir/" files: foo
161
165
162 9a7b52012991e4873687192c3e17e61ba3e837a3 644 foo
166 9a7b52012991e4873687192c3e17e61ba3e837a3 644 foo
163 bc3eca3f47023a3e70ca0d8cc95a22a6827db19d 644 quux
167 bc3eca3f47023a3e70ca0d8cc95a22a6827db19d 644 quux
164 $ splitrepo 'partial conversion' 'bar quux' '-r 3'
168 $ splitrepo 'partial conversion' 'bar quux' '-r 3'
165 % bar quux: partial conversion
169 % bar quux: partial conversion
166 @ 1 "3: change bar quux" files: bar quux
170 @ 1 "3: change bar quux" files: bar quux
167 |
171 |
168 o 0 "1: add bar quux; copy foo to copied" files: bar quux
172 o 0 "1: add bar quux; copy foo to copied" files: bar quux
169
173
170 b79105bedc55102f394e90a789c9c380117c1b4a 644 bar
174 b79105bedc55102f394e90a789c9c380117c1b4a 644 bar
171 db0421cc6b685a458c8d86c7d5c004f94429ea23 644 quux
175 db0421cc6b685a458c8d86c7d5c004f94429ea23 644 quux
172 $ splitrepo 'complete the partial conversion' 'bar quux'
176 $ splitrepo 'complete the partial conversion' 'bar quux'
173 % bar quux: complete the partial conversion
177 % bar quux: complete the partial conversion
174 @ 4 "7: second merge; change bar" files: bar
178 @ 4 "7: second merge; change bar" files: bar
175 |
179 |
176 o 3 "5: change bar baz quux" files: bar quux
180 o 3 "5: change bar baz quux" files: bar quux
177 |
181 |
178 o 2 "4: first merge; change bar baz" files: bar
182 o 2 "4: first merge; change bar baz" files: bar
179 |
183 |
180 o 1 "3: change bar quux" files: bar quux
184 o 1 "3: change bar quux" files: bar quux
181 |
185 |
182 o 0 "1: add bar quux; copy foo to copied" files: bar quux
186 o 0 "1: add bar quux; copy foo to copied" files: bar quux
183
187
184 9463f52fe115e377cf2878d4fc548117211063f2 644 bar
188 9463f52fe115e377cf2878d4fc548117211063f2 644 bar
185 bc3eca3f47023a3e70ca0d8cc95a22a6827db19d 644 quux
189 bc3eca3f47023a3e70ca0d8cc95a22a6827db19d 644 quux
186 $ rm -r foo.repo
190 $ rm -r foo.repo
187 $ splitrepo 'partial conversion' 'foo' '-r 3'
191 $ splitrepo 'partial conversion' 'foo' '-r 3'
188 % foo: partial conversion
192 % foo: partial conversion
189 @ 0 "0: add foo baz dir/" files: foo
193 @ 0 "0: add foo baz dir/" files: foo
190
194
191 2ed2a3912a0b24502043eae84ee4b279c18b90dd 644 foo
195 2ed2a3912a0b24502043eae84ee4b279c18b90dd 644 foo
192 $ splitrepo 'complete the partial conversion' 'foo'
196 $ splitrepo 'complete the partial conversion' 'foo'
193 % foo: complete the partial conversion
197 % foo: complete the partial conversion
194 @ 3 "8: change foo" files: foo
198 @ 3 "8: change foo" files: foo
195 |
199 |
196 o 2 "6: change foo baz" files: foo
200 o 2 "6: change foo baz" files: foo
197 |
201 |
198 o 1 "2: change foo" files: foo
202 o 1 "2: change foo" files: foo
199 |
203 |
200 o 0 "0: add foo baz dir/" files: foo
204 o 0 "0: add foo baz dir/" files: foo
201
205
202 9a7b52012991e4873687192c3e17e61ba3e837a3 644 foo
206 9a7b52012991e4873687192c3e17e61ba3e837a3 644 foo
203 $ splitrepo 'copied file; source not included in new repo' copied
207 $ splitrepo 'copied file; source not included in new repo' copied
204 % copied: copied file; source not included in new repo
208 % copied: copied file; source not included in new repo
205 @ 0 "1: add bar quux; copy foo to copied" files: copied
209 @ 0 "1: add bar quux; copy foo to copied" files: copied
206
210
207 2ed2a3912a0b24502043eae84ee4b279c18b90dd 644 copied
211 2ed2a3912a0b24502043eae84ee4b279c18b90dd 644 copied
208 $ hg --cwd copied.repo debugrename copied
212 $ hg --cwd copied.repo debugrename copied
209 copied not renamed
213 copied not renamed
210 $ splitrepo 'copied file; source included in new repo' 'foo copied'
214 $ splitrepo 'copied file; source included in new repo' 'foo copied'
211 % foo copied: copied file; source included in new repo
215 % foo copied: copied file; source included in new repo
212 @ 4 "8: change foo" files: foo
216 @ 4 "8: change foo" files: foo
213 |
217 |
214 o 3 "6: change foo baz" files: foo
218 o 3 "6: change foo baz" files: foo
215 |
219 |
216 o 2 "2: change foo" files: foo
220 o 2 "2: change foo" files: foo
217 |
221 |
218 o 1 "1: add bar quux; copy foo to copied" files: copied
222 o 1 "1: add bar quux; copy foo to copied" files: copied
219 |
223 |
220 o 0 "0: add foo baz dir/" files: foo
224 o 0 "0: add foo baz dir/" files: foo
221
225
222 7711d36246cc83e61fb29cd6d4ef394c63f1ceaf 644 copied
226 7711d36246cc83e61fb29cd6d4ef394c63f1ceaf 644 copied
223 9a7b52012991e4873687192c3e17e61ba3e837a3 644 foo
227 9a7b52012991e4873687192c3e17e61ba3e837a3 644 foo
224 $ hg --cwd foo-copied.repo debugrename copied
228 $ hg --cwd foo-copied.repo debugrename copied
225 copied renamed from foo:2ed2a3912a0b24502043eae84ee4b279c18b90dd
229 copied renamed from foo:2ed2a3912a0b24502043eae84ee4b279c18b90dd
226 $ cat > renames.fmap <<EOF
230 $ cat > renames.fmap <<EOF
227 > include dir
231 > include dir
228 > exclude dir/file2
232 > exclude dir/file2
229 > rename dir dir2
233 > rename dir dir2
230 > include foo
234 > include foo
231 > include copied
235 > include copied
232 > rename foo foo2
236 > rename foo foo2
233 > rename copied copied2
237 > rename copied copied2
234 > exclude dir/subdir
238 > exclude dir/subdir
235 > include dir/subdir/file3
239 > include dir/subdir/file3
236 > EOF
240 > EOF
237 $ hg -q convert --filemap renames.fmap --datesort source renames.repo
241 $ rm source/.hg/store/data/dir/file3.i
242 $ rm source/.hg/store/data/dir/file4.i
243 $ hg -q convert --filemap renames.fmap --datesort source dummydest
244 abort: data/dir/file3.i@e96dce0bc6a2: no match found!
245 [255]
246 $ hg -q convert --filemap renames.fmap --datesort --config convert.hg.ignoreerrors=1 source renames.repo
247 ignoring: data/dir/file3.i@e96dce0bc6a2: no match found
248 ignoring: data/dir/file4.i@6edd55f559cd: no match found
238 $ hg up -q -R renames.repo
249 $ hg up -q -R renames.repo
239 $ glog -R renames.repo
250 $ glog -R renames.repo
240 @ 4 "8: change foo" files: foo2
251 @ 4 "8: change foo" files: foo2
241 |
252 |
242 o 3 "6: change foo baz" files: foo2
253 o 3 "6: change foo baz" files: foo2
243 |
254 |
244 o 2 "2: change foo" files: foo2
255 o 2 "2: change foo" files: foo2
245 |
256 |
246 o 1 "1: add bar quux; copy foo to copied" files: copied2
257 o 1 "1: add bar quux; copy foo to copied" files: copied2
247 |
258 |
248 o 0 "0: add foo baz dir/" files: dir2/file dir2/subdir/file3 foo2
259 o 0 "0: add foo baz dir/" files: dir2/file dir2/subdir/file3 foo2
249
260
250 $ hg -R renames.repo manifest --debug
261 $ hg -R renames.repo manifest --debug
251 d43feacba7a4f1f2080dde4a4b985bd8a0236d46 644 copied2
262 d43feacba7a4f1f2080dde4a4b985bd8a0236d46 644 copied2
252 3e20847584beff41d7cd16136b7331ab3d754be0 644 dir2/file
263 3e20847584beff41d7cd16136b7331ab3d754be0 644 dir2/file
253 5fe139720576e18e34bcc9f79174db8897c8afe9 644 dir2/subdir/file3
264 5fe139720576e18e34bcc9f79174db8897c8afe9 644 dir2/subdir/file3
254 9a7b52012991e4873687192c3e17e61ba3e837a3 644 foo2
265 9a7b52012991e4873687192c3e17e61ba3e837a3 644 foo2
255 $ hg --cwd renames.repo debugrename copied2
266 $ hg --cwd renames.repo debugrename copied2
256 copied2 renamed from foo2:2ed2a3912a0b24502043eae84ee4b279c18b90dd
267 copied2 renamed from foo2:2ed2a3912a0b24502043eae84ee4b279c18b90dd
257
268
258 copied:
269 copied:
259
270
260 $ hg --cwd source cat copied
271 $ hg --cwd source cat copied
261 foo
272 foo
262
273
263 copied2:
274 copied2:
264
275
265 $ hg --cwd renames.repo cat copied2
276 $ hg --cwd renames.repo cat copied2
266 foo
277 foo
267
278
268 filemap errors
279 filemap errors
269
280
270 $ cat > errors.fmap <<EOF
281 $ cat > errors.fmap <<EOF
271 > include dir/ # beware that comments changes error line numbers!
282 > include dir/ # beware that comments changes error line numbers!
272 > exclude /dir
283 > exclude /dir
273 > rename dir//dir /dir//dir/ "out of sync"
284 > rename dir//dir /dir//dir/ "out of sync"
274 > include
285 > include
275 > EOF
286 > EOF
276 $ hg -q convert --filemap errors.fmap source errors.repo
287 $ hg -q convert --filemap errors.fmap source errors.repo
277 errors.fmap:1: superfluous / in exclude 'dir/'
288 errors.fmap:1: superfluous / in exclude 'dir/'
278 errors.fmap:3: superfluous / in include '/dir'
289 errors.fmap:3: superfluous / in include '/dir'
279 errors.fmap:3: superfluous / in rename '/dir'
290 errors.fmap:3: superfluous / in rename '/dir'
280 errors.fmap:3: superfluous / in exclude 'dir//dir'
291 errors.fmap:3: superfluous / in exclude 'dir//dir'
281 errors.fmap:4: unknown directive 'out of sync'
292 errors.fmap:4: unknown directive 'out of sync'
282 errors.fmap:5: path to exclude is missing
293 errors.fmap:5: path to exclude is missing
283 abort: errors in filemap
294 abort: errors in filemap
284 [255]
295 [255]
285
296
286 test branch closing revision pruning if branch is pruned
297 test branch closing revision pruning if branch is pruned
287
298
288 $ hg init branchpruning
299 $ hg init branchpruning
289 $ cd branchpruning
300 $ cd branchpruning
290 $ hg branch foo
301 $ hg branch foo
291 marked working directory as branch foo
302 marked working directory as branch foo
292 $ echo a > a
303 $ echo a > a
293 $ hg ci -Am adda
304 $ hg ci -Am adda
294 adding a
305 adding a
295 $ hg ci --close-branch -m closefoo
306 $ hg ci --close-branch -m closefoo
296 $ hg up 0
307 $ hg up 0
297 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
308 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
298 $ hg branch empty
309 $ hg branch empty
299 marked working directory as branch empty
310 marked working directory as branch empty
300 $ hg ci -m emptybranch
311 $ hg ci -m emptybranch
301 $ hg ci --close-branch -m closeempty
312 $ hg ci --close-branch -m closeempty
302 $ hg up 0
313 $ hg up 0
303 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
314 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
304 $ hg branch default
315 $ hg branch default
305 marked working directory as branch default
316 marked working directory as branch default
306 $ echo b > b
317 $ echo b > b
307 $ hg ci -Am addb
318 $ hg ci -Am addb
308 adding b
319 adding b
309 $ hg ci --close-branch -m closedefault
320 $ hg ci --close-branch -m closedefault
310 $ cat > filemap <<EOF
321 $ cat > filemap <<EOF
311 > include b
322 > include b
312 > EOF
323 > EOF
313 $ cd ..
324 $ cd ..
314 $ hg convert branchpruning branchpruning-hg1
325 $ hg convert branchpruning branchpruning-hg1
315 initializing destination branchpruning-hg1 repository
326 initializing destination branchpruning-hg1 repository
316 scanning source...
327 scanning source...
317 sorting...
328 sorting...
318 converting...
329 converting...
319 5 adda
330 5 adda
320 4 closefoo
331 4 closefoo
321 3 emptybranch
332 3 emptybranch
322 2 closeempty
333 2 closeempty
323 1 addb
334 1 addb
324 0 closedefault
335 0 closedefault
325 $ glog -R branchpruning-hg1
336 $ glog -R branchpruning-hg1
326 o 5 "closedefault" files:
337 o 5 "closedefault" files:
327 |
338 |
328 o 4 "addb" files: b
339 o 4 "addb" files: b
329 |
340 |
330 | o 3 "closeempty" files:
341 | o 3 "closeempty" files:
331 | |
342 | |
332 | o 2 "emptybranch" files:
343 | o 2 "emptybranch" files:
333 |/
344 |/
334 | o 1 "closefoo" files:
345 | o 1 "closefoo" files:
335 |/
346 |/
336 o 0 "adda" files: a
347 o 0 "adda" files: a
337
348
338
349
339 exercise incremental conversion at the same time
350 exercise incremental conversion at the same time
340
351
341 $ hg convert -r0 --filemap branchpruning/filemap branchpruning branchpruning-hg2
352 $ hg convert -r0 --filemap branchpruning/filemap branchpruning branchpruning-hg2
342 initializing destination branchpruning-hg2 repository
353 initializing destination branchpruning-hg2 repository
343 scanning source...
354 scanning source...
344 sorting...
355 sorting...
345 converting...
356 converting...
346 0 adda
357 0 adda
347 $ hg convert -r4 --filemap branchpruning/filemap branchpruning branchpruning-hg2
358 $ hg convert -r4 --filemap branchpruning/filemap branchpruning branchpruning-hg2
348 scanning source...
359 scanning source...
349 sorting...
360 sorting...
350 converting...
361 converting...
351 0 addb
362 0 addb
352 $ hg convert --filemap branchpruning/filemap branchpruning branchpruning-hg2
363 $ hg convert --filemap branchpruning/filemap branchpruning branchpruning-hg2
353 scanning source...
364 scanning source...
354 sorting...
365 sorting...
355 converting...
366 converting...
356 3 closefoo
367 3 closefoo
357 2 emptybranch
368 2 emptybranch
358 1 closeempty
369 1 closeempty
359 0 closedefault
370 0 closedefault
360 $ glog -R branchpruning-hg2
371 $ glog -R branchpruning-hg2
361 o 1 "closedefault" files:
372 o 1 "closedefault" files:
362 |
373 |
363 o 0 "addb" files: b
374 o 0 "addb" files: b
364
375
General Comments 0
You need to be logged in to leave comments. Login now