##// END OF EJS Templates
hg: move peerschemes back to schemes...
Matt Mackall -
r14606:6e631c24 default
parent child Browse files
Show More
@@ -1,98 +1,98 b''
1 1 # Copyright 2009, Alexander Solovyov <piranha@piranha.org.ua>
2 2 #
3 3 # This software may be used and distributed according to the terms of the
4 4 # GNU General Public License version 2 or any later version.
5 5
6 6 """extend schemes with shortcuts to repository swarms
7 7
8 8 This extension allows you to specify shortcuts for parent URLs with a
9 9 lot of repositories to act like a scheme, for example::
10 10
11 11 [schemes]
12 12 py = http://code.python.org/hg/
13 13
14 14 After that you can use it like::
15 15
16 16 hg clone py://trunk/
17 17
18 18 Additionally there is support for some more complex schemas, for
19 19 example used by Google Code::
20 20
21 21 [schemes]
22 22 gcode = http://{1}.googlecode.com/hg/
23 23
24 24 The syntax is taken from Mercurial templates, and you have unlimited
25 25 number of variables, starting with ``{1}`` and continuing with
26 26 ``{2}``, ``{3}`` and so on. This variables will receive parts of URL
27 27 supplied, split by ``/``. Anything not specified as ``{part}`` will be
28 28 just appended to an URL.
29 29
30 30 For convenience, the extension adds these schemes by default::
31 31
32 32 [schemes]
33 33 py = http://hg.python.org/
34 34 bb = https://bitbucket.org/
35 35 bb+ssh = ssh://hg@bitbucket.org/
36 36 gcode = https://{1}.googlecode.com/hg/
37 37 kiln = https://{1}.kilnhg.com/Repo/
38 38
39 39 You can override a predefined scheme by defining a new scheme with the
40 40 same name.
41 41 """
42 42
43 43 import os, re
44 44 from mercurial import extensions, hg, templater, util
45 45 from mercurial.i18n import _
46 46
47 47
48 48 class ShortRepository(object):
49 49 def __init__(self, url, scheme, templater):
50 50 self.scheme = scheme
51 51 self.templater = templater
52 52 self.url = url
53 53 try:
54 54 self.parts = max(map(int, re.findall(r'\{(\d+)\}', self.url)))
55 55 except ValueError:
56 56 self.parts = 0
57 57
58 58 def __repr__(self):
59 59 return '<ShortRepository: %s>' % self.scheme
60 60
61 61 def instance(self, ui, url, create):
62 62 # Should this use urlmod.url(), or is manual parsing better?
63 63 url = url.split('://', 1)[1]
64 64 parts = url.split('/', self.parts)
65 65 if len(parts) > self.parts:
66 66 tail = parts[-1]
67 67 parts = parts[:-1]
68 68 else:
69 69 tail = ''
70 70 context = dict((str(i + 1), v) for i, v in enumerate(parts))
71 71 url = ''.join(self.templater.process(self.url, context)) + tail
72 72 return hg._peerlookup(url).instance(ui, url, create)
73 73
74 74 def hasdriveletter(orig, path):
75 75 for scheme in schemes:
76 76 if path.startswith(scheme + ':'):
77 77 return False
78 78 return orig(path)
79 79
80 80 schemes = {
81 81 'py': 'http://hg.python.org/',
82 82 'bb': 'https://bitbucket.org/',
83 83 'bb+ssh': 'ssh://hg@bitbucket.org/',
84 84 'gcode': 'https://{1}.googlecode.com/hg/',
85 85 'kiln': 'https://{1}.kilnhg.com/Repo/'
86 86 }
87 87
88 88 def extsetup(ui):
89 89 schemes.update(dict(ui.configitems('schemes')))
90 90 t = templater.engine(lambda x: x)
91 91 for scheme, url in schemes.items():
92 92 if (os.name == 'nt' and len(scheme) == 1 and scheme.isalpha()
93 93 and os.path.exists('%s:\\' % scheme)):
94 94 raise util.Abort(_('custom scheme %s:// conflicts with drive '
95 95 'letter %s:\\\n') % (scheme, scheme.upper()))
96 hg.peerschemes[scheme] = ShortRepository(url, scheme, t)
96 hg.schemes[scheme] = ShortRepository(url, scheme, t)
97 97
98 98 extensions.wrapfunction(util, 'hasdriveletter', hasdriveletter)
@@ -1,564 +1,564 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, httprepo, sshrepo, statichttprepo, bookmarks
13 13 import lock, util, extensions, error, node
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.localpath(path))
21 21 return (os.path.isfile(path) and bundlerepo or localrepo)
22 22
23 23 def addbranchrevs(lrepo, repo, branches, revs):
24 24 hashbranch, branches = branches
25 25 if not hashbranch and not branches:
26 26 return revs or None, revs and revs[0] or None
27 27 revs = revs and list(revs) or []
28 28 if not repo.capable('branchmap'):
29 29 if branches:
30 30 raise util.Abort(_("remote branch lookup not supported"))
31 31 revs.append(hashbranch)
32 32 return revs, revs[0]
33 33 branchmap = repo.branchmap()
34 34
35 35 def primary(branch):
36 36 if branch == '.':
37 37 if not lrepo or not lrepo.local():
38 38 raise util.Abort(_("dirstate branch not accessible"))
39 39 branch = lrepo.dirstate.branch()
40 40 if branch in branchmap:
41 41 revs.extend(node.hex(r) for r in reversed(branchmap[branch]))
42 42 return True
43 43 else:
44 44 return False
45 45
46 46 for branch in branches:
47 47 if not primary(branch):
48 48 raise error.RepoLookupError(_("unknown branch '%s'") % branch)
49 49 if hashbranch:
50 50 if not primary(hashbranch):
51 51 revs.append(hashbranch)
52 52 return revs, revs[0]
53 53
54 54 def parseurl(path, branches=None):
55 55 '''parse url#branch, returning (url, (branch, branches))'''
56 56
57 57 u = util.url(path)
58 58 branch = None
59 59 if u.fragment:
60 60 branch = u.fragment
61 61 u.fragment = None
62 62 return str(u), (branch, branches or [])
63 63
64 peerschemes = {
64 schemes = {
65 65 'bundle': bundlerepo,
66 66 'file': _local,
67 67 'http': httprepo,
68 68 'https': httprepo,
69 69 'ssh': sshrepo,
70 70 'static-http': statichttprepo,
71 71 }
72 72
73 73 def _peerlookup(path):
74 74 u = util.url(path)
75 75 scheme = u.scheme or 'file'
76 thing = peerschemes.get(scheme) or peerschemes['file']
76 thing = schemes.get(scheme) or schemes['file']
77 77 try:
78 78 return thing(path)
79 79 except TypeError:
80 80 return thing
81 81
82 82 def islocal(repo):
83 83 '''return true if repo or path is local'''
84 84 if isinstance(repo, str):
85 85 try:
86 86 return _peerlookup(repo).islocal(repo)
87 87 except AttributeError:
88 88 return False
89 89 return repo.local()
90 90
91 91 def repository(ui, path='', create=False):
92 92 """return a repository object for the specified path"""
93 93 repo = _peerlookup(path).instance(ui, path, create)
94 94 ui = getattr(repo, "ui", ui)
95 95 for name, module in extensions.extensions():
96 96 hook = getattr(module, 'reposetup', None)
97 97 if hook:
98 98 hook(ui, repo)
99 99 return repo
100 100
101 101 def peer(ui, opts, path, create=False):
102 102 '''return a repository peer for the specified path'''
103 103 rui = remoteui(ui, opts)
104 104 return _peerlookup(path).instance(rui, path, create)
105 105
106 106 def defaultdest(source):
107 107 '''return default destination of clone if none is given'''
108 108 return os.path.basename(os.path.normpath(source))
109 109
110 110 def share(ui, source, dest=None, update=True):
111 111 '''create a shared repository'''
112 112
113 113 if not islocal(source):
114 114 raise util.Abort(_('can only share local repositories'))
115 115
116 116 if not dest:
117 117 dest = defaultdest(source)
118 118 else:
119 119 dest = ui.expandpath(dest)
120 120
121 121 if isinstance(source, str):
122 122 origsource = ui.expandpath(source)
123 123 source, branches = parseurl(origsource)
124 124 srcrepo = repository(ui, source)
125 125 rev, checkout = addbranchrevs(srcrepo, srcrepo, branches, None)
126 126 else:
127 127 srcrepo = source
128 128 origsource = source = srcrepo.url()
129 129 checkout = None
130 130
131 131 sharedpath = srcrepo.sharedpath # if our source is already sharing
132 132
133 133 root = os.path.realpath(dest)
134 134 roothg = os.path.join(root, '.hg')
135 135
136 136 if os.path.exists(roothg):
137 137 raise util.Abort(_('destination already exists'))
138 138
139 139 if not os.path.isdir(root):
140 140 os.mkdir(root)
141 141 util.makedir(roothg, notindexed=True)
142 142
143 143 requirements = ''
144 144 try:
145 145 requirements = srcrepo.opener.read('requires')
146 146 except IOError, inst:
147 147 if inst.errno != errno.ENOENT:
148 148 raise
149 149
150 150 requirements += 'shared\n'
151 151 util.writefile(os.path.join(roothg, 'requires'), requirements)
152 152 util.writefile(os.path.join(roothg, 'sharedpath'), sharedpath)
153 153
154 154 r = repository(ui, root)
155 155
156 156 default = srcrepo.ui.config('paths', 'default')
157 157 if default:
158 158 fp = r.opener("hgrc", "w", text=True)
159 159 fp.write("[paths]\n")
160 160 fp.write("default = %s\n" % default)
161 161 fp.close()
162 162
163 163 if update:
164 164 r.ui.status(_("updating working directory\n"))
165 165 if update is not True:
166 166 checkout = update
167 167 for test in (checkout, 'default', 'tip'):
168 168 if test is None:
169 169 continue
170 170 try:
171 171 uprev = r.lookup(test)
172 172 break
173 173 except error.RepoLookupError:
174 174 continue
175 175 _update(r, uprev)
176 176
177 177 def clone(ui, opts, source, dest=None, pull=False, rev=None, update=True,
178 178 stream=False, branch=None):
179 179 """Make a copy of an existing repository.
180 180
181 181 Create a copy of an existing repository in a new directory. The
182 182 source and destination are URLs, as passed to the repository
183 183 function. Returns a pair of repository objects, the source and
184 184 newly created destination.
185 185
186 186 The location of the source is added to the new repository's
187 187 .hg/hgrc file, as the default to be used for future pulls and
188 188 pushes.
189 189
190 190 If an exception is raised, the partly cloned/updated destination
191 191 repository will be deleted.
192 192
193 193 Arguments:
194 194
195 195 source: repository object or URL
196 196
197 197 dest: URL of destination repository to create (defaults to base
198 198 name of source repository)
199 199
200 200 pull: always pull from source repository, even in local case
201 201
202 202 stream: stream raw data uncompressed from repository (fast over
203 203 LAN, slow over WAN)
204 204
205 205 rev: revision to clone up to (implies pull=True)
206 206
207 207 update: update working directory after clone completes, if
208 208 destination is local repository (True means update to default rev,
209 209 anything else is treated as a revision)
210 210
211 211 branch: branches to clone
212 212 """
213 213
214 214 if isinstance(source, str):
215 215 origsource = ui.expandpath(source)
216 216 source, branch = parseurl(origsource, branch)
217 217 srcrepo = repository(remoteui(ui, opts), source)
218 218 else:
219 219 srcrepo = source
220 220 branch = (None, branch or [])
221 221 origsource = source = srcrepo.url()
222 222 rev, checkout = addbranchrevs(srcrepo, srcrepo, branch, rev)
223 223
224 224 if dest is None:
225 225 dest = defaultdest(source)
226 226 ui.status(_("destination directory: %s\n") % dest)
227 227 else:
228 228 dest = ui.expandpath(dest)
229 229
230 230 dest = util.localpath(dest)
231 231 source = util.localpath(source)
232 232
233 233 if os.path.exists(dest):
234 234 if not os.path.isdir(dest):
235 235 raise util.Abort(_("destination '%s' already exists") % dest)
236 236 elif os.listdir(dest):
237 237 raise util.Abort(_("destination '%s' is not empty") % dest)
238 238
239 239 class DirCleanup(object):
240 240 def __init__(self, dir_):
241 241 self.rmtree = shutil.rmtree
242 242 self.dir_ = dir_
243 243 def close(self):
244 244 self.dir_ = None
245 245 def cleanup(self):
246 246 if self.dir_:
247 247 self.rmtree(self.dir_, True)
248 248
249 249 srclock = destlock = dircleanup = None
250 250 try:
251 251 abspath = origsource
252 252 if islocal(origsource):
253 253 abspath = os.path.abspath(util.localpath(origsource))
254 254
255 255 if islocal(dest):
256 256 dircleanup = DirCleanup(dest)
257 257
258 258 copy = False
259 259 if srcrepo.cancopy() and islocal(dest):
260 260 copy = not pull and not rev
261 261
262 262 if copy:
263 263 try:
264 264 # we use a lock here because if we race with commit, we
265 265 # can end up with extra data in the cloned revlogs that's
266 266 # not pointed to by changesets, thus causing verify to
267 267 # fail
268 268 srclock = srcrepo.lock(wait=False)
269 269 except error.LockError:
270 270 copy = False
271 271
272 272 if copy:
273 273 srcrepo.hook('preoutgoing', throw=True, source='clone')
274 274 hgdir = os.path.realpath(os.path.join(dest, ".hg"))
275 275 if not os.path.exists(dest):
276 276 os.mkdir(dest)
277 277 else:
278 278 # only clean up directories we create ourselves
279 279 dircleanup.dir_ = hgdir
280 280 try:
281 281 destpath = hgdir
282 282 util.makedir(destpath, notindexed=True)
283 283 except OSError, inst:
284 284 if inst.errno == errno.EEXIST:
285 285 dircleanup.close()
286 286 raise util.Abort(_("destination '%s' already exists")
287 287 % dest)
288 288 raise
289 289
290 290 hardlink = None
291 291 num = 0
292 292 for f in srcrepo.store.copylist():
293 293 src = os.path.join(srcrepo.sharedpath, f)
294 294 dst = os.path.join(destpath, f)
295 295 dstbase = os.path.dirname(dst)
296 296 if dstbase and not os.path.exists(dstbase):
297 297 os.mkdir(dstbase)
298 298 if os.path.exists(src):
299 299 if dst.endswith('data'):
300 300 # lock to avoid premature writing to the target
301 301 destlock = lock.lock(os.path.join(dstbase, "lock"))
302 302 hardlink, n = util.copyfiles(src, dst, hardlink)
303 303 num += n
304 304 if hardlink:
305 305 ui.debug("linked %d files\n" % num)
306 306 else:
307 307 ui.debug("copied %d files\n" % num)
308 308
309 309 # we need to re-init the repo after manually copying the data
310 310 # into it
311 311 destrepo = repository(remoteui(ui, opts), dest)
312 312 srcrepo.hook('outgoing', source='clone',
313 313 node=node.hex(node.nullid))
314 314 else:
315 315 try:
316 316 destrepo = repository(remoteui(ui, opts), dest, create=True)
317 317 except OSError, inst:
318 318 if inst.errno == errno.EEXIST:
319 319 dircleanup.close()
320 320 raise util.Abort(_("destination '%s' already exists")
321 321 % dest)
322 322 raise
323 323
324 324 revs = None
325 325 if rev:
326 326 if not srcrepo.capable('lookup'):
327 327 raise util.Abort(_("src repository does not support "
328 328 "revision lookup and so doesn't "
329 329 "support clone by revision"))
330 330 revs = [srcrepo.lookup(r) for r in rev]
331 331 checkout = revs[0]
332 332 if destrepo.local():
333 333 destrepo.clone(srcrepo, heads=revs, stream=stream)
334 334 elif srcrepo.local():
335 335 srcrepo.push(destrepo, revs=revs)
336 336 else:
337 337 raise util.Abort(_("clone from remote to remote not supported"))
338 338
339 339 if dircleanup:
340 340 dircleanup.close()
341 341
342 342 if destrepo.local():
343 343 fp = destrepo.opener("hgrc", "w", text=True)
344 344 fp.write("[paths]\n")
345 345 fp.write("default = %s\n" % abspath)
346 346 fp.close()
347 347
348 348 destrepo.ui.setconfig('paths', 'default', abspath)
349 349
350 350 if update:
351 351 if update is not True:
352 352 checkout = update
353 353 if srcrepo.local():
354 354 checkout = srcrepo.lookup(update)
355 355 for test in (checkout, 'default', 'tip'):
356 356 if test is None:
357 357 continue
358 358 try:
359 359 uprev = destrepo.lookup(test)
360 360 break
361 361 except error.RepoLookupError:
362 362 continue
363 363 bn = destrepo[uprev].branch()
364 364 destrepo.ui.status(_("updating to branch %s\n") % bn)
365 365 _update(destrepo, uprev)
366 366
367 367 # clone all bookmarks
368 368 if destrepo.local() and srcrepo.capable("pushkey"):
369 369 rb = srcrepo.listkeys('bookmarks')
370 370 for k, n in rb.iteritems():
371 371 try:
372 372 m = destrepo.lookup(n)
373 373 destrepo._bookmarks[k] = m
374 374 except error.RepoLookupError:
375 375 pass
376 376 if rb:
377 377 bookmarks.write(destrepo)
378 378 elif srcrepo.local() and destrepo.capable("pushkey"):
379 379 for k, n in srcrepo._bookmarks.iteritems():
380 380 destrepo.pushkey('bookmarks', k, '', hex(n))
381 381
382 382 return srcrepo, destrepo
383 383 finally:
384 384 release(srclock, destlock)
385 385 if dircleanup is not None:
386 386 dircleanup.cleanup()
387 387
388 388 def _showstats(repo, stats):
389 389 repo.ui.status(_("%d files updated, %d files merged, "
390 390 "%d files removed, %d files unresolved\n") % stats)
391 391
392 392 def update(repo, node):
393 393 """update the working directory to node, merging linear changes"""
394 394 stats = mergemod.update(repo, node, False, False, None)
395 395 _showstats(repo, stats)
396 396 if stats[3]:
397 397 repo.ui.status(_("use 'hg resolve' to retry unresolved file merges\n"))
398 398 return stats[3] > 0
399 399
400 400 # naming conflict in clone()
401 401 _update = update
402 402
403 403 def clean(repo, node, show_stats=True):
404 404 """forcibly switch the working directory to node, clobbering changes"""
405 405 stats = mergemod.update(repo, node, False, True, None)
406 406 if show_stats:
407 407 _showstats(repo, stats)
408 408 return stats[3] > 0
409 409
410 410 def merge(repo, node, force=None, remind=True):
411 411 """Branch merge with node, resolving changes. Return true if any
412 412 unresolved conflicts."""
413 413 stats = mergemod.update(repo, node, True, force, False)
414 414 _showstats(repo, stats)
415 415 if stats[3]:
416 416 repo.ui.status(_("use 'hg resolve' to retry unresolved file merges "
417 417 "or 'hg update -C .' to abandon\n"))
418 418 elif remind:
419 419 repo.ui.status(_("(branch merge, don't forget to commit)\n"))
420 420 return stats[3] > 0
421 421
422 422 def _incoming(displaychlist, subreporecurse, ui, repo, source,
423 423 opts, buffered=False):
424 424 """
425 425 Helper for incoming / gincoming.
426 426 displaychlist gets called with
427 427 (remoterepo, incomingchangesetlist, displayer) parameters,
428 428 and is supposed to contain only code that can't be unified.
429 429 """
430 430 source, branches = parseurl(ui.expandpath(source), opts.get('branch'))
431 431 other = peer(repo, opts, source)
432 432 ui.status(_('comparing with %s\n') % util.hidepassword(source))
433 433 revs, checkout = addbranchrevs(repo, other, branches, opts.get('rev'))
434 434
435 435 if revs:
436 436 revs = [other.lookup(rev) for rev in revs]
437 437 other, chlist, cleanupfn = bundlerepo.getremotechanges(ui, repo, other,
438 438 revs, opts["bundle"], opts["force"])
439 439 try:
440 440 if not chlist:
441 441 ui.status(_("no changes found\n"))
442 442 return subreporecurse()
443 443
444 444 displayer = cmdutil.show_changeset(ui, other, opts, buffered)
445 445
446 446 # XXX once graphlog extension makes it into core,
447 447 # should be replaced by a if graph/else
448 448 displaychlist(other, chlist, displayer)
449 449
450 450 displayer.close()
451 451 finally:
452 452 cleanupfn()
453 453 subreporecurse()
454 454 return 0 # exit code is zero since we found incoming changes
455 455
456 456 def incoming(ui, repo, source, opts):
457 457 def subreporecurse():
458 458 ret = 1
459 459 if opts.get('subrepos'):
460 460 ctx = repo[None]
461 461 for subpath in sorted(ctx.substate):
462 462 sub = ctx.sub(subpath)
463 463 ret = min(ret, sub.incoming(ui, source, opts))
464 464 return ret
465 465
466 466 def display(other, chlist, displayer):
467 467 limit = cmdutil.loglimit(opts)
468 468 if opts.get('newest_first'):
469 469 chlist.reverse()
470 470 count = 0
471 471 for n in chlist:
472 472 if limit is not None and count >= limit:
473 473 break
474 474 parents = [p for p in other.changelog.parents(n) if p != nullid]
475 475 if opts.get('no_merges') and len(parents) == 2:
476 476 continue
477 477 count += 1
478 478 displayer.show(other[n])
479 479 return _incoming(display, subreporecurse, ui, repo, source, opts)
480 480
481 481 def _outgoing(ui, repo, dest, opts):
482 482 dest = ui.expandpath(dest or 'default-push', dest or 'default')
483 483 dest, branches = parseurl(dest, opts.get('branch'))
484 484 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
485 485 revs, checkout = addbranchrevs(repo, repo, branches, opts.get('rev'))
486 486 if revs:
487 487 revs = [repo.lookup(rev) for rev in revs]
488 488
489 489 other = peer(repo, opts, dest)
490 490 common, outheads = discovery.findcommonoutgoing(repo, other, revs,
491 491 force=opts.get('force'))
492 492 o = repo.changelog.findmissing(common, outheads)
493 493 if not o:
494 494 ui.status(_("no changes found\n"))
495 495 return None
496 496 return o
497 497
498 498 def outgoing(ui, repo, dest, opts):
499 499 def recurse():
500 500 ret = 1
501 501 if opts.get('subrepos'):
502 502 ctx = repo[None]
503 503 for subpath in sorted(ctx.substate):
504 504 sub = ctx.sub(subpath)
505 505 ret = min(ret, sub.outgoing(ui, dest, opts))
506 506 return ret
507 507
508 508 limit = cmdutil.loglimit(opts)
509 509 o = _outgoing(ui, repo, dest, opts)
510 510 if o is None:
511 511 return recurse()
512 512
513 513 if opts.get('newest_first'):
514 514 o.reverse()
515 515 displayer = cmdutil.show_changeset(ui, repo, opts)
516 516 count = 0
517 517 for n in o:
518 518 if limit is not None and count >= limit:
519 519 break
520 520 parents = [p for p in repo.changelog.parents(n) if p != nullid]
521 521 if opts.get('no_merges') and len(parents) == 2:
522 522 continue
523 523 count += 1
524 524 displayer.show(repo[n])
525 525 displayer.close()
526 526 recurse()
527 527 return 0 # exit code is zero since we found outgoing changes
528 528
529 529 def revert(repo, node, choose):
530 530 """revert changes to revision in node without updating dirstate"""
531 531 return mergemod.update(repo, node, False, True, choose)[3] > 0
532 532
533 533 def verify(repo):
534 534 """verify the consistency of a repository"""
535 535 return verifymod.verify(repo)
536 536
537 537 def remoteui(src, opts):
538 538 'build a remote ui from ui or repo and opts'
539 539 if hasattr(src, 'baseui'): # looks like a repository
540 540 dst = src.baseui.copy() # drop repo-specific config
541 541 src = src.ui # copy target options from repo
542 542 else: # assume it's a global ui object
543 543 dst = src.copy() # keep all global options
544 544
545 545 # copy ssh-specific options
546 546 for o in 'ssh', 'remotecmd':
547 547 v = opts.get(o) or src.config('ui', o)
548 548 if v:
549 549 dst.setconfig("ui", o, v)
550 550
551 551 # copy bundle-specific options
552 552 r = src.config('bundle', 'mainreporoot')
553 553 if r:
554 554 dst.setconfig('bundle', 'mainreporoot', r)
555 555
556 556 # copy selected local settings to the remote ui
557 557 for sect in ('auth', 'hostfingerprints', 'http_proxy'):
558 558 for key, val in src.configitems(sect):
559 559 dst.setconfig(sect, key, val)
560 560 v = src.config('web', 'cacerts')
561 561 if v:
562 562 dst.setconfig('web', 'cacerts', util.expandpath(v))
563 563
564 564 return dst
General Comments 0
You need to be logged in to leave comments. Login now