Mercurial > public > mercurial-scm > hg
comparison mercurial/changegroup.py @ 20933:d3775db748a0
localrepo: move the addchangegroup method in changegroup module
This is a gratuitous code move aimed at reducing the localrepo bloatness.
The method had few callers, not enough to be kept in local repo.
author | Pierre-Yves David <pierre-yves.david@fb.com> |
---|---|
date | Tue, 01 Apr 2014 15:27:53 -0700 |
parents | 0ac83e4e4f7c |
children | 3737e653dcbe |
comparison
equal
deleted
inserted
replaced
20932:0ac83e4e4f7c | 20933:d3775db748a0 |
---|---|
3 # Copyright 2006 Matt Mackall <mpm@selenic.com> | 3 # Copyright 2006 Matt Mackall <mpm@selenic.com> |
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 import weakref | |
8 from i18n import _ | 9 from i18n import _ |
9 from node import nullrev, nullid, hex | 10 from node import nullrev, nullid, hex, short |
10 import mdiff, util, dagutil | 11 import mdiff, util, dagutil |
11 import struct, os, bz2, zlib, tempfile | 12 import struct, os, bz2, zlib, tempfile |
12 import discovery, error | 13 import discovery, error, phases, branchmap |
13 | 14 |
14 _BUNDLE10_DELTA_HEADER = "20s20s20s20s" | 15 _BUNDLE10_DELTA_HEADER = "20s20s20s20s" |
15 | 16 |
16 def readexactly(stream, n): | 17 def readexactly(stream, n): |
17 '''read n bytes from stream.read and abort if less was available''' | 18 '''read n bytes from stream.read and abort if less was available''' |
552 raise util.Abort( | 553 raise util.Abort( |
553 _('missing file data for %s:%s - run hg verify') % | 554 _('missing file data for %s:%s - run hg verify') % |
554 (f, hex(n))) | 555 (f, hex(n))) |
555 | 556 |
556 return revisions, files | 557 return revisions, files |
558 | |
559 def addchangegroup(repo, source, srctype, url, emptyok=False): | |
560 """Add the changegroup returned by source.read() to this repo. | |
561 srctype is a string like 'push', 'pull', or 'unbundle'. url is | |
562 the URL of the repo where this changegroup is coming from. | |
563 | |
564 Return an integer summarizing the change to this repo: | |
565 - nothing changed or no source: 0 | |
566 - more heads than before: 1+added heads (2..n) | |
567 - fewer heads than before: -1-removed heads (-2..-n) | |
568 - number of heads stays the same: 1 | |
569 """ | |
570 repo = repo.unfiltered() | |
571 def csmap(x): | |
572 repo.ui.debug("add changeset %s\n" % short(x)) | |
573 return len(cl) | |
574 | |
575 def revmap(x): | |
576 return cl.rev(x) | |
577 | |
578 if not source: | |
579 return 0 | |
580 | |
581 repo.hook('prechangegroup', throw=True, source=srctype, url=url) | |
582 | |
583 changesets = files = revisions = 0 | |
584 efiles = set() | |
585 | |
586 # write changelog data to temp files so concurrent readers will not see | |
587 # inconsistent view | |
588 cl = repo.changelog | |
589 cl.delayupdate() | |
590 oldheads = cl.heads() | |
591 | |
592 tr = repo.transaction("\n".join([srctype, util.hidepassword(url)])) | |
593 try: | |
594 trp = weakref.proxy(tr) | |
595 # pull off the changeset group | |
596 repo.ui.status(_("adding changesets\n")) | |
597 clstart = len(cl) | |
598 class prog(object): | |
599 step = _('changesets') | |
600 count = 1 | |
601 ui = repo.ui | |
602 total = None | |
603 def __call__(repo): | |
604 repo.ui.progress(repo.step, repo.count, unit=_('chunks'), | |
605 total=repo.total) | |
606 repo.count += 1 | |
607 pr = prog() | |
608 source.callback = pr | |
609 | |
610 source.changelogheader() | |
611 srccontent = cl.addgroup(source, csmap, trp) | |
612 if not (srccontent or emptyok): | |
613 raise util.Abort(_("received changelog group is empty")) | |
614 clend = len(cl) | |
615 changesets = clend - clstart | |
616 for c in xrange(clstart, clend): | |
617 efiles.update(repo[c].files()) | |
618 efiles = len(efiles) | |
619 repo.ui.progress(_('changesets'), None) | |
620 | |
621 # pull off the manifest group | |
622 repo.ui.status(_("adding manifests\n")) | |
623 pr.step = _('manifests') | |
624 pr.count = 1 | |
625 pr.total = changesets # manifests <= changesets | |
626 # no need to check for empty manifest group here: | |
627 # if the result of the merge of 1 and 2 is the same in 3 and 4, | |
628 # no new manifest will be created and the manifest group will | |
629 # be empty during the pull | |
630 source.manifestheader() | |
631 repo.manifest.addgroup(source, revmap, trp) | |
632 repo.ui.progress(_('manifests'), None) | |
633 | |
634 needfiles = {} | |
635 if repo.ui.configbool('server', 'validate', default=False): | |
636 # validate incoming csets have their manifests | |
637 for cset in xrange(clstart, clend): | |
638 mfest = repo.changelog.read(repo.changelog.node(cset))[0] | |
639 mfest = repo.manifest.readdelta(mfest) | |
640 # store file nodes we must see | |
641 for f, n in mfest.iteritems(): | |
642 needfiles.setdefault(f, set()).add(n) | |
643 | |
644 # process the files | |
645 repo.ui.status(_("adding file changes\n")) | |
646 pr.step = _('files') | |
647 pr.count = 1 | |
648 pr.total = efiles | |
649 source.callback = None | |
650 | |
651 newrevs, newfiles = addchangegroupfiles(repo, source, revmap, trp, pr, | |
652 needfiles) | |
653 revisions += newrevs | |
654 files += newfiles | |
655 | |
656 dh = 0 | |
657 if oldheads: | |
658 heads = cl.heads() | |
659 dh = len(heads) - len(oldheads) | |
660 for h in heads: | |
661 if h not in oldheads and repo[h].closesbranch(): | |
662 dh -= 1 | |
663 htext = "" | |
664 if dh: | |
665 htext = _(" (%+d heads)") % dh | |
666 | |
667 repo.ui.status(_("added %d changesets" | |
668 " with %d changes to %d files%s\n") | |
669 % (changesets, revisions, files, htext)) | |
670 repo.invalidatevolatilesets() | |
671 | |
672 if changesets > 0: | |
673 p = lambda: cl.writepending() and repo.root or "" | |
674 repo.hook('pretxnchangegroup', throw=True, | |
675 node=hex(cl.node(clstart)), source=srctype, | |
676 url=url, pending=p) | |
677 | |
678 added = [cl.node(r) for r in xrange(clstart, clend)] | |
679 publishing = repo.ui.configbool('phases', 'publish', True) | |
680 if srctype == 'push': | |
681 # Old servers can not push the boundary themselves. | |
682 # New servers won't push the boundary if changeset already | |
683 # exists locally as secret | |
684 # | |
685 # We should not use added here but the list of all change in | |
686 # the bundle | |
687 if publishing: | |
688 phases.advanceboundary(repo, phases.public, srccontent) | |
689 else: | |
690 phases.advanceboundary(repo, phases.draft, srccontent) | |
691 phases.retractboundary(repo, phases.draft, added) | |
692 elif srctype != 'strip': | |
693 # publishing only alter behavior during push | |
694 # | |
695 # strip should not touch boundary at all | |
696 phases.retractboundary(repo, phases.draft, added) | |
697 | |
698 # make changelog see real files again | |
699 cl.finalize(trp) | |
700 | |
701 tr.close() | |
702 | |
703 if changesets > 0: | |
704 if srctype != 'strip': | |
705 # During strip, branchcache is invalid but coming call to | |
706 # `destroyed` will repair it. | |
707 # In other case we can safely update cache on disk. | |
708 branchmap.updatecache(repo.filtered('served')) | |
709 def runhooks(): | |
710 # These hooks run when the lock releases, not when the | |
711 # transaction closes. So it's possible for the changelog | |
712 # to have changed since we last saw it. | |
713 if clstart >= len(repo): | |
714 return | |
715 | |
716 # forcefully update the on-disk branch cache | |
717 repo.ui.debug("updating the branch cache\n") | |
718 repo.hook("changegroup", node=hex(cl.node(clstart)), | |
719 source=srctype, url=url) | |
720 | |
721 for n in added: | |
722 repo.hook("incoming", node=hex(n), source=srctype, | |
723 url=url) | |
724 | |
725 newheads = [h for h in repo.heads() if h not in oldheads] | |
726 repo.ui.log("incoming", | |
727 "%s incoming changes - new heads: %s\n", | |
728 len(added), | |
729 ', '.join([hex(c[:6]) for c in newheads])) | |
730 repo._afterlock(runhooks) | |
731 | |
732 finally: | |
733 tr.release() | |
734 # never return 0 here: | |
735 if dh < 0: | |
736 return dh - 1 | |
737 else: | |
738 return dh + 1 |