Mercurial > hg > mercurial-crew-with-dirclash
comparison mercurial/hg.py @ 46:93e868fa0db8
Add changegroup support
author | mpm@selenic.com |
---|---|
date | Tue, 10 May 2005 00:40:49 -0800 |
parents | e825a68d7227 |
children | 9f64181ff9a9 |
comparison
equal
deleted
inserted
replaced
45:f2b2d5daec30 | 46:93e868fa0db8 |
---|---|
556 | 556 |
557 def remove(self, list): | 557 def remove(self, list): |
558 dl = self.opener("to-remove", "a") | 558 dl = self.opener("to-remove", "a") |
559 for f in list: | 559 for f in list: |
560 dl.write(f + "\n") | 560 dl.write(f + "\n") |
561 | |
562 def newer(self, node): | |
563 nodes = [] | |
564 for i in xrange(self.changelog.rev(node) + 1, self.changelog.count()): | |
565 nodes.append(self.changelog.node(i)) | |
566 | |
567 return nodes | |
568 | |
569 def changegroup(self, nodes): | |
570 # construct the link map | |
571 linkmap = {} | |
572 for n in nodes: | |
573 linkmap[self.changelog.rev(n)] = n | |
574 | |
575 # construct a list of all changed files | |
576 changed = {} | |
577 for n in nodes: | |
578 c = self.changelog.read(n) | |
579 for f in c[3]: | |
580 changed[f] = 1 | |
581 changed = changed.keys() | |
582 changed.sort() | |
583 | |
584 # the changegroup is changesets + manifests + all file revs | |
585 cg = [] | |
586 revs = [ self.changelog.rev(n) for n in nodes ] | |
587 | |
588 g = self.changelog.group(linkmap) | |
589 cg.append(g) | |
590 g = self.manifest.group(linkmap) | |
591 cg.append(g) | |
592 | |
593 for f in changed: | |
594 g = self.file(f).group(linkmap) | |
595 if not g: raise "couldn't find change to %s" % f | |
596 l = struct.pack(">l", len(f)) | |
597 cg += [l, f, g] | |
598 | |
599 return compress("".join(cg)) | |
600 | |
601 def addchangegroup(self, data): | |
602 data = decompress(data) | |
603 def getlen(data, pos): | |
604 return struct.unpack(">l", data[pos:pos + 4])[0] | |
605 | |
606 tr = self.transaction() | |
607 simple = True | |
608 | |
609 print "merging changesets" | |
610 # pull off the changeset group | |
611 l = getlen(data, 0) | |
612 csg = data[0:l] | |
613 pos = l | |
614 co = self.changelog.tip() | |
615 cn = self.changelog.addgroup(csg, lambda x: self.changelog.count(), tr) | |
616 | |
617 print "merging manifests" | |
618 # pull off the manifest group | |
619 l = getlen(data, pos) | |
620 mfg = data[pos: pos + l] | |
621 pos += l | |
622 mo = self.manifest.tip() | |
623 mn = self.manifest.addgroup(mfg, lambda x: self.changelog.rev(x), tr) | |
624 | |
625 # do we need a resolve? | |
626 if self.changelog.ancestor(co, cn) != co: | |
627 print "NEED RESOLVE" | |
628 simple = False | |
629 resolverev = self.changelog.count() | |
630 | |
631 # process the files | |
632 print "merging files" | |
633 new = {} | |
634 while pos < len(data): | |
635 l = getlen(data, pos) | |
636 pos += 4 | |
637 f = data[pos:pos + l] | |
638 pos += l | |
639 | |
640 l = getlen(data, pos) | |
641 fg = data[pos: pos + l] | |
642 pos += l | |
643 | |
644 fl = self.file(f) | |
645 o = fl.tip() | |
646 n = fl.addgroup(fg, lambda x: self.changelog.rev(x), tr) | |
647 if not simple: | |
648 new[fl] = fl.resolvedag(o, n, tr, resolverev) | |
649 | |
650 # For simple merges, we don't need to resolve manifests or changesets | |
651 if simple: | |
652 tr.close() | |
653 return | |
654 | |
655 # resolve the manifest to point to all the merged files | |
656 self.ui.status("resolving manifests\n") | |
657 ma = self.manifest.ancestor(mm, mo) | |
658 mmap = self.manifest.read(mm) # mine | |
659 omap = self.manifest.read(mo) # other | |
660 amap = self.manifest.read(ma) # ancestor | |
661 nmap = {} | |
662 | |
663 for f, mid in mmap.iteritems(): | |
664 if f in omap: | |
665 if mid != omap[f]: | |
666 nmap[f] = new.get(f, mid) # use merged version | |
667 else: | |
668 nmap[f] = new.get(f, mid) # they're the same | |
669 del omap[f] | |
670 elif f in amap: | |
671 if mid != amap[f]: | |
672 pass # we should prompt here | |
673 else: | |
674 pass # other deleted it | |
675 else: | |
676 nmap[f] = new.get(f, mid) # we created it | |
677 | |
678 del mmap | |
679 | |
680 for f, oid in omap.iteritems(): | |
681 if f in amap: | |
682 if oid != amap[f]: | |
683 pass # this is the nasty case, we should prompt | |
684 else: | |
685 pass # probably safe | |
686 else: | |
687 nmap[f] = new.get(f, oid) # remote created it | |
688 | |
689 del omap | |
690 del amap | |
691 | |
692 node = self.manifest.add(nmap, tr, resolverev, mm, mo) | |
693 | |
694 # Now all files and manifests are merged, we add the changed files | |
695 # and manifest id to the changelog | |
696 self.ui.status("committing merge changeset\n") | |
697 new = new.keys() | |
698 new.sort() | |
699 if co == cn: cn = -1 | |
700 | |
701 edittext = "\n"+"".join(["HG: changed %s\n" % f for f in new]) | |
702 edittext = self.ui.edit(edittext) | |
703 n = self.changelog.add(node, new, edittext, tr, co, cn) | |
704 | |
705 tr.close() | |
561 | 706 |
562 class ui: | 707 class ui: |
563 def __init__(self, verbose=False, debug=False): | 708 def __init__(self, verbose=False, debug=False): |
564 self.verbose = verbose | 709 self.verbose = verbose |
565 def write(self, *args): | 710 def write(self, *args): |