Mercurial > public > mercurial-scm > hg
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.""" |