##// END OF EJS Templates
hg.clone: set 'stream' depending on whether --pull was requested or not...
Siddharth Agarwal -
r23545:68c43479 default
parent child Browse files
Show More
@@ -1,667 +1,673 b''
1 1 # hg.py - repository classes for mercurial
2 2 #
3 3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 4 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
5 5 #
6 6 # This software may be used and distributed according to the terms of the
7 7 # GNU General Public License version 2 or any later version.
8 8
9 9 from i18n import _
10 10 from lock import release
11 11 from node import nullid
12 12
13 13 import localrepo, bundlerepo, unionrepo, httppeer, sshpeer, statichttprepo
14 14 import bookmarks, lock, util, extensions, error, node, scmutil, phases, url
15 15 import cmdutil, discovery, repoview, exchange
16 16 import ui as uimod
17 17 import merge as mergemod
18 18 import verify as verifymod
19 19 import errno, os, shutil
20 20
21 21 def _local(path):
22 22 path = util.expandpath(util.urllocalpath(path))
23 23 return (os.path.isfile(path) and bundlerepo or localrepo)
24 24
25 25 def addbranchrevs(lrepo, other, branches, revs):
26 26 peer = other.peer() # a courtesy to callers using a localrepo for other
27 27 hashbranch, branches = branches
28 28 if not hashbranch and not branches:
29 29 x = revs or None
30 30 if util.safehasattr(revs, 'first'):
31 31 y = revs.first()
32 32 elif revs:
33 33 y = revs[0]
34 34 else:
35 35 y = None
36 36 return x, y
37 37 revs = revs and list(revs) or []
38 38 if not peer.capable('branchmap'):
39 39 if branches:
40 40 raise util.Abort(_("remote branch lookup not supported"))
41 41 revs.append(hashbranch)
42 42 return revs, revs[0]
43 43 branchmap = peer.branchmap()
44 44
45 45 def primary(branch):
46 46 if branch == '.':
47 47 if not lrepo:
48 48 raise util.Abort(_("dirstate branch not accessible"))
49 49 branch = lrepo.dirstate.branch()
50 50 if branch in branchmap:
51 51 revs.extend(node.hex(r) for r in reversed(branchmap[branch]))
52 52 return True
53 53 else:
54 54 return False
55 55
56 56 for branch in branches:
57 57 if not primary(branch):
58 58 raise error.RepoLookupError(_("unknown branch '%s'") % branch)
59 59 if hashbranch:
60 60 if not primary(hashbranch):
61 61 revs.append(hashbranch)
62 62 return revs, revs[0]
63 63
64 64 def parseurl(path, branches=None):
65 65 '''parse url#branch, returning (url, (branch, branches))'''
66 66
67 67 u = util.url(path)
68 68 branch = None
69 69 if u.fragment:
70 70 branch = u.fragment
71 71 u.fragment = None
72 72 return str(u), (branch, branches or [])
73 73
74 74 schemes = {
75 75 'bundle': bundlerepo,
76 76 'union': unionrepo,
77 77 'file': _local,
78 78 'http': httppeer,
79 79 'https': httppeer,
80 80 'ssh': sshpeer,
81 81 'static-http': statichttprepo,
82 82 }
83 83
84 84 def _peerlookup(path):
85 85 u = util.url(path)
86 86 scheme = u.scheme or 'file'
87 87 thing = schemes.get(scheme) or schemes['file']
88 88 try:
89 89 return thing(path)
90 90 except TypeError:
91 91 return thing
92 92
93 93 def islocal(repo):
94 94 '''return true if repo (or path pointing to repo) is local'''
95 95 if isinstance(repo, str):
96 96 try:
97 97 return _peerlookup(repo).islocal(repo)
98 98 except AttributeError:
99 99 return False
100 100 return repo.local()
101 101
102 102 def openpath(ui, path):
103 103 '''open path with open if local, url.open if remote'''
104 104 pathurl = util.url(path, parsequery=False, parsefragment=False)
105 105 if pathurl.islocal():
106 106 return util.posixfile(pathurl.localpath(), 'rb')
107 107 else:
108 108 return url.open(ui, path)
109 109
110 110 # a list of (ui, repo) functions called for wire peer initialization
111 111 wirepeersetupfuncs = []
112 112
113 113 def _peerorrepo(ui, path, create=False):
114 114 """return a repository object for the specified path"""
115 115 obj = _peerlookup(path).instance(ui, path, create)
116 116 ui = getattr(obj, "ui", ui)
117 117 for name, module in extensions.extensions(ui):
118 118 hook = getattr(module, 'reposetup', None)
119 119 if hook:
120 120 hook(ui, obj)
121 121 if not obj.local():
122 122 for f in wirepeersetupfuncs:
123 123 f(ui, obj)
124 124 return obj
125 125
126 126 def repository(ui, path='', create=False):
127 127 """return a repository object for the specified path"""
128 128 peer = _peerorrepo(ui, path, create)
129 129 repo = peer.local()
130 130 if not repo:
131 131 raise util.Abort(_("repository '%s' is not local") %
132 132 (path or peer.url()))
133 133 return repo.filtered('visible')
134 134
135 135 def peer(uiorrepo, opts, path, create=False):
136 136 '''return a repository peer for the specified path'''
137 137 rui = remoteui(uiorrepo, opts)
138 138 return _peerorrepo(rui, path, create).peer()
139 139
140 140 def defaultdest(source):
141 141 '''return default destination of clone if none is given
142 142
143 143 >>> defaultdest('foo')
144 144 'foo'
145 145 >>> defaultdest('/foo/bar')
146 146 'bar'
147 147 >>> defaultdest('/')
148 148 ''
149 149 >>> defaultdest('')
150 150 ''
151 151 >>> defaultdest('http://example.org/')
152 152 ''
153 153 >>> defaultdest('http://example.org/foo/')
154 154 'foo'
155 155 '''
156 156 path = util.url(source).path
157 157 if not path:
158 158 return ''
159 159 return os.path.basename(os.path.normpath(path))
160 160
161 161 def share(ui, source, dest=None, update=True):
162 162 '''create a shared repository'''
163 163
164 164 if not islocal(source):
165 165 raise util.Abort(_('can only share local repositories'))
166 166
167 167 if not dest:
168 168 dest = defaultdest(source)
169 169 else:
170 170 dest = ui.expandpath(dest)
171 171
172 172 if isinstance(source, str):
173 173 origsource = ui.expandpath(source)
174 174 source, branches = parseurl(origsource)
175 175 srcrepo = repository(ui, source)
176 176 rev, checkout = addbranchrevs(srcrepo, srcrepo, branches, None)
177 177 else:
178 178 srcrepo = source.local()
179 179 origsource = source = srcrepo.url()
180 180 checkout = None
181 181
182 182 sharedpath = srcrepo.sharedpath # if our source is already sharing
183 183
184 184 destwvfs = scmutil.vfs(dest, realpath=True)
185 185 destvfs = scmutil.vfs(os.path.join(destwvfs.base, '.hg'), realpath=True)
186 186
187 187 if destvfs.lexists():
188 188 raise util.Abort(_('destination already exists'))
189 189
190 190 if not destwvfs.isdir():
191 191 destwvfs.mkdir()
192 192 destvfs.makedir()
193 193
194 194 requirements = ''
195 195 try:
196 196 requirements = srcrepo.opener.read('requires')
197 197 except IOError, inst:
198 198 if inst.errno != errno.ENOENT:
199 199 raise
200 200
201 201 requirements += 'shared\n'
202 202 destvfs.write('requires', requirements)
203 203 destvfs.write('sharedpath', sharedpath)
204 204
205 205 r = repository(ui, destwvfs.base)
206 206
207 207 default = srcrepo.ui.config('paths', 'default')
208 208 if default:
209 209 fp = r.opener("hgrc", "w", text=True)
210 210 fp.write("[paths]\n")
211 211 fp.write("default = %s\n" % default)
212 212 fp.close()
213 213
214 214 if update:
215 215 r.ui.status(_("updating working directory\n"))
216 216 if update is not True:
217 217 checkout = update
218 218 for test in (checkout, 'default', 'tip'):
219 219 if test is None:
220 220 continue
221 221 try:
222 222 uprev = r.lookup(test)
223 223 break
224 224 except error.RepoLookupError:
225 225 continue
226 226 _update(r, uprev)
227 227
228 228 def copystore(ui, srcrepo, destpath):
229 229 '''copy files from store of srcrepo in destpath
230 230
231 231 returns destlock
232 232 '''
233 233 destlock = None
234 234 try:
235 235 hardlink = None
236 236 num = 0
237 237 srcpublishing = srcrepo.ui.configbool('phases', 'publish', True)
238 238 srcvfs = scmutil.vfs(srcrepo.sharedpath)
239 239 dstvfs = scmutil.vfs(destpath)
240 240 for f in srcrepo.store.copylist():
241 241 if srcpublishing and f.endswith('phaseroots'):
242 242 continue
243 243 dstbase = os.path.dirname(f)
244 244 if dstbase and not dstvfs.exists(dstbase):
245 245 dstvfs.mkdir(dstbase)
246 246 if srcvfs.exists(f):
247 247 if f.endswith('data'):
248 248 # 'dstbase' may be empty (e.g. revlog format 0)
249 249 lockfile = os.path.join(dstbase, "lock")
250 250 # lock to avoid premature writing to the target
251 251 destlock = lock.lock(dstvfs, lockfile)
252 252 hardlink, n = util.copyfiles(srcvfs.join(f), dstvfs.join(f),
253 253 hardlink)
254 254 num += n
255 255 if hardlink:
256 256 ui.debug("linked %d files\n" % num)
257 257 else:
258 258 ui.debug("copied %d files\n" % num)
259 259 return destlock
260 260 except: # re-raises
261 261 release(destlock)
262 262 raise
263 263
264 264 def clone(ui, peeropts, source, dest=None, pull=False, rev=None,
265 265 update=True, stream=False, branch=None):
266 266 """Make a copy of an existing repository.
267 267
268 268 Create a copy of an existing repository in a new directory. The
269 269 source and destination are URLs, as passed to the repository
270 270 function. Returns a pair of repository peers, the source and
271 271 newly created destination.
272 272
273 273 The location of the source is added to the new repository's
274 274 .hg/hgrc file, as the default to be used for future pulls and
275 275 pushes.
276 276
277 277 If an exception is raised, the partly cloned/updated destination
278 278 repository will be deleted.
279 279
280 280 Arguments:
281 281
282 282 source: repository object or URL
283 283
284 284 dest: URL of destination repository to create (defaults to base
285 285 name of source repository)
286 286
287 pull: always pull from source repository, even in local case
287 pull: always pull from source repository, even in local case or if the
288 server prefers streaming
288 289
289 290 stream: stream raw data uncompressed from repository (fast over
290 291 LAN, slow over WAN)
291 292
292 293 rev: revision to clone up to (implies pull=True)
293 294
294 295 update: update working directory after clone completes, if
295 296 destination is local repository (True means update to default rev,
296 297 anything else is treated as a revision)
297 298
298 299 branch: branches to clone
299 300 """
300 301
301 302 if isinstance(source, str):
302 303 origsource = ui.expandpath(source)
303 304 source, branch = parseurl(origsource, branch)
304 305 srcpeer = peer(ui, peeropts, source)
305 306 else:
306 307 srcpeer = source.peer() # in case we were called with a localrepo
307 308 branch = (None, branch or [])
308 309 origsource = source = srcpeer.url()
309 310 rev, checkout = addbranchrevs(srcpeer, srcpeer, branch, rev)
310 311
311 312 if dest is None:
312 313 dest = defaultdest(source)
313 314 if dest:
314 315 ui.status(_("destination directory: %s\n") % dest)
315 316 else:
316 317 dest = ui.expandpath(dest)
317 318
318 319 dest = util.urllocalpath(dest)
319 320 source = util.urllocalpath(source)
320 321
321 322 if not dest:
322 323 raise util.Abort(_("empty destination path is not valid"))
323 324
324 325 destvfs = scmutil.vfs(dest, expandpath=True)
325 326 if destvfs.lexists():
326 327 if not destvfs.isdir():
327 328 raise util.Abort(_("destination '%s' already exists") % dest)
328 329 elif destvfs.listdir():
329 330 raise util.Abort(_("destination '%s' is not empty") % dest)
330 331
331 332 srclock = destlock = cleandir = None
332 333 srcrepo = srcpeer.local()
333 334 try:
334 335 abspath = origsource
335 336 if islocal(origsource):
336 337 abspath = os.path.abspath(util.urllocalpath(origsource))
337 338
338 339 if islocal(dest):
339 340 cleandir = dest
340 341
341 342 copy = False
342 343 if (srcrepo and srcrepo.cancopy() and islocal(dest)
343 344 and not phases.hassecret(srcrepo)):
344 345 copy = not pull and not rev
345 346
346 347 if copy:
347 348 try:
348 349 # we use a lock here because if we race with commit, we
349 350 # can end up with extra data in the cloned revlogs that's
350 351 # not pointed to by changesets, thus causing verify to
351 352 # fail
352 353 srclock = srcrepo.lock(wait=False)
353 354 except error.LockError:
354 355 copy = False
355 356
356 357 if copy:
357 358 srcrepo.hook('preoutgoing', throw=True, source='clone')
358 359 hgdir = os.path.realpath(os.path.join(dest, ".hg"))
359 360 if not os.path.exists(dest):
360 361 os.mkdir(dest)
361 362 else:
362 363 # only clean up directories we create ourselves
363 364 cleandir = hgdir
364 365 try:
365 366 destpath = hgdir
366 367 util.makedir(destpath, notindexed=True)
367 368 except OSError, inst:
368 369 if inst.errno == errno.EEXIST:
369 370 cleandir = None
370 371 raise util.Abort(_("destination '%s' already exists")
371 372 % dest)
372 373 raise
373 374
374 375 destlock = copystore(ui, srcrepo, destpath)
375 376 # copy bookmarks over
376 377 srcbookmarks = srcrepo.join('bookmarks')
377 378 dstbookmarks = os.path.join(destpath, 'bookmarks')
378 379 if os.path.exists(srcbookmarks):
379 380 util.copyfile(srcbookmarks, dstbookmarks)
380 381
381 382 # Recomputing branch cache might be slow on big repos,
382 383 # so just copy it
383 384 def copybranchcache(fname):
384 385 srcbranchcache = srcrepo.join('cache/%s' % fname)
385 386 dstbranchcache = os.path.join(dstcachedir, fname)
386 387 if os.path.exists(srcbranchcache):
387 388 if not os.path.exists(dstcachedir):
388 389 os.mkdir(dstcachedir)
389 390 util.copyfile(srcbranchcache, dstbranchcache)
390 391
391 392 dstcachedir = os.path.join(destpath, 'cache')
392 393 # In local clones we're copying all nodes, not just served
393 394 # ones. Therefore copy all branch caches over.
394 395 copybranchcache('branch2')
395 396 for cachename in repoview.filtertable:
396 397 copybranchcache('branch2-%s' % cachename)
397 398
398 399 # we need to re-init the repo after manually copying the data
399 400 # into it
400 401 destpeer = peer(srcrepo, peeropts, dest)
401 402 srcrepo.hook('outgoing', source='clone',
402 403 node=node.hex(node.nullid))
403 404 else:
404 405 try:
405 406 destpeer = peer(srcrepo or ui, peeropts, dest, create=True)
406 407 # only pass ui when no srcrepo
407 408 except OSError, inst:
408 409 if inst.errno == errno.EEXIST:
409 410 cleandir = None
410 411 raise util.Abort(_("destination '%s' already exists")
411 412 % dest)
412 413 raise
413 414
414 415 revs = None
415 416 if rev:
416 417 if not srcpeer.capable('lookup'):
417 418 raise util.Abort(_("src repository does not support "
418 419 "revision lookup and so doesn't "
419 420 "support clone by revision"))
420 421 revs = [srcpeer.lookup(r) for r in rev]
421 422 checkout = revs[0]
422 423 if destpeer.local():
424 if not stream:
425 if pull:
426 stream = False
427 else:
428 stream = None
423 429 destpeer.local().clone(srcpeer, heads=revs, stream=stream)
424 430 elif srcrepo:
425 431 exchange.push(srcrepo, destpeer, revs=revs,
426 432 bookmarks=srcrepo._bookmarks.keys())
427 433 else:
428 434 raise util.Abort(_("clone from remote to remote not supported"))
429 435
430 436 cleandir = None
431 437
432 438 destrepo = destpeer.local()
433 439 if destrepo:
434 440 template = uimod.samplehgrcs['cloned']
435 441 fp = destrepo.opener("hgrc", "w", text=True)
436 442 u = util.url(abspath)
437 443 u.passwd = None
438 444 defaulturl = str(u)
439 445 fp.write(template % defaulturl)
440 446 fp.close()
441 447
442 448 destrepo.ui.setconfig('paths', 'default', defaulturl, 'clone')
443 449
444 450 if update:
445 451 if update is not True:
446 452 checkout = srcpeer.lookup(update)
447 453 uprev = None
448 454 status = None
449 455 if checkout is not None:
450 456 try:
451 457 uprev = destrepo.lookup(checkout)
452 458 except error.RepoLookupError:
453 459 pass
454 460 if uprev is None:
455 461 try:
456 462 uprev = destrepo._bookmarks['@']
457 463 update = '@'
458 464 bn = destrepo[uprev].branch()
459 465 if bn == 'default':
460 466 status = _("updating to bookmark @\n")
461 467 else:
462 468 status = (_("updating to bookmark @ on branch %s\n")
463 469 % bn)
464 470 except KeyError:
465 471 try:
466 472 uprev = destrepo.branchtip('default')
467 473 except error.RepoLookupError:
468 474 uprev = destrepo.lookup('tip')
469 475 if not status:
470 476 bn = destrepo[uprev].branch()
471 477 status = _("updating to branch %s\n") % bn
472 478 destrepo.ui.status(status)
473 479 _update(destrepo, uprev)
474 480 if update in destrepo._bookmarks:
475 481 bookmarks.setcurrent(destrepo, update)
476 482 finally:
477 483 release(srclock, destlock)
478 484 if cleandir is not None:
479 485 shutil.rmtree(cleandir, True)
480 486 if srcpeer is not None:
481 487 srcpeer.close()
482 488 return srcpeer, destpeer
483 489
484 490 def _showstats(repo, stats):
485 491 repo.ui.status(_("%d files updated, %d files merged, "
486 492 "%d files removed, %d files unresolved\n") % stats)
487 493
488 494 def updaterepo(repo, node, overwrite):
489 495 """Update the working directory to node.
490 496
491 497 When overwrite is set, changes are clobbered, merged else
492 498
493 499 returns stats (see pydoc mercurial.merge.applyupdates)"""
494 500 return mergemod.update(repo, node, False, overwrite, None,
495 501 labels=['working copy', 'destination'])
496 502
497 503 def update(repo, node):
498 504 """update the working directory to node, merging linear changes"""
499 505 stats = updaterepo(repo, node, False)
500 506 _showstats(repo, stats)
501 507 if stats[3]:
502 508 repo.ui.status(_("use 'hg resolve' to retry unresolved file merges\n"))
503 509 return stats[3] > 0
504 510
505 511 # naming conflict in clone()
506 512 _update = update
507 513
508 514 def clean(repo, node, show_stats=True):
509 515 """forcibly switch the working directory to node, clobbering changes"""
510 516 stats = updaterepo(repo, node, True)
511 517 util.unlinkpath(repo.join('graftstate'), ignoremissing=True)
512 518 if show_stats:
513 519 _showstats(repo, stats)
514 520 return stats[3] > 0
515 521
516 522 def merge(repo, node, force=None, remind=True):
517 523 """Branch merge with node, resolving changes. Return true if any
518 524 unresolved conflicts."""
519 525 stats = mergemod.update(repo, node, True, force, False)
520 526 _showstats(repo, stats)
521 527 if stats[3]:
522 528 repo.ui.status(_("use 'hg resolve' to retry unresolved file merges "
523 529 "or 'hg update -C .' to abandon\n"))
524 530 elif remind:
525 531 repo.ui.status(_("(branch merge, don't forget to commit)\n"))
526 532 return stats[3] > 0
527 533
528 534 def _incoming(displaychlist, subreporecurse, ui, repo, source,
529 535 opts, buffered=False):
530 536 """
531 537 Helper for incoming / gincoming.
532 538 displaychlist gets called with
533 539 (remoterepo, incomingchangesetlist, displayer) parameters,
534 540 and is supposed to contain only code that can't be unified.
535 541 """
536 542 source, branches = parseurl(ui.expandpath(source), opts.get('branch'))
537 543 other = peer(repo, opts, source)
538 544 ui.status(_('comparing with %s\n') % util.hidepassword(source))
539 545 revs, checkout = addbranchrevs(repo, other, branches, opts.get('rev'))
540 546
541 547 if revs:
542 548 revs = [other.lookup(rev) for rev in revs]
543 549 other, chlist, cleanupfn = bundlerepo.getremotechanges(ui, repo, other,
544 550 revs, opts["bundle"], opts["force"])
545 551 try:
546 552 if not chlist:
547 553 ui.status(_("no changes found\n"))
548 554 return subreporecurse()
549 555
550 556 displayer = cmdutil.show_changeset(ui, other, opts, buffered)
551 557 displaychlist(other, chlist, displayer)
552 558 displayer.close()
553 559 finally:
554 560 cleanupfn()
555 561 subreporecurse()
556 562 return 0 # exit code is zero since we found incoming changes
557 563
558 564 def incoming(ui, repo, source, opts):
559 565 def subreporecurse():
560 566 ret = 1
561 567 if opts.get('subrepos'):
562 568 ctx = repo[None]
563 569 for subpath in sorted(ctx.substate):
564 570 sub = ctx.sub(subpath)
565 571 ret = min(ret, sub.incoming(ui, source, opts))
566 572 return ret
567 573
568 574 def display(other, chlist, displayer):
569 575 limit = cmdutil.loglimit(opts)
570 576 if opts.get('newest_first'):
571 577 chlist.reverse()
572 578 count = 0
573 579 for n in chlist:
574 580 if limit is not None and count >= limit:
575 581 break
576 582 parents = [p for p in other.changelog.parents(n) if p != nullid]
577 583 if opts.get('no_merges') and len(parents) == 2:
578 584 continue
579 585 count += 1
580 586 displayer.show(other[n])
581 587 return _incoming(display, subreporecurse, ui, repo, source, opts)
582 588
583 589 def _outgoing(ui, repo, dest, opts):
584 590 dest = ui.expandpath(dest or 'default-push', dest or 'default')
585 591 dest, branches = parseurl(dest, opts.get('branch'))
586 592 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
587 593 revs, checkout = addbranchrevs(repo, repo, branches, opts.get('rev'))
588 594 if revs:
589 595 revs = [repo.lookup(rev) for rev in scmutil.revrange(repo, revs)]
590 596
591 597 other = peer(repo, opts, dest)
592 598 outgoing = discovery.findcommonoutgoing(repo.unfiltered(), other, revs,
593 599 force=opts.get('force'))
594 600 o = outgoing.missing
595 601 if not o:
596 602 scmutil.nochangesfound(repo.ui, repo, outgoing.excluded)
597 603 return o, other
598 604
599 605 def outgoing(ui, repo, dest, opts):
600 606 def recurse():
601 607 ret = 1
602 608 if opts.get('subrepos'):
603 609 ctx = repo[None]
604 610 for subpath in sorted(ctx.substate):
605 611 sub = ctx.sub(subpath)
606 612 ret = min(ret, sub.outgoing(ui, dest, opts))
607 613 return ret
608 614
609 615 limit = cmdutil.loglimit(opts)
610 616 o, other = _outgoing(ui, repo, dest, opts)
611 617 if not o:
612 618 cmdutil.outgoinghooks(ui, repo, other, opts, o)
613 619 return recurse()
614 620
615 621 if opts.get('newest_first'):
616 622 o.reverse()
617 623 displayer = cmdutil.show_changeset(ui, repo, opts)
618 624 count = 0
619 625 for n in o:
620 626 if limit is not None and count >= limit:
621 627 break
622 628 parents = [p for p in repo.changelog.parents(n) if p != nullid]
623 629 if opts.get('no_merges') and len(parents) == 2:
624 630 continue
625 631 count += 1
626 632 displayer.show(repo[n])
627 633 displayer.close()
628 634 cmdutil.outgoinghooks(ui, repo, other, opts, o)
629 635 recurse()
630 636 return 0 # exit code is zero since we found outgoing changes
631 637
632 638 def revert(repo, node, choose):
633 639 """revert changes to revision in node without updating dirstate"""
634 640 return mergemod.update(repo, node, False, True, choose)[3] > 0
635 641
636 642 def verify(repo):
637 643 """verify the consistency of a repository"""
638 644 return verifymod.verify(repo)
639 645
640 646 def remoteui(src, opts):
641 647 'build a remote ui from ui or repo and opts'
642 648 if util.safehasattr(src, 'baseui'): # looks like a repository
643 649 dst = src.baseui.copy() # drop repo-specific config
644 650 src = src.ui # copy target options from repo
645 651 else: # assume it's a global ui object
646 652 dst = src.copy() # keep all global options
647 653
648 654 # copy ssh-specific options
649 655 for o in 'ssh', 'remotecmd':
650 656 v = opts.get(o) or src.config('ui', o)
651 657 if v:
652 658 dst.setconfig("ui", o, v, 'copied')
653 659
654 660 # copy bundle-specific options
655 661 r = src.config('bundle', 'mainreporoot')
656 662 if r:
657 663 dst.setconfig('bundle', 'mainreporoot', r, 'copied')
658 664
659 665 # copy selected local settings to the remote ui
660 666 for sect in ('auth', 'hostfingerprints', 'http_proxy'):
661 667 for key, val in src.configitems(sect):
662 668 dst.setconfig(sect, key, val, 'copied')
663 669 v = src.config('web', 'cacerts')
664 670 if v:
665 671 dst.setconfig('web', 'cacerts', util.expandpath(v), 'copied')
666 672
667 673 return dst
General Comments 0
You need to be logged in to leave comments. Login now