##// END OF EJS Templates
Changes to network protocol...
mpm@selenic.com -
r192:5d855335 default
parent child Browse files
Show More
@@ -417,7 +417,6 b' elif cmd == "merge":'
417 if args[0] in paths: args[0] = paths[args[0]]
417 if args[0] in paths: args[0] = paths[args[0]]
418
418
419 other = hg.repository(ui, args[0])
419 other = hg.repository(ui, args[0])
420 ui.status("requesting changegroup\n")
421 cg = repo.getchangegroup(other)
420 cg = repo.getchangegroup(other)
422 repo.addchangegroup(cg)
421 repo.addchangegroup(cg)
423 else:
422 else:
@@ -291,6 +291,7 b' class localrepository:'
291 return os.path.join(self.path, f)
291 return os.path.join(self.path, f)
292
292
293 def file(self, f):
293 def file(self, f):
294 if f[0] == '/': f = f[1:]
294 return filelog(self.opener, f)
295 return filelog(self.opener, f)
295
296
296 def transaction(self):
297 def transaction(self):
@@ -530,6 +531,8 b' class localrepository:'
530 fetch = []
531 fetch = []
531 seen = {}
532 seen = {}
532 seenbranch = {}
533 seenbranch = {}
534
535 self.ui.status("searching for changes\n")
533 tip = remote.branches([])[0]
536 tip = remote.branches([])[0]
534 self.ui.debug("remote tip branch is %s:%s\n" %
537 self.ui.debug("remote tip branch is %s:%s\n" %
535 (short(tip[0]), short(tip[1])))
538 (short(tip[0]), short(tip[1])))
@@ -542,7 +545,7 b' class localrepository:'
542 unknown = [tip]
545 unknown = [tip]
543
546
544 if tip[0] in m:
547 if tip[0] in m:
545 self.ui.note("nothing to do!\n")
548 self.ui.status("nothing to do!\n")
546 return None
549 return None
547
550
548 while unknown:
551 while unknown:
@@ -627,14 +630,13 b' class localrepository:'
627 # the changegroup is changesets + manifests + all file revs
630 # the changegroup is changesets + manifests + all file revs
628 revs = [ self.changelog.rev(n) for n in nodes ]
631 revs = [ self.changelog.rev(n) for n in nodes ]
629
632
630 yield self.changelog.group(linkmap)
633 for y in self.changelog.group(linkmap): yield y
631 yield self.manifest.group(linkmap)
634 for y in self.manifest.group(linkmap): yield y
632
633 for f in changed:
635 for f in changed:
636 yield struct.pack(">l", len(f) + 4) + f
634 g = self.file(f).group(linkmap)
637 g = self.file(f).group(linkmap)
635 if not g: raise "couldn't find change to %s" % f
638 for y in g:
636 l = struct.pack(">l", len(f))
639 yield y
637 yield "".join([l, f, g])
638
640
639 def addchangegroup(self, generator):
641 def addchangegroup(self, generator):
640 changesets = files = revisions = 0
642 changesets = files = revisions = 0
@@ -656,11 +658,18 b' class localrepository:'
656 if not generator: return
658 if not generator: return
657 source = genread(generator)
659 source = genread(generator)
658
660
659 def getchunk(add = 0):
661 def getchunk():
660 d = source.read(4)
662 d = source.read(4)
661 if not d: return ""
663 if not d: return ""
662 l = struct.unpack(">l", d)[0]
664 l = struct.unpack(">l", d)[0]
663 return source.read(l - 4 + add)
665 if l <= 4: return ""
666 return source.read(l - 4)
667
668 def getgroup():
669 while 1:
670 c = getchunk()
671 if not c: break
672 yield c
664
673
665 tr = self.transaction()
674 tr = self.transaction()
666 simple = True
675 simple = True
@@ -671,21 +680,17 b' class localrepository:'
671 def report(x):
680 def report(x):
672 self.ui.debug("add changeset %s\n" % short(x))
681 self.ui.debug("add changeset %s\n" % short(x))
673 return self.changelog.count()
682 return self.changelog.count()
674
683
675 csg = getchunk()
676 co = self.changelog.tip()
684 co = self.changelog.tip()
677 cn = self.changelog.addgroup(csg, report, tr)
685 cn = self.changelog.addgroup(getgroup(), report, tr)
678
686
679 revisions = self.changelog.rev(cn) - self.changelog.rev(co)
687 changesets = self.changelog.rev(cn) - self.changelog.rev(co)
680 changesets = revisions
681
688
682 self.ui.status("adding manifests\n")
689 self.ui.status("adding manifests\n")
683 # pull off the manifest group
690 # pull off the manifest group
684 mfg = getchunk()
685 mm = self.manifest.tip()
691 mm = self.manifest.tip()
686 mo = self.manifest.addgroup(mfg, lambda x: self.changelog.rev(x), tr)
692 mo = self.manifest.addgroup(getgroup(),
687
693 lambda x: self.changelog.rev(x), tr)
688 revisions += self.manifest.rev(mo) - self.manifest.rev(mm)
689
694
690 # do we need a resolve?
695 # do we need a resolve?
691 if self.changelog.ancestor(co, cn) != co:
696 if self.changelog.ancestor(co, cn) != co:
@@ -749,13 +754,12 b' class localrepository:'
749 # process the files
754 # process the files
750 self.ui.status("adding files\n")
755 self.ui.status("adding files\n")
751 while 1:
756 while 1:
752 f = getchunk(4)
757 f = getchunk()
753 if not f: break
758 if not f: break
754 fg = getchunk()
755 self.ui.debug("adding %s revisions\n" % f)
759 self.ui.debug("adding %s revisions\n" % f)
756 fl = self.file(f)
760 fl = self.file(f)
757 o = fl.tip()
761 o = fl.tip()
758 n = fl.addgroup(fg, lambda x: self.changelog.rev(x), tr)
762 n = fl.addgroup(getgroup(), lambda x: self.changelog.rev(x), tr)
759 revisions += fl.rev(n) - fl.rev(o)
763 revisions += fl.rev(n) - fl.rev(o)
760 files += 1
764 files += 1
761 if f in need:
765 if f in need:
@@ -774,9 +778,9 b' class localrepository:'
774 # For simple merges, we don't need to resolve manifests or changesets
778 # For simple merges, we don't need to resolve manifests or changesets
775 if simple:
779 if simple:
776 self.ui.debug("simple merge, skipping resolve\n")
780 self.ui.debug("simple merge, skipping resolve\n")
777 self.ui.status(("added %d changesets, %d files," +
781 self.ui.status(("modified %d files, added %d changesets" +
778 " and %d new revisions\n")
782 " and %d new revisions\n")
779 % (changesets, files, revisions))
783 % (files, changesets, revisions))
780 tr.close()
784 tr.close()
781 return
785 return
782
786
@@ -865,12 +869,15 b' class remoterepository:'
865 n = " ".join(map(hex, nodes))
869 n = " ".join(map(hex, nodes))
866 zd = zlib.decompressobj()
870 zd = zlib.decompressobj()
867 f = self.do_cmd("changegroup", roots=n)
871 f = self.do_cmd("changegroup", roots=n)
872 bytes = 0
868 while 1:
873 while 1:
869 d = f.read(4096)
874 d = f.read(4096)
875 bytes += len(d)
870 if not d:
876 if not d:
871 yield zd.flush()
877 yield zd.flush()
872 break
878 break
873 yield zd.decompress(d)
879 yield zd.decompress(d)
880 self.ui.note("%d bytes of data transfered\n" % bytes)
874
881
875 def repository(ui, path=None, create=0):
882 def repository(ui, path=None, create=0):
876 if path and path[:7] == "http://":
883 if path and path[:7] == "http://":
@@ -244,8 +244,6 b' class revlog:'
244 end = self.end(t)
244 end = self.end(t)
245 prev = self.revision(self.tip())
245 prev = self.revision(self.tip())
246 d = self.diff(prev, text)
246 d = self.diff(prev, text)
247 if self.patches(prev, [d]) != text:
248 raise AssertionError("diff failed")
249 data = compress(d)
247 data = compress(d)
250 dist = end - start + len(data)
248 dist = end - start + len(data)
251
249
@@ -330,7 +328,9 b' class revlog:'
330 needed[i] = 1
328 needed[i] = 1
331
329
332 # if we don't have any revisions touched by these changesets, bail
330 # if we don't have any revisions touched by these changesets, bail
333 if not revs: return struct.pack(">l", 0)
331 if not revs:
332 yield struct.pack(">l", 0)
333 return
334
334
335 # add the parent of the first rev
335 # add the parent of the first rev
336 p = self.parents(self.node(revs[0]))[0]
336 p = self.parents(self.node(revs[0]))[0]
@@ -352,25 +352,25 b' class revlog:'
352 needed = needed.keys()
352 needed = needed.keys()
353 needed.sort()
353 needed.sort()
354 spans = []
354 spans = []
355 oo = -1
356 ol = 0
355 for n in needed:
357 for n in needed:
356 if n < 0: continue
358 if n < 0: continue
357 o = self.start(n)
359 o = self.start(n)
358 l = self.length(n)
360 l = self.length(n)
359 spans.append((o, l, [(n, l)]))
361 if oo + ol == o: # can we merge with the previous?
360
362 nl = spans[-1][2]
361 # merge spans
363 nl.append((n, l))
362 merge = [spans.pop(0)]
364 ol += l
363 while spans:
365 spans[-1] = (oo, ol, nl)
364 e = spans.pop(0)
365 f = merge[-1]
366 if e[0] == f[0] + f[1]:
367 merge[-1] = (f[0], f[1] + e[1], f[2] + e[2])
368 else:
366 else:
369 merge.append(e)
367 oo = o
368 ol = l
369 spans.append((oo, ol, [(n, l)]))
370
370
371 # read spans in, divide up chunks
371 # read spans in, divide up chunks
372 chunks = {}
372 chunks = {}
373 for span in merge:
373 for span in spans:
374 # we reopen the file for each span to make http happy for now
374 # we reopen the file for each span to make http happy for now
375 f = self.opener(self.datafile)
375 f = self.opener(self.datafile)
376 f.seek(span[0])
376 f.seek(span[0])
@@ -379,12 +379,12 b' class revlog:'
379 # divide up the span
379 # divide up the span
380 pos = 0
380 pos = 0
381 for r, l in span[2]:
381 for r, l in span[2]:
382 chunks[r] = data[pos: pos + l]
382 chunks[r] = decompress(data[pos: pos + l])
383 pos += l
383 pos += l
384
384
385 # helper to reconstruct intermediate versions
385 # helper to reconstruct intermediate versions
386 def construct(text, base, rev):
386 def construct(text, base, rev):
387 bins = [decompress(chunks[r]) for r in xrange(base + 1, rev + 1)]
387 bins = [chunks[r] for r in xrange(base + 1, rev + 1)]
388 return mdiff.patches(text, bins)
388 return mdiff.patches(text, bins)
389
389
390 # build deltas
390 # build deltas
@@ -392,11 +392,12 b' class revlog:'
392 for d in xrange(0, len(revs) - 1):
392 for d in xrange(0, len(revs) - 1):
393 a, b = revs[d], revs[d + 1]
393 a, b = revs[d], revs[d + 1]
394 n = self.node(b)
394 n = self.node(b)
395
395
396 # do we need to construct a new delta?
396 if a + 1 != b or self.base(b) == b:
397 if a + 1 != b or self.base(b) == b:
397 if a >= 0:
398 if a >= 0:
398 base = self.base(a)
399 base = self.base(a)
399 ta = decompress(chunks[self.base(a)])
400 ta = chunks[self.base(a)]
400 ta = construct(ta, base, a)
401 ta = construct(ta, base, a)
401 else:
402 else:
402 ta = ""
403 ta = ""
@@ -406,36 +407,30 b' class revlog:'
406 base = a
407 base = a
407 tb = ta
408 tb = ta
408 else:
409 else:
409 tb = decompress(chunks[self.base(b)])
410 tb = chunks[self.base(b)]
410 tb = construct(tb, base, b)
411 tb = construct(tb, base, b)
411 d = self.diff(ta, tb)
412 d = self.diff(ta, tb)
412 else:
413 else:
413 d = decompress(chunks[b])
414 d = chunks[b]
414
415
415 p = self.parents(n)
416 p = self.parents(n)
416 meta = n + p[0] + p[1] + linkmap[self.linkrev(n)]
417 meta = n + p[0] + p[1] + linkmap[self.linkrev(n)]
417 l = struct.pack(">l", len(meta) + len(d) + 4)
418 l = struct.pack(">l", len(meta) + len(d) + 4)
418 deltas.append(l + meta + d)
419 yield l
420 yield meta
421 yield d
419
422
420 l = struct.pack(">l", sum(map(len, deltas)) + 4)
423 yield struct.pack(">l", 0)
421 deltas.insert(0, l)
424
422 return "".join(deltas)
425 def addgroup(self, revs, linkmapper, transaction):
423
424 def addgroup(self, data, linkmapper, transaction):
425 # given a set of deltas, add them to the revision log. the
426 # given a set of deltas, add them to the revision log. the
426 # first delta is against its parent, which should be in our
427 # first delta is against its parent, which should be in our
427 # log, the rest are against the previous delta.
428 # log, the rest are against the previous delta.
428
429
429 if not data: return self.tip()
430
431 # retrieve the parent revision of the delta chain
432 chain = data[24:44]
433 if not chain in self.nodemap:
434 raise "unknown base %s" % short(chain[:4])
435
436 # track the base of the current delta log
430 # track the base of the current delta log
437 r = self.count()
431 r = self.count()
438 t = r - 1
432 t = r - 1
433 node = nullid
439
434
440 base = prev = -1
435 base = prev = -1
441 start = end = 0
436 start = end = 0
@@ -452,15 +447,19 b' class revlog:'
452 ifh = self.opener(self.indexfile, "a")
447 ifh = self.opener(self.indexfile, "a")
453
448
454 # loop through our set of deltas
449 # loop through our set of deltas
455 pos = 0
450 chain = None
456 while pos < len(data):
451 for chunk in revs:
457 l, node, p1, p2, cs = struct.unpack(">l20s20s20s20s",
452 node, p1, p2, cs = struct.unpack("20s20s20s20s", chunk[:80])
458 data[pos:pos+84])
459 link = linkmapper(cs)
453 link = linkmapper(cs)
460 if node in self.nodemap:
454 if node in self.nodemap:
461 raise "already have %s" % hex(node[:4])
455 raise "already have %s" % hex(node[:4])
462 delta = data[pos + 84:pos + l]
456 delta = chunk[80:]
463 pos += l
457
458 if not chain:
459 # retrieve the parent revision of the delta chain
460 chain = p1
461 if not chain in self.nodemap:
462 raise "unknown base %s" % short(chain[:4])
464
463
465 # full versions are inserted when the needed deltas become
464 # full versions are inserted when the needed deltas become
466 # comparable to the uncompressed text or when the previous
465 # comparable to the uncompressed text or when the previous
General Comments 0
You need to be logged in to leave comments. Login now