comparison mercurial/hg.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 c59eb1560c44
comparison
equal deleted inserted replaced
43076:2372284d9457 43077:687b865b95ad
51 from .interfaces import repository as repositorymod 51 from .interfaces import repository as repositorymod
52 52
53 release = lock.release 53 release = lock.release
54 54
55 # shared features 55 # shared features
56 sharedbookmarks = 'bookmarks' 56 sharedbookmarks = b'bookmarks'
57 57
58 58
59 def _local(path): 59 def _local(path):
60 path = util.expandpath(util.urllocalpath(path)) 60 path = util.expandpath(util.urllocalpath(path))
61 61
62 try: 62 try:
63 isfile = os.path.isfile(path) 63 isfile = os.path.isfile(path)
64 # Python 2 raises TypeError, Python 3 ValueError. 64 # Python 2 raises TypeError, Python 3 ValueError.
65 except (TypeError, ValueError) as e: 65 except (TypeError, ValueError) as e:
66 raise error.Abort( 66 raise error.Abort(
67 _('invalid path %s: %s') % (path, pycompat.bytestr(e)) 67 _(b'invalid path %s: %s') % (path, pycompat.bytestr(e))
68 ) 68 )
69 69
70 return isfile and bundlerepo or localrepo 70 return isfile and bundlerepo or localrepo
71 71
72 72
83 if revs: 83 if revs:
84 revs = list(revs) 84 revs = list(revs)
85 else: 85 else:
86 revs = [] 86 revs = []
87 87
88 if not peer.capable('branchmap'): 88 if not peer.capable(b'branchmap'):
89 if branches: 89 if branches:
90 raise error.Abort(_("remote branch lookup not supported")) 90 raise error.Abort(_(b"remote branch lookup not supported"))
91 revs.append(hashbranch) 91 revs.append(hashbranch)
92 return revs, revs[0] 92 return revs, revs[0]
93 93
94 with peer.commandexecutor() as e: 94 with peer.commandexecutor() as e:
95 branchmap = e.callcommand('branchmap', {}).result() 95 branchmap = e.callcommand(b'branchmap', {}).result()
96 96
97 def primary(branch): 97 def primary(branch):
98 if branch == '.': 98 if branch == b'.':
99 if not lrepo: 99 if not lrepo:
100 raise error.Abort(_("dirstate branch not accessible")) 100 raise error.Abort(_(b"dirstate branch not accessible"))
101 branch = lrepo.dirstate.branch() 101 branch = lrepo.dirstate.branch()
102 if branch in branchmap: 102 if branch in branchmap:
103 revs.extend(node.hex(r) for r in reversed(branchmap[branch])) 103 revs.extend(node.hex(r) for r in reversed(branchmap[branch]))
104 return True 104 return True
105 else: 105 else:
106 return False 106 return False
107 107
108 for branch in branches: 108 for branch in branches:
109 if not primary(branch): 109 if not primary(branch):
110 raise error.RepoLookupError(_("unknown branch '%s'") % branch) 110 raise error.RepoLookupError(_(b"unknown branch '%s'") % branch)
111 if hashbranch: 111 if hashbranch:
112 if not primary(hashbranch): 112 if not primary(hashbranch):
113 revs.append(hashbranch) 113 revs.append(hashbranch)
114 return revs, revs[0] 114 return revs, revs[0]
115 115
124 u.fragment = None 124 u.fragment = None
125 return bytes(u), (branch, branches or []) 125 return bytes(u), (branch, branches or [])
126 126
127 127
128 schemes = { 128 schemes = {
129 'bundle': bundlerepo, 129 b'bundle': bundlerepo,
130 'union': unionrepo, 130 b'union': unionrepo,
131 'file': _local, 131 b'file': _local,
132 'http': httppeer, 132 b'http': httppeer,
133 'https': httppeer, 133 b'https': httppeer,
134 'ssh': sshpeer, 134 b'ssh': sshpeer,
135 'static-http': statichttprepo, 135 b'static-http': statichttprepo,
136 } 136 }
137 137
138 138
139 def _peerlookup(path): 139 def _peerlookup(path):
140 u = util.url(path) 140 u = util.url(path)
141 scheme = u.scheme or 'file' 141 scheme = u.scheme or b'file'
142 thing = schemes.get(scheme) or schemes['file'] 142 thing = schemes.get(scheme) or schemes[b'file']
143 try: 143 try:
144 return thing(path) 144 return thing(path)
145 except TypeError: 145 except TypeError:
146 # we can't test callable(thing) because 'thing' can be an unloaded 146 # we can't test callable(thing) because 'thing' can be an unloaded
147 # module that implements __call__ 147 # module that implements __call__
148 if not util.safehasattr(thing, 'instance'): 148 if not util.safehasattr(thing, b'instance'):
149 raise 149 raise
150 return thing 150 return thing
151 151
152 152
153 def islocal(repo): 153 def islocal(repo):
162 162
163 def openpath(ui, path, sendaccept=True): 163 def openpath(ui, path, sendaccept=True):
164 '''open path with open if local, url.open if remote''' 164 '''open path with open if local, url.open if remote'''
165 pathurl = util.url(path, parsequery=False, parsefragment=False) 165 pathurl = util.url(path, parsequery=False, parsefragment=False)
166 if pathurl.islocal(): 166 if pathurl.islocal():
167 return util.posixfile(pathurl.localpath(), 'rb') 167 return util.posixfile(pathurl.localpath(), b'rb')
168 else: 168 else:
169 return url.open(ui, path, sendaccept=sendaccept) 169 return url.open(ui, path, sendaccept=sendaccept)
170 170
171 171
172 # a list of (ui, repo) functions called for wire peer initialization 172 # a list of (ui, repo) functions called for wire peer initialization
182 ) 182 )
183 ui = getattr(obj, "ui", ui) 183 ui = getattr(obj, "ui", ui)
184 for f in presetupfuncs or []: 184 for f in presetupfuncs or []:
185 f(ui, obj) 185 f(ui, obj)
186 ui.log(b'extension', b'- executing reposetup hooks\n') 186 ui.log(b'extension', b'- executing reposetup hooks\n')
187 with util.timedcm('all reposetup') as allreposetupstats: 187 with util.timedcm(b'all reposetup') as allreposetupstats:
188 for name, module in extensions.extensions(ui): 188 for name, module in extensions.extensions(ui):
189 ui.log(b'extension', b' - running reposetup for %s\n', name) 189 ui.log(b'extension', b' - running reposetup for %s\n', name)
190 hook = getattr(module, 'reposetup', None) 190 hook = getattr(module, 'reposetup', None)
191 if hook: 191 if hook:
192 with util.timedcm('reposetup %r', name) as stats: 192 with util.timedcm(b'reposetup %r', name) as stats:
193 hook(ui, obj) 193 hook(ui, obj)
194 ui.log( 194 ui.log(
195 b'extension', b' > reposetup for %s took %s\n', name, stats 195 b'extension', b' > reposetup for %s took %s\n', name, stats
196 ) 196 )
197 ui.log(b'extension', b'> all reposetup took %s\n', allreposetupstats) 197 ui.log(b'extension', b'> all reposetup took %s\n', allreposetupstats)
200 f(ui, obj) 200 f(ui, obj)
201 return obj 201 return obj
202 202
203 203
204 def repository( 204 def repository(
205 ui, path='', create=False, presetupfuncs=None, intents=None, createopts=None 205 ui,
206 path=b'',
207 create=False,
208 presetupfuncs=None,
209 intents=None,
210 createopts=None,
206 ): 211 ):
207 """return a repository object for the specified path""" 212 """return a repository object for the specified path"""
208 peer = _peerorrepo( 213 peer = _peerorrepo(
209 ui, 214 ui,
210 path, 215 path,
214 createopts=createopts, 219 createopts=createopts,
215 ) 220 )
216 repo = peer.local() 221 repo = peer.local()
217 if not repo: 222 if not repo:
218 raise error.Abort( 223 raise error.Abort(
219 _("repository '%s' is not local") % (path or peer.url()) 224 _(b"repository '%s' is not local") % (path or peer.url())
220 ) 225 )
221 return repo.filtered('visible') 226 return repo.filtered(b'visible')
222 227
223 228
224 def peer(uiorrepo, opts, path, create=False, intents=None, createopts=None): 229 def peer(uiorrepo, opts, path, create=False, intents=None, createopts=None):
225 '''return a repository peer for the specified path''' 230 '''return a repository peer for the specified path'''
226 rui = remoteui(uiorrepo, opts) 231 rui = remoteui(uiorrepo, opts)
245 >>> defaultdest(b'http://example.org/foo/') 250 >>> defaultdest(b'http://example.org/foo/')
246 'foo' 251 'foo'
247 ''' 252 '''
248 path = util.url(source).path 253 path = util.url(source).path
249 if not path: 254 if not path:
250 return '' 255 return b''
251 return os.path.basename(os.path.normpath(path)) 256 return os.path.basename(os.path.normpath(path))
252 257
253 258
254 def sharedreposource(repo): 259 def sharedreposource(repo):
255 """Returns repository object for source repository of a shared repo. 260 """Returns repository object for source repository of a shared repo.
257 If repo is not a shared repository, returns None. 262 If repo is not a shared repository, returns None.
258 """ 263 """
259 if repo.sharedpath == repo.path: 264 if repo.sharedpath == repo.path:
260 return None 265 return None
261 266
262 if util.safehasattr(repo, 'srcrepo') and repo.srcrepo: 267 if util.safehasattr(repo, b'srcrepo') and repo.srcrepo:
263 return repo.srcrepo 268 return repo.srcrepo
264 269
265 # the sharedpath always ends in the .hg; we want the path to the repo 270 # the sharedpath always ends in the .hg; we want the path to the repo
266 source = repo.vfs.split(repo.sharedpath)[0] 271 source = repo.vfs.split(repo.sharedpath)[0]
267 srcurl, branches = parseurl(source) 272 srcurl, branches = parseurl(source)
280 relative=False, 285 relative=False,
281 ): 286 ):
282 '''create a shared repository''' 287 '''create a shared repository'''
283 288
284 if not islocal(source): 289 if not islocal(source):
285 raise error.Abort(_('can only share local repositories')) 290 raise error.Abort(_(b'can only share local repositories'))
286 291
287 if not dest: 292 if not dest:
288 dest = defaultdest(source) 293 dest = defaultdest(source)
289 else: 294 else:
290 dest = ui.expandpath(dest) 295 dest = ui.expandpath(dest)
305 r = repository( 310 r = repository(
306 ui, 311 ui,
307 dest, 312 dest,
308 create=True, 313 create=True,
309 createopts={ 314 createopts={
310 'sharedrepo': srcrepo, 315 b'sharedrepo': srcrepo,
311 'sharedrelative': relative, 316 b'sharedrelative': relative,
312 'shareditems': shareditems, 317 b'shareditems': shareditems,
313 }, 318 },
314 ) 319 )
315 320
316 postshare(srcrepo, r, defaultpath=defaultpath) 321 postshare(srcrepo, r, defaultpath=defaultpath)
317 r = repository(ui, dest) 322 r = repository(ui, dest)
336 # not pointed to by changesets, thus causing verify to 341 # not pointed to by changesets, thus causing verify to
337 # fail 342 # fail
338 destlock = copystore(ui, repo, repo.path) 343 destlock = copystore(ui, repo, repo.path)
339 with destlock or util.nullcontextmanager(): 344 with destlock or util.nullcontextmanager():
340 345
341 sharefile = repo.vfs.join('sharedpath') 346 sharefile = repo.vfs.join(b'sharedpath')
342 util.rename(sharefile, sharefile + '.old') 347 util.rename(sharefile, sharefile + b'.old')
343 348
344 repo.requirements.discard('shared') 349 repo.requirements.discard(b'shared')
345 repo.requirements.discard('relshared') 350 repo.requirements.discard(b'relshared')
346 repo._writerequirements() 351 repo._writerequirements()
347 352
348 # Removing share changes some fundamental properties of the repo instance. 353 # Removing share changes some fundamental properties of the repo instance.
349 # So we instantiate a new repo object and operate on it rather than 354 # So we instantiate a new repo object and operate on it rather than
350 # try to keep the existing repo usable. 355 # try to keep the existing repo usable.
351 newrepo = repository(repo.baseui, repo.root, create=False) 356 newrepo = repository(repo.baseui, repo.root, create=False)
352 357
353 # TODO: figure out how to access subrepos that exist, but were previously 358 # TODO: figure out how to access subrepos that exist, but were previously
354 # removed from .hgsub 359 # removed from .hgsub
355 c = newrepo['.'] 360 c = newrepo[b'.']
356 subs = c.substate 361 subs = c.substate
357 for s in sorted(subs): 362 for s in sorted(subs):
358 c.sub(s).unshare() 363 c.sub(s).unshare()
359 364
360 localrepo.poisonrepository(repo) 365 localrepo.poisonrepository(repo)
369 This function configures additional shared data. 374 This function configures additional shared data.
370 375
371 Extensions can wrap this function and write additional entries to 376 Extensions can wrap this function and write additional entries to
372 destrepo/.hg/shared to indicate additional pieces of data to be shared. 377 destrepo/.hg/shared to indicate additional pieces of data to be shared.
373 """ 378 """
374 default = defaultpath or sourcerepo.ui.config('paths', 'default') 379 default = defaultpath or sourcerepo.ui.config(b'paths', b'default')
375 if default: 380 if default:
376 template = '[paths]\n' 'default = %s\n' 381 template = b'[paths]\n' b'default = %s\n'
377 destrepo.vfs.write('hgrc', util.tonativeeol(template % default)) 382 destrepo.vfs.write(b'hgrc', util.tonativeeol(template % default))
378 if repositorymod.NARROW_REQUIREMENT in sourcerepo.requirements: 383 if repositorymod.NARROW_REQUIREMENT in sourcerepo.requirements:
379 with destrepo.wlock(): 384 with destrepo.wlock():
380 narrowspec.copytoworkingcopy(destrepo) 385 narrowspec.copytoworkingcopy(destrepo)
381 386
382 387
386 ``update`` can be a boolean or a revision to update to. 391 ``update`` can be a boolean or a revision to update to.
387 """ 392 """
388 if not update: 393 if not update:
389 return 394 return
390 395
391 repo.ui.status(_("updating working directory\n")) 396 repo.ui.status(_(b"updating working directory\n"))
392 if update is not True: 397 if update is not True:
393 checkout = update 398 checkout = update
394 for test in (checkout, 'default', 'tip'): 399 for test in (checkout, b'default', b'tip'):
395 if test is None: 400 if test is None:
396 continue 401 continue
397 try: 402 try:
398 uprev = repo.lookup(test) 403 uprev = repo.lookup(test)
399 break 404 break
408 returns destlock 413 returns destlock
409 ''' 414 '''
410 destlock = None 415 destlock = None
411 try: 416 try:
412 hardlink = None 417 hardlink = None
413 topic = _('linking') if hardlink else _('copying') 418 topic = _(b'linking') if hardlink else _(b'copying')
414 with ui.makeprogress(topic, unit=_('files')) as progress: 419 with ui.makeprogress(topic, unit=_(b'files')) as progress:
415 num = 0 420 num = 0
416 srcpublishing = srcrepo.publishing() 421 srcpublishing = srcrepo.publishing()
417 srcvfs = vfsmod.vfs(srcrepo.sharedpath) 422 srcvfs = vfsmod.vfs(srcrepo.sharedpath)
418 dstvfs = vfsmod.vfs(destpath) 423 dstvfs = vfsmod.vfs(destpath)
419 for f in srcrepo.store.copylist(): 424 for f in srcrepo.store.copylist():
420 if srcpublishing and f.endswith('phaseroots'): 425 if srcpublishing and f.endswith(b'phaseroots'):
421 continue 426 continue
422 dstbase = os.path.dirname(f) 427 dstbase = os.path.dirname(f)
423 if dstbase and not dstvfs.exists(dstbase): 428 if dstbase and not dstvfs.exists(dstbase):
424 dstvfs.mkdir(dstbase) 429 dstvfs.mkdir(dstbase)
425 if srcvfs.exists(f): 430 if srcvfs.exists(f):
426 if f.endswith('data'): 431 if f.endswith(b'data'):
427 # 'dstbase' may be empty (e.g. revlog format 0) 432 # 'dstbase' may be empty (e.g. revlog format 0)
428 lockfile = os.path.join(dstbase, "lock") 433 lockfile = os.path.join(dstbase, b"lock")
429 # lock to avoid premature writing to the target 434 # lock to avoid premature writing to the target
430 destlock = lock.lock(dstvfs, lockfile) 435 destlock = lock.lock(dstvfs, lockfile)
431 hardlink, n = util.copyfiles( 436 hardlink, n = util.copyfiles(
432 srcvfs.join(f), dstvfs.join(f), hardlink, progress 437 srcvfs.join(f), dstvfs.join(f), hardlink, progress
433 ) 438 )
434 num += n 439 num += n
435 if hardlink: 440 if hardlink:
436 ui.debug("linked %d files\n" % num) 441 ui.debug(b"linked %d files\n" % num)
437 else: 442 else:
438 ui.debug("copied %d files\n" % num) 443 ui.debug(b"copied %d files\n" % num)
439 return destlock 444 return destlock
440 except: # re-raises 445 except: # re-raises
441 release(destlock) 446 release(destlock)
442 raise 447 raise
443 448
461 will be created at "dest" and a working copy will be created if "update" is 466 will be created at "dest" and a working copy will be created if "update" is
462 True. 467 True.
463 """ 468 """
464 revs = None 469 revs = None
465 if rev: 470 if rev:
466 if not srcpeer.capable('lookup'): 471 if not srcpeer.capable(b'lookup'):
467 raise error.Abort( 472 raise error.Abort(
468 _( 473 _(
469 "src repository does not support " 474 b"src repository does not support "
470 "revision lookup and so doesn't " 475 b"revision lookup and so doesn't "
471 "support clone by revision" 476 b"support clone by revision"
472 ) 477 )
473 ) 478 )
474 479
475 # TODO this is batchable. 480 # TODO this is batchable.
476 remoterevs = [] 481 remoterevs = []
477 for r in rev: 482 for r in rev:
478 with srcpeer.commandexecutor() as e: 483 with srcpeer.commandexecutor() as e:
479 remoterevs.append(e.callcommand('lookup', {'key': r,}).result()) 484 remoterevs.append(
485 e.callcommand(b'lookup', {b'key': r,}).result()
486 )
480 revs = remoterevs 487 revs = remoterevs
481 488
482 # Obtain a lock before checking for or cloning the pooled repo otherwise 489 # Obtain a lock before checking for or cloning the pooled repo otherwise
483 # 2 clients may race creating or populating it. 490 # 2 clients may race creating or populating it.
484 pooldir = os.path.dirname(sharepath) 491 pooldir = os.path.dirname(sharepath)
490 raise 497 raise
491 498
492 poolvfs = vfsmod.vfs(pooldir) 499 poolvfs = vfsmod.vfs(pooldir)
493 basename = os.path.basename(sharepath) 500 basename = os.path.basename(sharepath)
494 501
495 with lock.lock(poolvfs, '%s.lock' % basename): 502 with lock.lock(poolvfs, b'%s.lock' % basename):
496 if os.path.exists(sharepath): 503 if os.path.exists(sharepath):
497 ui.status( 504 ui.status(
498 _('(sharing from existing pooled repository %s)\n') % basename 505 _(b'(sharing from existing pooled repository %s)\n') % basename
499 ) 506 )
500 else: 507 else:
501 ui.status(_('(sharing from new pooled repository %s)\n') % basename) 508 ui.status(
509 _(b'(sharing from new pooled repository %s)\n') % basename
510 )
502 # Always use pull mode because hardlinks in share mode don't work 511 # Always use pull mode because hardlinks in share mode don't work
503 # well. Never update because working copies aren't necessary in 512 # well. Never update because working copies aren't necessary in
504 # share mode. 513 # share mode.
505 clone( 514 clone(
506 ui, 515 ui,
543 552
544 # Recomputing branch cache might be slow on big repos, 553 # Recomputing branch cache might be slow on big repos,
545 # so just copy it 554 # so just copy it
546 def _copycache(srcrepo, dstcachedir, fname): 555 def _copycache(srcrepo, dstcachedir, fname):
547 """copy a cache from srcrepo to destcachedir (if it exists)""" 556 """copy a cache from srcrepo to destcachedir (if it exists)"""
548 srcbranchcache = srcrepo.vfs.join('cache/%s' % fname) 557 srcbranchcache = srcrepo.vfs.join(b'cache/%s' % fname)
549 dstbranchcache = os.path.join(dstcachedir, fname) 558 dstbranchcache = os.path.join(dstcachedir, fname)
550 if os.path.exists(srcbranchcache): 559 if os.path.exists(srcbranchcache):
551 if not os.path.exists(dstcachedir): 560 if not os.path.exists(dstcachedir):
552 os.mkdir(dstcachedir) 561 os.mkdir(dstcachedir)
553 util.copyfile(srcbranchcache, dstbranchcache) 562 util.copyfile(srcbranchcache, dstbranchcache)
629 revs, checkout = addbranchrevs(srcpeer, srcpeer, branches, revs) 638 revs, checkout = addbranchrevs(srcpeer, srcpeer, branches, revs)
630 639
631 if dest is None: 640 if dest is None:
632 dest = defaultdest(source) 641 dest = defaultdest(source)
633 if dest: 642 if dest:
634 ui.status(_("destination directory: %s\n") % dest) 643 ui.status(_(b"destination directory: %s\n") % dest)
635 else: 644 else:
636 dest = ui.expandpath(dest) 645 dest = ui.expandpath(dest)
637 646
638 dest = util.urllocalpath(dest) 647 dest = util.urllocalpath(dest)
639 source = util.urllocalpath(source) 648 source = util.urllocalpath(source)
640 649
641 if not dest: 650 if not dest:
642 raise error.Abort(_("empty destination path is not valid")) 651 raise error.Abort(_(b"empty destination path is not valid"))
643 652
644 destvfs = vfsmod.vfs(dest, expandpath=True) 653 destvfs = vfsmod.vfs(dest, expandpath=True)
645 if destvfs.lexists(): 654 if destvfs.lexists():
646 if not destvfs.isdir(): 655 if not destvfs.isdir():
647 raise error.Abort(_("destination '%s' already exists") % dest) 656 raise error.Abort(_(b"destination '%s' already exists") % dest)
648 elif destvfs.listdir(): 657 elif destvfs.listdir():
649 raise error.Abort(_("destination '%s' is not empty") % dest) 658 raise error.Abort(_(b"destination '%s' is not empty") % dest)
650 659
651 createopts = {} 660 createopts = {}
652 narrow = False 661 narrow = False
653 662
654 if storeincludepats is not None: 663 if storeincludepats is not None:
660 narrow = True 669 narrow = True
661 670
662 if narrow: 671 if narrow:
663 # Include everything by default if only exclusion patterns defined. 672 # Include everything by default if only exclusion patterns defined.
664 if storeexcludepats and not storeincludepats: 673 if storeexcludepats and not storeincludepats:
665 storeincludepats = {'path:.'} 674 storeincludepats = {b'path:.'}
666 675
667 createopts['narrowfiles'] = True 676 createopts[b'narrowfiles'] = True
668 677
669 if depth: 678 if depth:
670 createopts['shallowfilestore'] = True 679 createopts[b'shallowfilestore'] = True
671 680
672 if srcpeer.capable(b'lfs-serve'): 681 if srcpeer.capable(b'lfs-serve'):
673 # Repository creation honors the config if it disabled the extension, so 682 # Repository creation honors the config if it disabled the extension, so
674 # we can't just announce that lfs will be enabled. This check avoids 683 # we can't just announce that lfs will be enabled. This check avoids
675 # saying that lfs will be enabled, and then saying it's an unknown 684 # saying that lfs will be enabled, and then saying it's an unknown
676 # feature. The lfs creation option is set in either case so that a 685 # feature. The lfs creation option is set in either case so that a
677 # requirement is added. If the extension is explicitly disabled but the 686 # requirement is added. If the extension is explicitly disabled but the
678 # requirement is set, the clone aborts early, before transferring any 687 # requirement is set, the clone aborts early, before transferring any
679 # data. 688 # data.
680 createopts['lfs'] = True 689 createopts[b'lfs'] = True
681 690
682 if extensions.disabledext('lfs'): 691 if extensions.disabledext(b'lfs'):
683 ui.status( 692 ui.status(
684 _( 693 _(
685 '(remote is using large file support (lfs), but it is ' 694 b'(remote is using large file support (lfs), but it is '
686 'explicitly disabled in the local configuration)\n' 695 b'explicitly disabled in the local configuration)\n'
687 ) 696 )
688 ) 697 )
689 else: 698 else:
690 ui.status( 699 ui.status(
691 _( 700 _(
692 '(remote is using large file support (lfs); lfs will ' 701 b'(remote is using large file support (lfs); lfs will '
693 'be enabled for this repository)\n' 702 b'be enabled for this repository)\n'
694 ) 703 )
695 ) 704 )
696 705
697 shareopts = shareopts or {} 706 shareopts = shareopts or {}
698 sharepool = shareopts.get('pool') 707 sharepool = shareopts.get(b'pool')
699 sharenamemode = shareopts.get('mode') 708 sharenamemode = shareopts.get(b'mode')
700 if sharepool and islocal(dest): 709 if sharepool and islocal(dest):
701 sharepath = None 710 sharepath = None
702 if sharenamemode == 'identity': 711 if sharenamemode == b'identity':
703 # Resolve the name from the initial changeset in the remote 712 # Resolve the name from the initial changeset in the remote
704 # repository. This returns nullid when the remote is empty. It 713 # repository. This returns nullid when the remote is empty. It
705 # raises RepoLookupError if revision 0 is filtered or otherwise 714 # raises RepoLookupError if revision 0 is filtered or otherwise
706 # not available. If we fail to resolve, sharing is not enabled. 715 # not available. If we fail to resolve, sharing is not enabled.
707 try: 716 try:
708 with srcpeer.commandexecutor() as e: 717 with srcpeer.commandexecutor() as e:
709 rootnode = e.callcommand('lookup', {'key': '0',}).result() 718 rootnode = e.callcommand(
719 b'lookup', {b'key': b'0',}
720 ).result()
710 721
711 if rootnode != node.nullid: 722 if rootnode != node.nullid:
712 sharepath = os.path.join(sharepool, node.hex(rootnode)) 723 sharepath = os.path.join(sharepool, node.hex(rootnode))
713 else: 724 else:
714 ui.status( 725 ui.status(
715 _( 726 _(
716 '(not using pooled storage: ' 727 b'(not using pooled storage: '
717 'remote appears to be empty)\n' 728 b'remote appears to be empty)\n'
718 ) 729 )
719 ) 730 )
720 except error.RepoLookupError: 731 except error.RepoLookupError:
721 ui.status( 732 ui.status(
722 _( 733 _(
723 '(not using pooled storage: ' 734 b'(not using pooled storage: '
724 'unable to resolve identity of remote)\n' 735 b'unable to resolve identity of remote)\n'
725 ) 736 )
726 ) 737 )
727 elif sharenamemode == 'remote': 738 elif sharenamemode == b'remote':
728 sharepath = os.path.join( 739 sharepath = os.path.join(
729 sharepool, node.hex(hashlib.sha1(source).digest()) 740 sharepool, node.hex(hashlib.sha1(source).digest())
730 ) 741 )
731 else: 742 else:
732 raise error.Abort( 743 raise error.Abort(
733 _('unknown share naming mode: %s') % sharenamemode 744 _(b'unknown share naming mode: %s') % sharenamemode
734 ) 745 )
735 746
736 # TODO this is a somewhat arbitrary restriction. 747 # TODO this is a somewhat arbitrary restriction.
737 if narrow: 748 if narrow:
738 ui.status(_('(pooled storage not supported for narrow clones)\n')) 749 ui.status(_(b'(pooled storage not supported for narrow clones)\n'))
739 sharepath = None 750 sharepath = None
740 751
741 if sharepath: 752 if sharepath:
742 return clonewithshare( 753 return clonewithshare(
743 ui, 754 ui,
784 srclock = srcrepo.lock(wait=False) 795 srclock = srcrepo.lock(wait=False)
785 except error.LockError: 796 except error.LockError:
786 copy = False 797 copy = False
787 798
788 if copy: 799 if copy:
789 srcrepo.hook('preoutgoing', throw=True, source='clone') 800 srcrepo.hook(b'preoutgoing', throw=True, source=b'clone')
790 hgdir = os.path.realpath(os.path.join(dest, ".hg")) 801 hgdir = os.path.realpath(os.path.join(dest, b".hg"))
791 if not os.path.exists(dest): 802 if not os.path.exists(dest):
792 util.makedirs(dest) 803 util.makedirs(dest)
793 else: 804 else:
794 # only clean up directories we create ourselves 805 # only clean up directories we create ourselves
795 cleandir = hgdir 806 cleandir = hgdir
798 util.makedir(destpath, notindexed=True) 809 util.makedir(destpath, notindexed=True)
799 except OSError as inst: 810 except OSError as inst:
800 if inst.errno == errno.EEXIST: 811 if inst.errno == errno.EEXIST:
801 cleandir = None 812 cleandir = None
802 raise error.Abort( 813 raise error.Abort(
803 _("destination '%s' already exists") % dest 814 _(b"destination '%s' already exists") % dest
804 ) 815 )
805 raise 816 raise
806 817
807 destlock = copystore(ui, srcrepo, destpath) 818 destlock = copystore(ui, srcrepo, destpath)
808 # copy bookmarks over 819 # copy bookmarks over
809 srcbookmarks = srcrepo.vfs.join('bookmarks') 820 srcbookmarks = srcrepo.vfs.join(b'bookmarks')
810 dstbookmarks = os.path.join(destpath, 'bookmarks') 821 dstbookmarks = os.path.join(destpath, b'bookmarks')
811 if os.path.exists(srcbookmarks): 822 if os.path.exists(srcbookmarks):
812 util.copyfile(srcbookmarks, dstbookmarks) 823 util.copyfile(srcbookmarks, dstbookmarks)
813 824
814 dstcachedir = os.path.join(destpath, 'cache') 825 dstcachedir = os.path.join(destpath, b'cache')
815 for cache in cacheutil.cachetocopy(srcrepo): 826 for cache in cacheutil.cachetocopy(srcrepo):
816 _copycache(srcrepo, dstcachedir, cache) 827 _copycache(srcrepo, dstcachedir, cache)
817 828
818 # we need to re-init the repo after manually copying the data 829 # we need to re-init the repo after manually copying the data
819 # into it 830 # into it
820 destpeer = peer(srcrepo, peeropts, dest) 831 destpeer = peer(srcrepo, peeropts, dest)
821 srcrepo.hook('outgoing', source='clone', node=node.hex(node.nullid)) 832 srcrepo.hook(
833 b'outgoing', source=b'clone', node=node.hex(node.nullid)
834 )
822 else: 835 else:
823 try: 836 try:
824 # only pass ui when no srcrepo 837 # only pass ui when no srcrepo
825 destpeer = peer( 838 destpeer = peer(
826 srcrepo or ui, 839 srcrepo or ui,
831 ) 844 )
832 except OSError as inst: 845 except OSError as inst:
833 if inst.errno == errno.EEXIST: 846 if inst.errno == errno.EEXIST:
834 cleandir = None 847 cleandir = None
835 raise error.Abort( 848 raise error.Abort(
836 _("destination '%s' already exists") % dest 849 _(b"destination '%s' already exists") % dest
837 ) 850 )
838 raise 851 raise
839 852
840 if revs: 853 if revs:
841 if not srcpeer.capable('lookup'): 854 if not srcpeer.capable(b'lookup'):
842 raise error.Abort( 855 raise error.Abort(
843 _( 856 _(
844 "src repository does not support " 857 b"src repository does not support "
845 "revision lookup and so doesn't " 858 b"revision lookup and so doesn't "
846 "support clone by revision" 859 b"support clone by revision"
847 ) 860 )
848 ) 861 )
849 862
850 # TODO this is batchable. 863 # TODO this is batchable.
851 remoterevs = [] 864 remoterevs = []
852 for rev in revs: 865 for rev in revs:
853 with srcpeer.commandexecutor() as e: 866 with srcpeer.commandexecutor() as e:
854 remoterevs.append( 867 remoterevs.append(
855 e.callcommand('lookup', {'key': rev,}).result() 868 e.callcommand(b'lookup', {b'key': rev,}).result()
856 ) 869 )
857 revs = remoterevs 870 revs = remoterevs
858 871
859 checkout = revs[0] 872 checkout = revs[0]
860 else: 873 else:
866 local.setnarrowpats(storeincludepats, storeexcludepats) 879 local.setnarrowpats(storeincludepats, storeexcludepats)
867 narrowspec.copytoworkingcopy(local) 880 narrowspec.copytoworkingcopy(local)
868 881
869 u = util.url(abspath) 882 u = util.url(abspath)
870 defaulturl = bytes(u) 883 defaulturl = bytes(u)
871 local.ui.setconfig('paths', 'default', defaulturl, 'clone') 884 local.ui.setconfig(b'paths', b'default', defaulturl, b'clone')
872 if not stream: 885 if not stream:
873 if pull: 886 if pull:
874 stream = False 887 stream = False
875 else: 888 else:
876 stream = None 889 stream = None
877 # internal config: ui.quietbookmarkmove 890 # internal config: ui.quietbookmarkmove
878 overrides = {('ui', 'quietbookmarkmove'): True} 891 overrides = {(b'ui', b'quietbookmarkmove'): True}
879 with local.ui.configoverride(overrides, 'clone'): 892 with local.ui.configoverride(overrides, b'clone'):
880 exchange.pull( 893 exchange.pull(
881 local, 894 local,
882 srcpeer, 895 srcpeer,
883 revs, 896 revs,
884 streamclonerequested=stream, 897 streamclonerequested=stream,
890 # TODO lift restriction once exchange.push() accepts narrow 903 # TODO lift restriction once exchange.push() accepts narrow
891 # push. 904 # push.
892 if narrow: 905 if narrow:
893 raise error.Abort( 906 raise error.Abort(
894 _( 907 _(
895 'narrow clone not available for ' 908 b'narrow clone not available for '
896 'remote destinations' 909 b'remote destinations'
897 ) 910 )
898 ) 911 )
899 912
900 exchange.push( 913 exchange.push(
901 srcrepo, 914 srcrepo,
903 revs=revs, 916 revs=revs,
904 bookmarks=srcrepo._bookmarks.keys(), 917 bookmarks=srcrepo._bookmarks.keys(),
905 ) 918 )
906 else: 919 else:
907 raise error.Abort( 920 raise error.Abort(
908 _("clone from remote to remote not supported") 921 _(b"clone from remote to remote not supported")
909 ) 922 )
910 923
911 cleandir = None 924 cleandir = None
912 925
913 destrepo = destpeer.local() 926 destrepo = destpeer.local()
914 if destrepo: 927 if destrepo:
915 template = uimod.samplehgrcs['cloned'] 928 template = uimod.samplehgrcs[b'cloned']
916 u = util.url(abspath) 929 u = util.url(abspath)
917 u.passwd = None 930 u.passwd = None
918 defaulturl = bytes(u) 931 defaulturl = bytes(u)
919 destrepo.vfs.write('hgrc', util.tonativeeol(template % defaulturl)) 932 destrepo.vfs.write(b'hgrc', util.tonativeeol(template % defaulturl))
920 destrepo.ui.setconfig('paths', 'default', defaulturl, 'clone') 933 destrepo.ui.setconfig(b'paths', b'default', defaulturl, b'clone')
921 934
922 if ui.configbool('experimental', 'remotenames'): 935 if ui.configbool(b'experimental', b'remotenames'):
923 logexchange.pullremotenames(destrepo, srcpeer) 936 logexchange.pullremotenames(destrepo, srcpeer)
924 937
925 if update: 938 if update:
926 if update is not True: 939 if update is not True:
927 with srcpeer.commandexecutor() as e: 940 with srcpeer.commandexecutor() as e:
928 checkout = e.callcommand( 941 checkout = e.callcommand(
929 'lookup', {'key': update,} 942 b'lookup', {b'key': update,}
930 ).result() 943 ).result()
931 944
932 uprev = None 945 uprev = None
933 status = None 946 status = None
934 if checkout is not None: 947 if checkout is not None:
946 uprev = destrepo.lookup(update) 959 uprev = destrepo.lookup(update)
947 except error.RepoLookupError: 960 except error.RepoLookupError:
948 pass 961 pass
949 if uprev is None: 962 if uprev is None:
950 try: 963 try:
951 uprev = destrepo._bookmarks['@'] 964 uprev = destrepo._bookmarks[b'@']
952 update = '@' 965 update = b'@'
953 bn = destrepo[uprev].branch() 966 bn = destrepo[uprev].branch()
954 if bn == 'default': 967 if bn == b'default':
955 status = _("updating to bookmark @\n") 968 status = _(b"updating to bookmark @\n")
956 else: 969 else:
957 status = ( 970 status = (
958 _("updating to bookmark @ on branch %s\n") % bn 971 _(b"updating to bookmark @ on branch %s\n") % bn
959 ) 972 )
960 except KeyError: 973 except KeyError:
961 try: 974 try:
962 uprev = destrepo.branchtip('default') 975 uprev = destrepo.branchtip(b'default')
963 except error.RepoLookupError: 976 except error.RepoLookupError:
964 uprev = destrepo.lookup('tip') 977 uprev = destrepo.lookup(b'tip')
965 if not status: 978 if not status:
966 bn = destrepo[uprev].branch() 979 bn = destrepo[uprev].branch()
967 status = _("updating to branch %s\n") % bn 980 status = _(b"updating to branch %s\n") % bn
968 destrepo.ui.status(status) 981 destrepo.ui.status(status)
969 _update(destrepo, uprev) 982 _update(destrepo, uprev)
970 if update in destrepo._bookmarks: 983 if update in destrepo._bookmarks:
971 bookmarks.activate(destrepo, update) 984 bookmarks.activate(destrepo, update)
972 finally: 985 finally:
981 def _showstats(repo, stats, quietempty=False): 994 def _showstats(repo, stats, quietempty=False):
982 if quietempty and stats.isempty(): 995 if quietempty and stats.isempty():
983 return 996 return
984 repo.ui.status( 997 repo.ui.status(
985 _( 998 _(
986 "%d files updated, %d files merged, " 999 b"%d files updated, %d files merged, "
987 "%d files removed, %d files unresolved\n" 1000 b"%d files removed, %d files unresolved\n"
988 ) 1001 )
989 % ( 1002 % (
990 stats.updatedcount, 1003 stats.updatedcount,
991 stats.mergedcount, 1004 stats.mergedcount,
992 stats.removedcount, 1005 stats.removedcount,
1004 return mergemod.update( 1017 return mergemod.update(
1005 repo, 1018 repo,
1006 node, 1019 node,
1007 branchmerge=False, 1020 branchmerge=False,
1008 force=overwrite, 1021 force=overwrite,
1009 labels=['working copy', 'destination'], 1022 labels=[b'working copy', b'destination'],
1010 updatecheck=updatecheck, 1023 updatecheck=updatecheck,
1011 ) 1024 )
1012 1025
1013 1026
1014 def update(repo, node, quietempty=False, updatecheck=None): 1027 def update(repo, node, quietempty=False, updatecheck=None):
1015 """update the working directory to node""" 1028 """update the working directory to node"""
1016 stats = updaterepo(repo, node, False, updatecheck=updatecheck) 1029 stats = updaterepo(repo, node, False, updatecheck=updatecheck)
1017 _showstats(repo, stats, quietempty) 1030 _showstats(repo, stats, quietempty)
1018 if stats.unresolvedcount: 1031 if stats.unresolvedcount:
1019 repo.ui.status(_("use 'hg resolve' to retry unresolved file merges\n")) 1032 repo.ui.status(_(b"use 'hg resolve' to retry unresolved file merges\n"))
1020 return stats.unresolvedcount > 0 1033 return stats.unresolvedcount > 0
1021 1034
1022 1035
1023 # naming conflict in clone() 1036 # naming conflict in clone()
1024 _update = update 1037 _update = update
1025 1038
1026 1039
1027 def clean(repo, node, show_stats=True, quietempty=False): 1040 def clean(repo, node, show_stats=True, quietempty=False):
1028 """forcibly switch the working directory to node, clobbering changes""" 1041 """forcibly switch the working directory to node, clobbering changes"""
1029 stats = updaterepo(repo, node, True) 1042 stats = updaterepo(repo, node, True)
1030 repo.vfs.unlinkpath('graftstate', ignoremissing=True) 1043 repo.vfs.unlinkpath(b'graftstate', ignoremissing=True)
1031 if show_stats: 1044 if show_stats:
1032 _showstats(repo, stats, quietempty) 1045 _showstats(repo, stats, quietempty)
1033 return stats.unresolvedcount > 0 1046 return stats.unresolvedcount > 0
1034 1047
1035 1048
1069 * NO_CONFLICT: check that the update does not result in file merges 1082 * NO_CONFLICT: check that the update does not result in file merges
1070 1083
1071 This returns whether conflict is detected at updating or not. 1084 This returns whether conflict is detected at updating or not.
1072 """ 1085 """
1073 if updatecheck is None: 1086 if updatecheck is None:
1074 updatecheck = ui.config('commands', 'update.check') 1087 updatecheck = ui.config(b'commands', b'update.check')
1075 if updatecheck not in _VALID_UPDATECHECKS: 1088 if updatecheck not in _VALID_UPDATECHECKS:
1076 # If not configured, or invalid value configured 1089 # If not configured, or invalid value configured
1077 updatecheck = mergemod.UPDATECHECK_LINEAR 1090 updatecheck = mergemod.UPDATECHECK_LINEAR
1078 if updatecheck not in _VALID_UPDATECHECKS: 1091 if updatecheck not in _VALID_UPDATECHECKS:
1079 raise ValueError( 1092 raise ValueError(
1095 cmdutil.bailifchanged(repo, merge=False) 1108 cmdutil.bailifchanged(repo, merge=False)
1096 updatecheck = mergemod.UPDATECHECK_NONE 1109 updatecheck = mergemod.UPDATECHECK_NONE
1097 ret = _update(repo, checkout, updatecheck=updatecheck) 1110 ret = _update(repo, checkout, updatecheck=updatecheck)
1098 1111
1099 if not ret and movemarkfrom: 1112 if not ret and movemarkfrom:
1100 if movemarkfrom == repo['.'].node(): 1113 if movemarkfrom == repo[b'.'].node():
1101 pass # no-op update 1114 pass # no-op update
1102 elif bookmarks.update(repo, [movemarkfrom], repo['.'].node()): 1115 elif bookmarks.update(repo, [movemarkfrom], repo[b'.'].node()):
1103 b = ui.label(repo._activebookmark, 'bookmarks.active') 1116 b = ui.label(repo._activebookmark, b'bookmarks.active')
1104 ui.status(_("updating bookmark %s\n") % b) 1117 ui.status(_(b"updating bookmark %s\n") % b)
1105 else: 1118 else:
1106 # this can happen with a non-linear update 1119 # this can happen with a non-linear update
1107 b = ui.label(repo._activebookmark, 'bookmarks') 1120 b = ui.label(repo._activebookmark, b'bookmarks')
1108 ui.status(_("(leaving bookmark %s)\n") % b) 1121 ui.status(_(b"(leaving bookmark %s)\n") % b)
1109 bookmarks.deactivate(repo) 1122 bookmarks.deactivate(repo)
1110 elif brev in repo._bookmarks: 1123 elif brev in repo._bookmarks:
1111 if brev != repo._activebookmark: 1124 if brev != repo._activebookmark:
1112 b = ui.label(brev, 'bookmarks.active') 1125 b = ui.label(brev, b'bookmarks.active')
1113 ui.status(_("(activating bookmark %s)\n") % b) 1126 ui.status(_(b"(activating bookmark %s)\n") % b)
1114 bookmarks.activate(repo, brev) 1127 bookmarks.activate(repo, brev)
1115 elif brev: 1128 elif brev:
1116 if repo._activebookmark: 1129 if repo._activebookmark:
1117 b = ui.label(repo._activebookmark, 'bookmarks') 1130 b = ui.label(repo._activebookmark, b'bookmarks')
1118 ui.status(_("(leaving bookmark %s)\n") % b) 1131 ui.status(_(b"(leaving bookmark %s)\n") % b)
1119 bookmarks.deactivate(repo) 1132 bookmarks.deactivate(repo)
1120 1133
1121 if warndest: 1134 if warndest:
1122 destutil.statusotherdests(ui, repo) 1135 destutil.statusotherdests(ui, repo)
1123 1136
1148 ) 1161 )
1149 _showstats(repo, stats) 1162 _showstats(repo, stats)
1150 if stats.unresolvedcount: 1163 if stats.unresolvedcount:
1151 repo.ui.status( 1164 repo.ui.status(
1152 _( 1165 _(
1153 "use 'hg resolve' to retry unresolved file merges " 1166 b"use 'hg resolve' to retry unresolved file merges "
1154 "or 'hg merge --abort' to abandon\n" 1167 b"or 'hg merge --abort' to abandon\n"
1155 ) 1168 )
1156 ) 1169 )
1157 elif remind: 1170 elif remind:
1158 repo.ui.status(_("(branch merge, don't forget to commit)\n")) 1171 repo.ui.status(_(b"(branch merge, don't forget to commit)\n"))
1159 return stats.unresolvedcount > 0 1172 return stats.unresolvedcount > 0
1160 1173
1161 1174
1162 def abortmerge(ui, repo): 1175 def abortmerge(ui, repo):
1163 ms = mergemod.mergestate.read(repo) 1176 ms = mergemod.mergestate.read(repo)
1164 if ms.active(): 1177 if ms.active():
1165 # there were conflicts 1178 # there were conflicts
1166 node = ms.localctx.hex() 1179 node = ms.localctx.hex()
1167 else: 1180 else:
1168 # there were no conficts, mergestate was not stored 1181 # there were no conficts, mergestate was not stored
1169 node = repo['.'].hex() 1182 node = repo[b'.'].hex()
1170 1183
1171 repo.ui.status( 1184 repo.ui.status(
1172 _("aborting the merge, updating back to" " %s\n") % node[:12] 1185 _(b"aborting the merge, updating back to" b" %s\n") % node[:12]
1173 ) 1186 )
1174 stats = mergemod.update(repo, node, branchmerge=False, force=True) 1187 stats = mergemod.update(repo, node, branchmerge=False, force=True)
1175 _showstats(repo, stats) 1188 _showstats(repo, stats)
1176 return stats.unresolvedcount > 0 1189 return stats.unresolvedcount > 0
1177 1190
1183 Helper for incoming / gincoming. 1196 Helper for incoming / gincoming.
1184 displaychlist gets called with 1197 displaychlist gets called with
1185 (remoterepo, incomingchangesetlist, displayer) parameters, 1198 (remoterepo, incomingchangesetlist, displayer) parameters,
1186 and is supposed to contain only code that can't be unified. 1199 and is supposed to contain only code that can't be unified.
1187 """ 1200 """
1188 source, branches = parseurl(ui.expandpath(source), opts.get('branch')) 1201 source, branches = parseurl(ui.expandpath(source), opts.get(b'branch'))
1189 other = peer(repo, opts, source) 1202 other = peer(repo, opts, source)
1190 ui.status(_('comparing with %s\n') % util.hidepassword(source)) 1203 ui.status(_(b'comparing with %s\n') % util.hidepassword(source))
1191 revs, checkout = addbranchrevs(repo, other, branches, opts.get('rev')) 1204 revs, checkout = addbranchrevs(repo, other, branches, opts.get(b'rev'))
1192 1205
1193 if revs: 1206 if revs:
1194 revs = [other.lookup(rev) for rev in revs] 1207 revs = [other.lookup(rev) for rev in revs]
1195 other, chlist, cleanupfn = bundlerepo.getremotechanges( 1208 other, chlist, cleanupfn = bundlerepo.getremotechanges(
1196 ui, repo, other, revs, opts["bundle"], opts["force"] 1209 ui, repo, other, revs, opts[b"bundle"], opts[b"force"]
1197 ) 1210 )
1198 try: 1211 try:
1199 if not chlist: 1212 if not chlist:
1200 ui.status(_("no changes found\n")) 1213 ui.status(_(b"no changes found\n"))
1201 return subreporecurse() 1214 return subreporecurse()
1202 ui.pager('incoming') 1215 ui.pager(b'incoming')
1203 displayer = logcmdutil.changesetdisplayer( 1216 displayer = logcmdutil.changesetdisplayer(
1204 ui, other, opts, buffered=buffered 1217 ui, other, opts, buffered=buffered
1205 ) 1218 )
1206 displaychlist(other, chlist, displayer) 1219 displaychlist(other, chlist, displayer)
1207 displayer.close() 1220 displayer.close()
1212 1225
1213 1226
1214 def incoming(ui, repo, source, opts): 1227 def incoming(ui, repo, source, opts):
1215 def subreporecurse(): 1228 def subreporecurse():
1216 ret = 1 1229 ret = 1
1217 if opts.get('subrepos'): 1230 if opts.get(b'subrepos'):
1218 ctx = repo[None] 1231 ctx = repo[None]
1219 for subpath in sorted(ctx.substate): 1232 for subpath in sorted(ctx.substate):
1220 sub = ctx.sub(subpath) 1233 sub = ctx.sub(subpath)
1221 ret = min(ret, sub.incoming(ui, source, opts)) 1234 ret = min(ret, sub.incoming(ui, source, opts))
1222 return ret 1235 return ret
1223 1236
1224 def display(other, chlist, displayer): 1237 def display(other, chlist, displayer):
1225 limit = logcmdutil.getlimit(opts) 1238 limit = logcmdutil.getlimit(opts)
1226 if opts.get('newest_first'): 1239 if opts.get(b'newest_first'):
1227 chlist.reverse() 1240 chlist.reverse()
1228 count = 0 1241 count = 0
1229 for n in chlist: 1242 for n in chlist:
1230 if limit is not None and count >= limit: 1243 if limit is not None and count >= limit:
1231 break 1244 break
1232 parents = [p for p in other.changelog.parents(n) if p != nullid] 1245 parents = [p for p in other.changelog.parents(n) if p != nullid]
1233 if opts.get('no_merges') and len(parents) == 2: 1246 if opts.get(b'no_merges') and len(parents) == 2:
1234 continue 1247 continue
1235 count += 1 1248 count += 1
1236 displayer.show(other[n]) 1249 displayer.show(other[n])
1237 1250
1238 return _incoming(display, subreporecurse, ui, repo, source, opts) 1251 return _incoming(display, subreporecurse, ui, repo, source, opts)
1239 1252
1240 1253
1241 def _outgoing(ui, repo, dest, opts): 1254 def _outgoing(ui, repo, dest, opts):
1242 path = ui.paths.getpath(dest, default=('default-push', 'default')) 1255 path = ui.paths.getpath(dest, default=(b'default-push', b'default'))
1243 if not path: 1256 if not path:
1244 raise error.Abort( 1257 raise error.Abort(
1245 _('default repository not configured!'), 1258 _(b'default repository not configured!'),
1246 hint=_("see 'hg help config.paths'"), 1259 hint=_(b"see 'hg help config.paths'"),
1247 ) 1260 )
1248 dest = path.pushloc or path.loc 1261 dest = path.pushloc or path.loc
1249 branches = path.branch, opts.get('branch') or [] 1262 branches = path.branch, opts.get(b'branch') or []
1250 1263
1251 ui.status(_('comparing with %s\n') % util.hidepassword(dest)) 1264 ui.status(_(b'comparing with %s\n') % util.hidepassword(dest))
1252 revs, checkout = addbranchrevs(repo, repo, branches, opts.get('rev')) 1265 revs, checkout = addbranchrevs(repo, repo, branches, opts.get(b'rev'))
1253 if revs: 1266 if revs:
1254 revs = [repo[rev].node() for rev in scmutil.revrange(repo, revs)] 1267 revs = [repo[rev].node() for rev in scmutil.revrange(repo, revs)]
1255 1268
1256 other = peer(repo, opts, dest) 1269 other = peer(repo, opts, dest)
1257 outgoing = discovery.findcommonoutgoing( 1270 outgoing = discovery.findcommonoutgoing(
1258 repo, other, revs, force=opts.get('force') 1271 repo, other, revs, force=opts.get(b'force')
1259 ) 1272 )
1260 o = outgoing.missing 1273 o = outgoing.missing
1261 if not o: 1274 if not o:
1262 scmutil.nochangesfound(repo.ui, repo, outgoing.excluded) 1275 scmutil.nochangesfound(repo.ui, repo, outgoing.excluded)
1263 return o, other 1276 return o, other
1264 1277
1265 1278
1266 def outgoing(ui, repo, dest, opts): 1279 def outgoing(ui, repo, dest, opts):
1267 def recurse(): 1280 def recurse():
1268 ret = 1 1281 ret = 1
1269 if opts.get('subrepos'): 1282 if opts.get(b'subrepos'):
1270 ctx = repo[None] 1283 ctx = repo[None]
1271 for subpath in sorted(ctx.substate): 1284 for subpath in sorted(ctx.substate):
1272 sub = ctx.sub(subpath) 1285 sub = ctx.sub(subpath)
1273 ret = min(ret, sub.outgoing(ui, dest, opts)) 1286 ret = min(ret, sub.outgoing(ui, dest, opts))
1274 return ret 1287 return ret
1277 o, other = _outgoing(ui, repo, dest, opts) 1290 o, other = _outgoing(ui, repo, dest, opts)
1278 if not o: 1291 if not o:
1279 cmdutil.outgoinghooks(ui, repo, other, opts, o) 1292 cmdutil.outgoinghooks(ui, repo, other, opts, o)
1280 return recurse() 1293 return recurse()
1281 1294
1282 if opts.get('newest_first'): 1295 if opts.get(b'newest_first'):
1283 o.reverse() 1296 o.reverse()
1284 ui.pager('outgoing') 1297 ui.pager(b'outgoing')
1285 displayer = logcmdutil.changesetdisplayer(ui, repo, opts) 1298 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
1286 count = 0 1299 count = 0
1287 for n in o: 1300 for n in o:
1288 if limit is not None and count >= limit: 1301 if limit is not None and count >= limit:
1289 break 1302 break
1290 parents = [p for p in repo.changelog.parents(n) if p != nullid] 1303 parents = [p for p in repo.changelog.parents(n) if p != nullid]
1291 if opts.get('no_merges') and len(parents) == 2: 1304 if opts.get(b'no_merges') and len(parents) == 2:
1292 continue 1305 continue
1293 count += 1 1306 count += 1
1294 displayer.show(repo[n]) 1307 displayer.show(repo[n])
1295 displayer.close() 1308 displayer.close()
1296 cmdutil.outgoinghooks(ui, repo, other, opts, o) 1309 cmdutil.outgoinghooks(ui, repo, other, opts, o)
1306 # since they can't be pushed/pulled, and --hidden can be used if they are a 1319 # since they can't be pushed/pulled, and --hidden can be used if they are a
1307 # concern. 1320 # concern.
1308 1321
1309 # pathto() is needed for -R case 1322 # pathto() is needed for -R case
1310 revs = repo.revs( 1323 revs = repo.revs(
1311 "filelog(%s)", util.pathto(repo.root, repo.getcwd(), '.hgsubstate') 1324 b"filelog(%s)", util.pathto(repo.root, repo.getcwd(), b'.hgsubstate')
1312 ) 1325 )
1313 1326
1314 if revs: 1327 if revs:
1315 repo.ui.status(_('checking subrepo links\n')) 1328 repo.ui.status(_(b'checking subrepo links\n'))
1316 for rev in revs: 1329 for rev in revs:
1317 ctx = repo[rev] 1330 ctx = repo[rev]
1318 try: 1331 try:
1319 for subpath in ctx.substate: 1332 for subpath in ctx.substate:
1320 try: 1333 try:
1321 ret = ( 1334 ret = (
1322 ctx.sub(subpath, allowcreate=False).verify() or ret 1335 ctx.sub(subpath, allowcreate=False).verify() or ret
1323 ) 1336 )
1324 except error.RepoError as e: 1337 except error.RepoError as e:
1325 repo.ui.warn('%d: %s\n' % (rev, e)) 1338 repo.ui.warn(b'%d: %s\n' % (rev, e))
1326 except Exception: 1339 except Exception:
1327 repo.ui.warn( 1340 repo.ui.warn(
1328 _('.hgsubstate is corrupt in revision %s\n') 1341 _(b'.hgsubstate is corrupt in revision %s\n')
1329 % node.short(ctx.node()) 1342 % node.short(ctx.node())
1330 ) 1343 )
1331 1344
1332 return ret 1345 return ret
1333 1346
1334 1347
1335 def remoteui(src, opts): 1348 def remoteui(src, opts):
1336 'build a remote ui from ui or repo and opts' 1349 b'build a remote ui from ui or repo and opts'
1337 if util.safehasattr(src, 'baseui'): # looks like a repository 1350 if util.safehasattr(src, b'baseui'): # looks like a repository
1338 dst = src.baseui.copy() # drop repo-specific config 1351 dst = src.baseui.copy() # drop repo-specific config
1339 src = src.ui # copy target options from repo 1352 src = src.ui # copy target options from repo
1340 else: # assume it's a global ui object 1353 else: # assume it's a global ui object
1341 dst = src.copy() # keep all global options 1354 dst = src.copy() # keep all global options
1342 1355
1343 # copy ssh-specific options 1356 # copy ssh-specific options
1344 for o in 'ssh', 'remotecmd': 1357 for o in b'ssh', b'remotecmd':
1345 v = opts.get(o) or src.config('ui', o) 1358 v = opts.get(o) or src.config(b'ui', o)
1346 if v: 1359 if v:
1347 dst.setconfig("ui", o, v, 'copied') 1360 dst.setconfig(b"ui", o, v, b'copied')
1348 1361
1349 # copy bundle-specific options 1362 # copy bundle-specific options
1350 r = src.config('bundle', 'mainreporoot') 1363 r = src.config(b'bundle', b'mainreporoot')
1351 if r: 1364 if r:
1352 dst.setconfig('bundle', 'mainreporoot', r, 'copied') 1365 dst.setconfig(b'bundle', b'mainreporoot', r, b'copied')
1353 1366
1354 # copy selected local settings to the remote ui 1367 # copy selected local settings to the remote ui
1355 for sect in ('auth', 'hostfingerprints', 'hostsecurity', 'http_proxy'): 1368 for sect in (b'auth', b'hostfingerprints', b'hostsecurity', b'http_proxy'):
1356 for key, val in src.configitems(sect): 1369 for key, val in src.configitems(sect):
1357 dst.setconfig(sect, key, val, 'copied') 1370 dst.setconfig(sect, key, val, b'copied')
1358 v = src.config('web', 'cacerts') 1371 v = src.config(b'web', b'cacerts')
1359 if v: 1372 if v:
1360 dst.setconfig('web', 'cacerts', util.expandpath(v), 'copied') 1373 dst.setconfig(b'web', b'cacerts', util.expandpath(v), b'copied')
1361 1374
1362 return dst 1375 return dst
1363 1376
1364 1377
1365 # Files of interest 1378 # Files of interest
1366 # Used to check if the repository has changed looking at mtime and size of 1379 # Used to check if the repository has changed looking at mtime and size of
1367 # these files. 1380 # these files.
1368 foi = [ 1381 foi = [
1369 ('spath', '00changelog.i'), 1382 (b'spath', b'00changelog.i'),
1370 ('spath', 'phaseroots'), # ! phase can change content at the same size 1383 (b'spath', b'phaseroots'), # ! phase can change content at the same size
1371 ('spath', 'obsstore'), 1384 (b'spath', b'obsstore'),
1372 ('path', 'bookmarks'), # ! bookmark can change content at the same size 1385 (b'path', b'bookmarks'), # ! bookmark can change content at the same size
1373 ] 1386 ]
1374 1387
1375 1388
1376 class cachedlocalrepo(object): 1389 class cachedlocalrepo(object):
1377 """Holds a localrepository that can be cached and reused.""" 1390 """Holds a localrepository that can be cached and reused."""