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