##// END OF EJS Templates
Fix up a bunch of bugs in the new merge code...
mpm@selenic.com -
r65:d40cc5aa 0.4f default
parent child Browse files
Show More
@@ -282,7 +282,7 b' elif cmd == "debugindex":'
282 elif cmd == "merge":
282 elif cmd == "merge":
283 if args:
283 if args:
284 other = hg.repository(ui, args[0])
284 other = hg.repository(ui, args[0])
285 print "retrieving changegroup"
285 print "requesting changegroup"
286 cg = repo.getchangegroup(other)
286 cg = repo.getchangegroup(other)
287 repo.addchangegroup(cg)
287 repo.addchangegroup(cg)
288 else:
288 else:
@@ -613,23 +613,24 b' class localrepository:'
613
613
614 def getchangegroup(self, remote):
614 def getchangegroup(self, remote):
615 tip = remote.branches([])[0]
615 tip = remote.branches([])[0]
616 cl = self.changelog
616 m = self.changelog.nodemap
617 unknown = [tip]
617 unknown = [tip]
618 search = []
618 search = []
619 fetch = []
619 fetch = []
620
620
621 if tip[0] == self.changelog.tip():
621 if tip[0] in m:
622 return None
622 return None
623
623
624 while unknown:
624 while unknown:
625 n = unknown.pop(0)
625 n = unknown.pop(0)
626 if n == nullid: break
626 if n == nullid: break
627 if n[1] and cl.nodemap.has_key(n[1]): # do we know the base?
627 if n[1] and n[1] in m: # do we know the base?
628 search.append(n) # schedule branch range for scanning
628 search.append(n) # schedule branch range for scanning
629 else:
629 else:
630 for b in remote.branches([n[2], n[3]]):
630 for b in remote.branches([n[2], n[3]]):
631 if cl.nodemap.has_key(b[0]):
631 if b[0] in m:
632 fetch.append(n[1]) # earliest unknown
632 if n[1] not in fetch:
633 fetch.append(n[1]) # earliest unknown
633 else:
634 else:
634 unknown.append(b)
635 unknown.append(b)
635
636
@@ -639,13 +640,18 b' class localrepository:'
639 p = n[0]
640 p = n[0]
640 f = 1
641 f = 1
641 for i in l + [n[1]]:
642 for i in l + [n[1]]:
642 if self.changelog.nodemap.has_key(i):
643 if i in m:
643 if f <= 4:
644 if f <= 4:
644 fetch.append(p)
645 fetch.append(p)
645 else:
646 else:
646 search.append((p, i))
647 search.append((p, i))
648 break
647 p, f = i, f * 2
649 p, f = i, f * 2
648
650
651 for f in fetch:
652 if f in m:
653 raise "already have", hex(f[:4])
654
649 return remote.changegroup(fetch)
655 return remote.changegroup(fetch)
650
656
651 def changegroup(self, basenodes):
657 def changegroup(self, basenodes):
@@ -677,55 +683,63 b' class localrepository:'
677 l = struct.pack(">l", len(f))
683 l = struct.pack(">l", len(f))
678 yield "".join([l, f, g])
684 yield "".join([l, f, g])
679
685
680 def addchangegroup(self, data):
686 def addchangegroup(self, generator):
681 def getlen(data, pos):
687 class genread:
682 return struct.unpack(">l", data[pos:pos + 4])[0]
688 def __init__(self, generator):
689 self.g = generator
690 self.buf = ""
691 def read(self, l):
692 while l > len(self.buf):
693 try:
694 self.buf += self.g.next()
695 except StopIteration:
696 break
697 d, self.buf = self.buf[:l], self.buf[l:]
698 return d
699
700 if not generator: return
701 source = genread(generator)
683
702
684 if not data: return
703 def getchunk(add = 0):
685
704 d = source.read(4)
705 if not d: return ""
706 l = struct.unpack(">l", d)[0]
707 return source.read(l - 4 + add)
708
686 tr = self.transaction()
709 tr = self.transaction()
687 simple = True
710 simple = True
688
711
689 print "merging changesets"
712 print "merging changesets"
690 # pull off the changeset group
713 # pull off the changeset group
691 l = getlen(data, 0)
714 csg = getchunk()
692 csg = data[0:l]
693 pos = l
694 co = self.changelog.tip()
715 co = self.changelog.tip()
695 cn = self.changelog.addgroup(csg, lambda x: self.changelog.count(), tr)
716 cn = self.changelog.addgroup(csg, lambda x: self.changelog.count(), tr)
696
717
697 print "merging manifests"
718 print "merging manifests"
698 # pull off the manifest group
719 # pull off the manifest group
699 l = getlen(data, pos)
720 mfg = getchunk()
700 mfg = data[pos: pos + l]
701 pos += l
702 mo = self.manifest.tip()
721 mo = self.manifest.tip()
703 mn = self.manifest.addgroup(mfg, lambda x: self.changelog.rev(x), tr)
722 mm = self.manifest.addgroup(mfg, lambda x: self.changelog.rev(x), tr)
704
723
705 # do we need a resolve?
724 # do we need a resolve?
706 if self.changelog.ancestor(co, cn) != co:
725 if self.changelog.ancestor(co, cn) != co:
707 print "NEED RESOLVE"
708 simple = False
726 simple = False
709 resolverev = self.changelog.count()
727 resolverev = self.changelog.count()
710
728
711 # process the files
729 # process the files
712 print "merging files"
730 print "merging files"
713 new = {}
731 new = {}
714 while pos < len(data):
732 while 1:
715 l = getlen(data, pos)
733 f = getchunk(4)
716 pos += 4
734 if not f: break
717 f = data[pos:pos + l]
735 fg = getchunk()
718 pos += l
719
720 l = getlen(data, pos)
721 fg = data[pos: pos + l]
722 pos += l
723
736
724 fl = self.file(f)
737 fl = self.file(f)
725 o = fl.tip()
738 o = fl.tip()
726 n = fl.addgroup(fg, lambda x: self.changelog.rev(x), tr)
739 n = fl.addgroup(fg, lambda x: self.changelog.rev(x), tr)
727 if not simple:
740 if not simple:
728 new[fl] = fl.resolvedag(o, n, tr, resolverev)
741 nn = fl.resolvedag(o, n, tr, resolverev)
742 if nn: new[f] = nn
729
743
730 # For simple merges, we don't need to resolve manifests or changesets
744 # For simple merges, we don't need to resolve manifests or changesets
731 if simple:
745 if simple:
@@ -794,24 +808,30 b' class remoterepository:'
794 q.update(args)
808 q.update(args)
795 qs = urllib.urlencode(q)
809 qs = urllib.urlencode(q)
796 cu = "%s?%s" % (self.url, qs)
810 cu = "%s?%s" % (self.url, qs)
797 return urllib.urlopen(cu).read()
811 return urllib.urlopen(cu)
798
812
799 def branches(self, nodes):
813 def branches(self, nodes):
800 n = " ".join(map(hex, nodes))
814 n = " ".join(map(hex, nodes))
801 d = self.do_cmd("branches", nodes=n)
815 d = self.do_cmd("branches", nodes=n).read()
802 br = [ map(bin, b.split(" ")) for b in d.splitlines() ]
816 br = [ map(bin, b.split(" ")) for b in d.splitlines() ]
803 return br
817 return br
804
818
805 def between(self, pairs):
819 def between(self, pairs):
806 n = "\n".join(["-".join(map(hex, p)) for p in pairs])
820 n = "\n".join(["-".join(map(hex, p)) for p in pairs])
807 d = self.do_cmd("between", pairs=n)
821 d = self.do_cmd("between", pairs=n).read()
808 p = [ map(bin, l.split(" ")) for l in d.splitlines() ]
822 p = [ map(bin, l.split(" ")) for l in d.splitlines() ]
809 return p
823 return p
810
824
811 def changegroup(self, nodes):
825 def changegroup(self, nodes):
812 n = " ".join(map(hex, nodes))
826 n = " ".join(map(hex, nodes))
813 d = self.do_cmd("changegroup", roots=n)
827 zd = zlib.decompressobj()
814 return zlib.decompress(d)
828 f = self.do_cmd("changegroup", roots=n)
829 while 1:
830 d = f.read(4096)
831 if not d:
832 yield zd.flush()
833 break
834 yield zd.decompress(d)
815
835
816 def repository(ui, path=None, create=0):
836 def repository(ui, path=None, create=0):
817 if path and path[:5] == "hg://":
837 if path and path[:5] == "hg://":
@@ -345,11 +345,10 b' class revlog:'
345 # first delta is against its parent, which should be in our
345 # first delta is against its parent, which should be in our
346 # log, the rest are against the previous delta.
346 # log, the rest are against the previous delta.
347
347
348 if len(data) <= 4: return
348 if not data: return self.tip()
349
349
350 # retrieve the parent revision of the delta chain
350 # retrieve the parent revision of the delta chain
351 chain = data[28:48]
351 chain = data[24:44]
352 text = self.revision(chain)
353
352
354 # track the base of the current delta log
353 # track the base of the current delta log
355 r = self.count()
354 r = self.count()
@@ -370,7 +369,7 b' class revlog:'
370 ifh = self.opener(self.indexfile, "a")
369 ifh = self.opener(self.indexfile, "a")
371
370
372 # loop through our set of deltas
371 # loop through our set of deltas
373 pos = 4
372 pos = 0
374 while pos < len(data):
373 while pos < len(data):
375 l, node, p1, p2, cs = struct.unpack(">l20s20s20s20s",
374 l, node, p1, p2, cs = struct.unpack(">l20s20s20s20s",
376 data[pos:pos+84])
375 data[pos:pos+84])
@@ -391,7 +390,7 b' class revlog:'
391 # flush our writes here so we can read it in revision
390 # flush our writes here so we can read it in revision
392 dfh.flush()
391 dfh.flush()
393 ifh.flush()
392 ifh.flush()
394 text = self.revision(self.node(t))
393 text = self.revision(chain)
395 text = self.patch(text, delta)
394 text = self.patch(text, delta)
396 chk = self.addrevision(text, transaction, link, p1, p2)
395 chk = self.addrevision(text, transaction, link, p1, p2)
397 if chk != node:
396 if chk != node:
@@ -404,8 +403,7 b' class revlog:'
404 dfh.write(cdelta)
403 dfh.write(cdelta)
405 ifh.write(struct.pack(indexformat, *e))
404 ifh.write(struct.pack(indexformat, *e))
406
405
407 t, r = r, r + 1
406 t, r, chain, prev = r, r + 1, node, node
408 chain = prev
409 start = self.start(self.base(t))
407 start = self.start(self.base(t))
410 end = self.end(t)
408 end = self.end(t)
411
409
General Comments 0
You need to be logged in to leave comments. Login now