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