comparison mercurial/exchange.py @ 20469:6b4c789d618d

exchange: extract pull function from localrepo The localrepo class if far too big. Push and pull logic are extracted and reworked to better fit with the fact we exchange more than bundle now. This changeset extract the pulh code. later changeset will slowly slice it into smaller brick. The localrepo.pull method is kept for now to limit impact on user code. But it will be ultimately removed, now that the public API is hold by peer.
author Pierre-Yves David <pierre-yves.david@logilab.fr>
date Thu, 30 Jan 2014 16:12:49 -0800
parents 7d0bbb6dd730
children b97a453b8c27
comparison
equal deleted inserted replaced
20468:7d0bbb6dd730 20469:6b4c789d618d
4 # 4 #
5 # This software may be used and distributed according to the terms of the 5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version. 6 # GNU General Public License version 2 or any later version.
7 7
8 from i18n import _ 8 from i18n import _
9 from node import hex 9 from node import hex, nullid
10 import errno 10 import errno
11 import util, scmutil, changegroup 11 import util, scmutil, changegroup
12 import discovery, phases, obsolete, bookmarks 12 import discovery, phases, obsolete, bookmarks
13 13
14 14
370 continue 370 continue
371 if remote.pushkey('bookmarks', b, dcid, scid): 371 if remote.pushkey('bookmarks', b, dcid, scid):
372 ui.status(_("updating bookmark %s\n") % b) 372 ui.status(_("updating bookmark %s\n") % b)
373 else: 373 else:
374 ui.warn(_('updating bookmark %s failed!\n') % b) 374 ui.warn(_('updating bookmark %s failed!\n') % b)
375
376
377 def pull(repo, remote, heads=None, force=False):
378 if remote.local():
379 missing = set(remote.requirements) - repo.supported
380 if missing:
381 msg = _("required features are not"
382 " supported in the destination:"
383 " %s") % (', '.join(sorted(missing)))
384 raise util.Abort(msg)
385
386 # don't open transaction for nothing or you break future useful
387 # rollback call
388 tr = None
389 trname = 'pull\n' + util.hidepassword(remote.url())
390 lock = repo.lock()
391 try:
392 tmp = discovery.findcommonincoming(repo.unfiltered(), remote,
393 heads=heads, force=force)
394 common, fetch, rheads = tmp
395 if not fetch:
396 repo.ui.status(_("no changes found\n"))
397 result = 0
398 else:
399 tr = repo.transaction(trname)
400 if heads is None and list(common) == [nullid]:
401 repo.ui.status(_("requesting all changes\n"))
402 elif heads is None and remote.capable('changegroupsubset'):
403 # issue1320, avoid a race if remote changed after discovery
404 heads = rheads
405
406 if remote.capable('getbundle'):
407 # TODO: get bundlecaps from remote
408 cg = remote.getbundle('pull', common=common,
409 heads=heads or rheads)
410 elif heads is None:
411 cg = remote.changegroup(fetch, 'pull')
412 elif not remote.capable('changegroupsubset'):
413 raise util.Abort(_("partial pull cannot be done because "
414 "other repository doesn't support "
415 "changegroupsubset."))
416 else:
417 cg = remote.changegroupsubset(fetch, heads, 'pull')
418 result = repo.addchangegroup(cg, 'pull', remote.url())
419
420 # compute target subset
421 if heads is None:
422 # We pulled every thing possible
423 # sync on everything common
424 subset = common + rheads
425 else:
426 # We pulled a specific subset
427 # sync on this subset
428 subset = heads
429
430 # Get remote phases data from remote
431 remotephases = remote.listkeys('phases')
432 publishing = bool(remotephases.get('publishing', False))
433 if remotephases and not publishing:
434 # remote is new and unpublishing
435 pheads, _dr = phases.analyzeremotephases(repo, subset,
436 remotephases)
437 phases.advanceboundary(repo, phases.public, pheads)
438 phases.advanceboundary(repo, phases.draft, subset)
439 else:
440 # Remote is old or publishing all common changesets
441 # should be seen as public
442 phases.advanceboundary(repo, phases.public, subset)
443
444 def gettransaction():
445 if tr is None:
446 return repo.transaction(trname)
447 return tr
448
449 obstr = obsolete.syncpull(repo, remote, gettransaction)
450 if obstr is not None:
451 tr = obstr
452
453 if tr is not None:
454 tr.close()
455 finally:
456 if tr is not None:
457 tr.release()
458 lock.release()
459
460 return result