comparison hgext/convert/convcmd.py @ 43077:687b865b95ad

formatting: byteify all mercurial/ and hgext/ string literals Done with python3.7 contrib/byteify-strings.py -i $(hg files 'set:mercurial/**.py - mercurial/thirdparty/** + hgext/**.py - hgext/fsmonitor/pywatchman/** - mercurial/__init__.py') black -l 80 -t py33 -S $(hg files 'set:**.py - mercurial/thirdparty/** - "contrib/python-zstandard/**" - hgext/fsmonitor/pywatchman/**') # skip-blame mass-reformatting only Differential Revision: https://phab.mercurial-scm.org/D6972
author Augie Fackler <augie@google.com>
date Sun, 06 Oct 2019 09:48:39 -0400
parents 2372284d9457
children eef9a2d67051
comparison
equal deleted inserted replaced
43076:2372284d9457 43077:687b865b95ad
50 monotone_source = monotone.monotone_source 50 monotone_source = monotone.monotone_source
51 p4_source = p4.p4_source 51 p4_source = p4.p4_source
52 svn_sink = subversion.svn_sink 52 svn_sink = subversion.svn_sink
53 svn_source = subversion.svn_source 53 svn_source = subversion.svn_source
54 54
55 orig_encoding = 'ascii' 55 orig_encoding = b'ascii'
56 56
57 57
58 def recode(s): 58 def recode(s):
59 if isinstance(s, pycompat.unicode): 59 if isinstance(s, pycompat.unicode):
60 return s.encode(pycompat.sysstr(orig_encoding), 'replace') 60 return s.encode(pycompat.sysstr(orig_encoding), 'replace')
88 # If branch is None or empty, this commit is coming from the source 88 # If branch is None or empty, this commit is coming from the source
89 # repository's default branch and destined for the default branch in the 89 # repository's default branch and destined for the default branch in the
90 # destination repository. For such commits, using a literal "default" 90 # destination repository. For such commits, using a literal "default"
91 # in branchmap below allows the user to map "default" to an alternate 91 # in branchmap below allows the user to map "default" to an alternate
92 # default branch in the destination repository. 92 # default branch in the destination repository.
93 branch = branchmap.get(branch or 'default', branch) 93 branch = branchmap.get(branch or b'default', branch)
94 # At some point we used "None" literal to denote the default branch, 94 # At some point we used "None" literal to denote the default branch,
95 # attempt to use that for backward compatibility. 95 # attempt to use that for backward compatibility.
96 if not branch: 96 if not branch:
97 branch = branchmap.get('None', branch) 97 branch = branchmap.get(b'None', branch)
98 return branch 98 return branch
99 99
100 100
101 source_converters = [ 101 source_converters = [
102 ('cvs', convert_cvs, 'branchsort'), 102 (b'cvs', convert_cvs, b'branchsort'),
103 ('git', convert_git, 'branchsort'), 103 (b'git', convert_git, b'branchsort'),
104 ('svn', svn_source, 'branchsort'), 104 (b'svn', svn_source, b'branchsort'),
105 ('hg', mercurial_source, 'sourcesort'), 105 (b'hg', mercurial_source, b'sourcesort'),
106 ('darcs', darcs_source, 'branchsort'), 106 (b'darcs', darcs_source, b'branchsort'),
107 ('mtn', monotone_source, 'branchsort'), 107 (b'mtn', monotone_source, b'branchsort'),
108 ('gnuarch', gnuarch_source, 'branchsort'), 108 (b'gnuarch', gnuarch_source, b'branchsort'),
109 ('bzr', bzr_source, 'branchsort'), 109 (b'bzr', bzr_source, b'branchsort'),
110 ('p4', p4_source, 'branchsort'), 110 (b'p4', p4_source, b'branchsort'),
111 ] 111 ]
112 112
113 sink_converters = [ 113 sink_converters = [
114 ('hg', mercurial_sink), 114 (b'hg', mercurial_sink),
115 ('svn', svn_sink), 115 (b'svn', svn_sink),
116 ] 116 ]
117 117
118 118
119 def convertsource(ui, path, type, revs): 119 def convertsource(ui, path, type, revs):
120 exceptions = [] 120 exceptions = []
121 if type and type not in [s[0] for s in source_converters]: 121 if type and type not in [s[0] for s in source_converters]:
122 raise error.Abort(_('%s: invalid source repository type') % type) 122 raise error.Abort(_(b'%s: invalid source repository type') % type)
123 for name, source, sortmode in source_converters: 123 for name, source, sortmode in source_converters:
124 try: 124 try:
125 if not type or name == type: 125 if not type or name == type:
126 return source(ui, name, path, revs), sortmode 126 return source(ui, name, path, revs), sortmode
127 except (NoRepo, MissingTool) as inst: 127 except (NoRepo, MissingTool) as inst:
128 exceptions.append(inst) 128 exceptions.append(inst)
129 if not ui.quiet: 129 if not ui.quiet:
130 for inst in exceptions: 130 for inst in exceptions:
131 ui.write("%s\n" % pycompat.bytestr(inst.args[0])) 131 ui.write(b"%s\n" % pycompat.bytestr(inst.args[0]))
132 raise error.Abort(_('%s: missing or unsupported repository') % path) 132 raise error.Abort(_(b'%s: missing or unsupported repository') % path)
133 133
134 134
135 def convertsink(ui, path, type): 135 def convertsink(ui, path, type):
136 if type and type not in [s[0] for s in sink_converters]: 136 if type and type not in [s[0] for s in sink_converters]:
137 raise error.Abort(_('%s: invalid destination repository type') % type) 137 raise error.Abort(_(b'%s: invalid destination repository type') % type)
138 for name, sink in sink_converters: 138 for name, sink in sink_converters:
139 try: 139 try:
140 if not type or name == type: 140 if not type or name == type:
141 return sink(ui, name, path) 141 return sink(ui, name, path)
142 except NoRepo as inst: 142 except NoRepo as inst:
143 ui.note(_("convert: %s\n") % inst) 143 ui.note(_(b"convert: %s\n") % inst)
144 except MissingTool as inst: 144 except MissingTool as inst:
145 raise error.Abort('%s\n' % inst) 145 raise error.Abort(b'%s\n' % inst)
146 raise error.Abort(_('%s: unknown repository type') % path) 146 raise error.Abort(_(b'%s: unknown repository type') % path)
147 147
148 148
149 class progresssource(object): 149 class progresssource(object):
150 def __init__(self, ui, source, filecount): 150 def __init__(self, ui, source, filecount):
151 self.ui = ui 151 self.ui = ui
152 self.source = source 152 self.source = source
153 self.progress = ui.makeprogress( 153 self.progress = ui.makeprogress(
154 _('getting files'), unit=_('files'), total=filecount 154 _(b'getting files'), unit=_(b'files'), total=filecount
155 ) 155 )
156 156
157 def getfile(self, file, rev): 157 def getfile(self, file, rev):
158 self.progress.increment(item=file) 158 self.progress.increment(item=file)
159 return self.source.getfile(file, rev) 159 return self.source.getfile(file, rev)
187 # Read first the dst author map if any 187 # Read first the dst author map if any
188 authorfile = self.dest.authorfile() 188 authorfile = self.dest.authorfile()
189 if authorfile and os.path.exists(authorfile): 189 if authorfile and os.path.exists(authorfile):
190 self.readauthormap(authorfile) 190 self.readauthormap(authorfile)
191 # Extend/Override with new author map if necessary 191 # Extend/Override with new author map if necessary
192 if opts.get('authormap'): 192 if opts.get(b'authormap'):
193 self.readauthormap(opts.get('authormap')) 193 self.readauthormap(opts.get(b'authormap'))
194 self.authorfile = self.dest.authorfile() 194 self.authorfile = self.dest.authorfile()
195 195
196 self.splicemap = self.parsesplicemap(opts.get('splicemap')) 196 self.splicemap = self.parsesplicemap(opts.get(b'splicemap'))
197 self.branchmap = mapfile(ui, opts.get('branchmap')) 197 self.branchmap = mapfile(ui, opts.get(b'branchmap'))
198 198
199 def parsesplicemap(self, path): 199 def parsesplicemap(self, path):
200 """ check and validate the splicemap format and 200 """ check and validate the splicemap format and
201 return a child/parents dictionary. 201 return a child/parents dictionary.
202 Format checking has two parts. 202 Format checking has two parts.
209 209
210 if not path: 210 if not path:
211 return {} 211 return {}
212 m = {} 212 m = {}
213 try: 213 try:
214 fp = open(path, 'rb') 214 fp = open(path, b'rb')
215 for i, line in enumerate(util.iterfile(fp)): 215 for i, line in enumerate(util.iterfile(fp)):
216 line = line.splitlines()[0].rstrip() 216 line = line.splitlines()[0].rstrip()
217 if not line: 217 if not line:
218 # Ignore blank lines 218 # Ignore blank lines
219 continue 219 continue
220 # split line 220 # split line
221 lex = common.shlexer(data=line, whitespace=',') 221 lex = common.shlexer(data=line, whitespace=b',')
222 line = list(lex) 222 line = list(lex)
223 # check number of parents 223 # check number of parents
224 if not (2 <= len(line) <= 3): 224 if not (2 <= len(line) <= 3):
225 raise error.Abort( 225 raise error.Abort(
226 _( 226 _(
227 'syntax error in %s(%d): child parent1' 227 b'syntax error in %s(%d): child parent1'
228 '[,parent2] expected' 228 b'[,parent2] expected'
229 ) 229 )
230 % (path, i + 1) 230 % (path, i + 1)
231 ) 231 )
232 for part in line: 232 for part in line:
233 self.source.checkrevformat(part) 233 self.source.checkrevformat(part)
237 else: 237 else:
238 m[child] = p1 + p2 238 m[child] = p1 + p2
239 # if file does not exist or error reading, exit 239 # if file does not exist or error reading, exit
240 except IOError: 240 except IOError:
241 raise error.Abort( 241 raise error.Abort(
242 _('splicemap file not found or error reading %s:') % path 242 _(b'splicemap file not found or error reading %s:') % path
243 ) 243 )
244 return m 244 return m
245 245
246 def walktree(self, heads): 246 def walktree(self, heads):
247 '''Return a mapping that identifies the uncommitted parents of every 247 '''Return a mapping that identifies the uncommitted parents of every
249 visit = list(heads) 249 visit = list(heads)
250 known = set() 250 known = set()
251 parents = {} 251 parents = {}
252 numcommits = self.source.numcommits() 252 numcommits = self.source.numcommits()
253 progress = self.ui.makeprogress( 253 progress = self.ui.makeprogress(
254 _('scanning'), unit=_('revisions'), total=numcommits 254 _(b'scanning'), unit=_(b'revisions'), total=numcommits
255 ) 255 )
256 while visit: 256 while visit:
257 n = visit.pop(0) 257 n = visit.pop(0)
258 if n in known: 258 if n in known:
259 continue 259 continue
281 if c not in parents: 281 if c not in parents:
282 if not self.dest.hascommitforsplicemap(self.map.get(c, c)): 282 if not self.dest.hascommitforsplicemap(self.map.get(c, c)):
283 # Could be in source but not converted during this run 283 # Could be in source but not converted during this run
284 self.ui.warn( 284 self.ui.warn(
285 _( 285 _(
286 'splice map revision %s is not being ' 286 b'splice map revision %s is not being '
287 'converted, ignoring\n' 287 b'converted, ignoring\n'
288 ) 288 )
289 % c 289 % c
290 ) 290 )
291 continue 291 continue
292 pc = [] 292 pc = []
294 # We do not have to wait for nodes already in dest. 294 # We do not have to wait for nodes already in dest.
295 if self.dest.hascommitforsplicemap(self.map.get(p, p)): 295 if self.dest.hascommitforsplicemap(self.map.get(p, p)):
296 continue 296 continue
297 # Parent is not in dest and not being converted, not good 297 # Parent is not in dest and not being converted, not good
298 if p not in parents: 298 if p not in parents:
299 raise error.Abort(_('unknown splice map parent: %s') % p) 299 raise error.Abort(_(b'unknown splice map parent: %s') % p)
300 pc.append(p) 300 pc.append(p)
301 parents[c] = pc 301 parents[c] = pc
302 302
303 def toposort(self, parents, sortmode): 303 def toposort(self, parents, sortmode):
304 '''Return an ordering such that every uncommitted changeset is 304 '''Return an ordering such that every uncommitted changeset is
367 return picknext 367 return picknext
368 368
369 def makeclosesorter(): 369 def makeclosesorter():
370 """Close order sort.""" 370 """Close order sort."""
371 keyfn = lambda n: ( 371 keyfn = lambda n: (
372 'close' not in self.commitcache[n].extra, 372 b'close' not in self.commitcache[n].extra,
373 self.commitcache[n].sortkey, 373 self.commitcache[n].sortkey,
374 ) 374 )
375 375
376 def picknext(nodes): 376 def picknext(nodes):
377 return sorted(nodes, key=keyfn)[0] 377 return sorted(nodes, key=keyfn)[0]
390 def picknext(nodes): 390 def picknext(nodes):
391 return min([(getdate(n), n) for n in nodes])[1] 391 return min([(getdate(n), n) for n in nodes])[1]
392 392
393 return picknext 393 return picknext
394 394
395 if sortmode == 'branchsort': 395 if sortmode == b'branchsort':
396 picknext = makebranchsorter() 396 picknext = makebranchsorter()
397 elif sortmode == 'datesort': 397 elif sortmode == b'datesort':
398 picknext = makedatesorter() 398 picknext = makedatesorter()
399 elif sortmode == 'sourcesort': 399 elif sortmode == b'sourcesort':
400 picknext = makesourcesorter() 400 picknext = makesourcesorter()
401 elif sortmode == 'closesort': 401 elif sortmode == b'closesort':
402 picknext = makeclosesorter() 402 picknext = makeclosesorter()
403 else: 403 else:
404 raise error.Abort(_('unknown sort mode: %s') % sortmode) 404 raise error.Abort(_(b'unknown sort mode: %s') % sortmode)
405 405
406 children, actives = mapchildren(parents) 406 children, actives = mapchildren(parents)
407 407
408 s = [] 408 s = []
409 pendings = {} 409 pendings = {}
418 pendings[c] = [p for p in parents[c] if p not in self.map] 418 pendings[c] = [p for p in parents[c] if p not in self.map]
419 try: 419 try:
420 pendings[c].remove(n) 420 pendings[c].remove(n)
421 except ValueError: 421 except ValueError:
422 raise error.Abort( 422 raise error.Abort(
423 _('cycle detected between %s and %s') 423 _(b'cycle detected between %s and %s')
424 % (recode(c), recode(n)) 424 % (recode(c), recode(n))
425 ) 425 )
426 if not pendings[c]: 426 if not pendings[c]:
427 # Parents are converted, node is eligible 427 # Parents are converted, node is eligible
428 actives.insert(0, c) 428 actives.insert(0, c)
429 pendings[c] = None 429 pendings[c] = None
430 430
431 if len(s) != len(parents): 431 if len(s) != len(parents):
432 raise error.Abort(_("not all revisions were sorted")) 432 raise error.Abort(_(b"not all revisions were sorted"))
433 433
434 return s 434 return s
435 435
436 def writeauthormap(self): 436 def writeauthormap(self):
437 authorfile = self.authorfile 437 authorfile = self.authorfile
438 if authorfile: 438 if authorfile:
439 self.ui.status(_('writing author map file %s\n') % authorfile) 439 self.ui.status(_(b'writing author map file %s\n') % authorfile)
440 ofile = open(authorfile, 'wb+') 440 ofile = open(authorfile, b'wb+')
441 for author in self.authors: 441 for author in self.authors:
442 ofile.write( 442 ofile.write(
443 util.tonativeeol("%s=%s\n" % (author, self.authors[author])) 443 util.tonativeeol(
444 b"%s=%s\n" % (author, self.authors[author])
445 )
444 ) 446 )
445 ofile.close() 447 ofile.close()
446 448
447 def readauthormap(self, authorfile): 449 def readauthormap(self, authorfile):
448 afile = open(authorfile, 'rb') 450 afile = open(authorfile, b'rb')
449 for line in afile: 451 for line in afile:
450 452
451 line = line.strip() 453 line = line.strip()
452 if not line or line.startswith('#'): 454 if not line or line.startswith(b'#'):
453 continue 455 continue
454 456
455 try: 457 try:
456 srcauthor, dstauthor = line.split('=', 1) 458 srcauthor, dstauthor = line.split(b'=', 1)
457 except ValueError: 459 except ValueError:
458 msg = _('ignoring bad line in author map file %s: %s\n') 460 msg = _(b'ignoring bad line in author map file %s: %s\n')
459 self.ui.warn(msg % (authorfile, line.rstrip())) 461 self.ui.warn(msg % (authorfile, line.rstrip()))
460 continue 462 continue
461 463
462 srcauthor = srcauthor.strip() 464 srcauthor = srcauthor.strip()
463 dstauthor = dstauthor.strip() 465 dstauthor = dstauthor.strip()
464 if self.authors.get(srcauthor) in (None, dstauthor): 466 if self.authors.get(srcauthor) in (None, dstauthor):
465 msg = _('mapping author %s to %s\n') 467 msg = _(b'mapping author %s to %s\n')
466 self.ui.debug(msg % (srcauthor, dstauthor)) 468 self.ui.debug(msg % (srcauthor, dstauthor))
467 self.authors[srcauthor] = dstauthor 469 self.authors[srcauthor] = dstauthor
468 continue 470 continue
469 471
470 m = _('overriding mapping for author %s, was %s, will be %s\n') 472 m = _(b'overriding mapping for author %s, was %s, will be %s\n')
471 self.ui.status(m % (srcauthor, self.authors[srcauthor], dstauthor)) 473 self.ui.status(m % (srcauthor, self.authors[srcauthor], dstauthor))
472 474
473 afile.close() 475 afile.close()
474 476
475 def cachecommit(self, rev): 477 def cachecommit(self, rev):
479 self.commitcache[rev] = commit 481 self.commitcache[rev] = commit
480 return commit 482 return commit
481 483
482 def copy(self, rev): 484 def copy(self, rev):
483 commit = self.commitcache[rev] 485 commit = self.commitcache[rev]
484 full = self.opts.get('full') 486 full = self.opts.get(b'full')
485 changes = self.source.getchanges(rev, full) 487 changes = self.source.getchanges(rev, full)
486 if isinstance(changes, bytes): 488 if isinstance(changes, bytes):
487 if changes == SKIPREV: 489 if changes == SKIPREV:
488 dest = SKIPREV 490 dest = SKIPREV
489 else: 491 else:
501 ) 503 )
502 self.dest.setbranch(commit.branch, pbranches) 504 self.dest.setbranch(commit.branch, pbranches)
503 try: 505 try:
504 parents = self.splicemap[rev] 506 parents = self.splicemap[rev]
505 self.ui.status( 507 self.ui.status(
506 _('spliced in %s as parents of %s\n') 508 _(b'spliced in %s as parents of %s\n')
507 % (_(' and ').join(parents), rev) 509 % (_(b' and ').join(parents), rev)
508 ) 510 )
509 parents = [self.map.get(p, p) for p in parents] 511 parents = [self.map.get(p, p) for p in parents]
510 except KeyError: 512 except KeyError:
511 parents = [b[0] for b in pbranches] 513 parents = [b[0] for b in pbranches]
512 parents.extend( 514 parents.extend(
534 def convert(self, sortmode): 536 def convert(self, sortmode):
535 try: 537 try:
536 self.source.before() 538 self.source.before()
537 self.dest.before() 539 self.dest.before()
538 self.source.setrevmap(self.map) 540 self.source.setrevmap(self.map)
539 self.ui.status(_("scanning source...\n")) 541 self.ui.status(_(b"scanning source...\n"))
540 heads = self.source.getheads() 542 heads = self.source.getheads()
541 parents = self.walktree(heads) 543 parents = self.walktree(heads)
542 self.mergesplicemap(parents, self.splicemap) 544 self.mergesplicemap(parents, self.splicemap)
543 self.ui.status(_("sorting...\n")) 545 self.ui.status(_(b"sorting...\n"))
544 t = self.toposort(parents, sortmode) 546 t = self.toposort(parents, sortmode)
545 num = len(t) 547 num = len(t)
546 c = None 548 c = None
547 549
548 self.ui.status(_("converting...\n")) 550 self.ui.status(_(b"converting...\n"))
549 progress = self.ui.makeprogress( 551 progress = self.ui.makeprogress(
550 _('converting'), unit=_('revisions'), total=len(t) 552 _(b'converting'), unit=_(b'revisions'), total=len(t)
551 ) 553 )
552 for i, c in enumerate(t): 554 for i, c in enumerate(t):
553 num -= 1 555 num -= 1
554 desc = self.commitcache[c].desc 556 desc = self.commitcache[c].desc
555 if "\n" in desc: 557 if b"\n" in desc:
556 desc = desc.splitlines()[0] 558 desc = desc.splitlines()[0]
557 # convert log message to local encoding without using 559 # convert log message to local encoding without using
558 # tolocal() because the encoding.encoding convert() 560 # tolocal() because the encoding.encoding convert()
559 # uses is 'utf-8' 561 # uses is 'utf-8'
560 self.ui.status("%d %s\n" % (num, recode(desc))) 562 self.ui.status(b"%d %s\n" % (num, recode(desc)))
561 self.ui.note(_("source: %s\n") % recode(c)) 563 self.ui.note(_(b"source: %s\n") % recode(c))
562 progress.update(i) 564 progress.update(i)
563 self.copy(c) 565 self.copy(c)
564 progress.complete() 566 progress.complete()
565 567
566 if not self.ui.configbool('convert', 'skiptags'): 568 if not self.ui.configbool(b'convert', b'skiptags'):
567 tags = self.source.gettags() 569 tags = self.source.gettags()
568 ctags = {} 570 ctags = {}
569 for k in tags: 571 for k in tags:
570 v = tags[k] 572 v = tags[k]
571 if self.map.get(v, SKIPREV) != SKIPREV: 573 if self.map.get(v, SKIPREV) != SKIPREV:
608 610
609 def convert(ui, src, dest=None, revmapfile=None, **opts): 611 def convert(ui, src, dest=None, revmapfile=None, **opts):
610 opts = pycompat.byteskwargs(opts) 612 opts = pycompat.byteskwargs(opts)
611 global orig_encoding 613 global orig_encoding
612 orig_encoding = encoding.encoding 614 orig_encoding = encoding.encoding
613 encoding.encoding = 'UTF-8' 615 encoding.encoding = b'UTF-8'
614 616
615 # support --authors as an alias for --authormap 617 # support --authors as an alias for --authormap
616 if not opts.get('authormap'): 618 if not opts.get(b'authormap'):
617 opts['authormap'] = opts.get('authors') 619 opts[b'authormap'] = opts.get(b'authors')
618 620
619 if not dest: 621 if not dest:
620 dest = hg.defaultdest(src) + "-hg" 622 dest = hg.defaultdest(src) + b"-hg"
621 ui.status(_("assuming destination %s\n") % dest) 623 ui.status(_(b"assuming destination %s\n") % dest)
622 624
623 destc = convertsink(ui, dest, opts.get('dest_type')) 625 destc = convertsink(ui, dest, opts.get(b'dest_type'))
624 destc = scmutil.wrapconvertsink(destc) 626 destc = scmutil.wrapconvertsink(destc)
625 627
626 try: 628 try:
627 srcc, defaultsort = convertsource( 629 srcc, defaultsort = convertsource(
628 ui, src, opts.get('source_type'), opts.get('rev') 630 ui, src, opts.get(b'source_type'), opts.get(b'rev')
629 ) 631 )
630 except Exception: 632 except Exception:
631 for path in destc.created: 633 for path in destc.created:
632 shutil.rmtree(path, True) 634 shutil.rmtree(path, True)
633 raise 635 raise
634 636
635 sortmodes = ('branchsort', 'datesort', 'sourcesort', 'closesort') 637 sortmodes = (b'branchsort', b'datesort', b'sourcesort', b'closesort')
636 sortmode = [m for m in sortmodes if opts.get(m)] 638 sortmode = [m for m in sortmodes if opts.get(m)]
637 if len(sortmode) > 1: 639 if len(sortmode) > 1:
638 raise error.Abort(_('more than one sort mode specified')) 640 raise error.Abort(_(b'more than one sort mode specified'))
639 if sortmode: 641 if sortmode:
640 sortmode = sortmode[0] 642 sortmode = sortmode[0]
641 else: 643 else:
642 sortmode = defaultsort 644 sortmode = defaultsort
643 645
644 if sortmode == 'sourcesort' and not srcc.hasnativeorder(): 646 if sortmode == b'sourcesort' and not srcc.hasnativeorder():
645 raise error.Abort( 647 raise error.Abort(
646 _('--sourcesort is not supported by this data source') 648 _(b'--sourcesort is not supported by this data source')
647 ) 649 )
648 if sortmode == 'closesort' and not srcc.hasnativeclose(): 650 if sortmode == b'closesort' and not srcc.hasnativeclose():
649 raise error.Abort(_('--closesort is not supported by this data source')) 651 raise error.Abort(
650 652 _(b'--closesort is not supported by this data source')
651 fmap = opts.get('filemap') 653 )
654
655 fmap = opts.get(b'filemap')
652 if fmap: 656 if fmap:
653 srcc = filemap.filemap_source(ui, srcc, fmap) 657 srcc = filemap.filemap_source(ui, srcc, fmap)
654 destc.setfilemapmode(True) 658 destc.setfilemapmode(True)
655 659
656 if not revmapfile: 660 if not revmapfile: