828 def cmp(self, node, text): |
828 def cmp(self, node, text): |
829 """compare text with a given file revision""" |
829 """compare text with a given file revision""" |
830 p1, p2 = self.parents(node) |
830 p1, p2 = self.parents(node) |
831 return hash(text, p1, p2) != node |
831 return hash(text, p1, p2) != node |
832 |
832 |
833 def diff(self, a, b): |
|
834 """return a delta between two revisions""" |
|
835 return mdiff.textdiff(a, b) |
|
836 |
|
837 def patches(self, t, pl): |
|
838 """apply a list of patches to a string""" |
|
839 return mdiff.patches(t, pl) |
|
840 |
|
841 def chunk(self, rev, df=None): |
833 def chunk(self, rev, df=None): |
842 start, length = self.start(rev), self.length(rev) |
834 start, length = self.start(rev), self.length(rev) |
843 if self._inline: |
835 if self._inline: |
844 start += (rev + 1) * self._io.size |
836 start += (rev + 1) * self._io.size |
845 end = start + length |
837 end = start + length |
882 b1 = self.base(rev1) |
874 b1 = self.base(rev1) |
883 b2 = self.base(rev2) |
875 b2 = self.base(rev2) |
884 if b1 == b2 and rev1 + 1 == rev2: |
876 if b1 == b2 and rev1 + 1 == rev2: |
885 return self.chunk(rev2) |
877 return self.chunk(rev2) |
886 else: |
878 else: |
887 return self.diff(self.revision(self.node(rev1)), |
879 return mdiff.textdiff(self.revision(self.node(rev1)), |
888 self.revision(self.node(rev2))) |
880 self.revision(self.node(rev2))) |
889 |
881 |
890 def revision(self, node): |
882 def revision(self, node): |
891 """return an uncompressed revision of a given""" |
883 """return an uncompressed revision of a given""" |
892 if node == nullid: |
884 if node == nullid: |
893 return "" |
885 return "" |
912 self._loadindex(base, rev + 1) |
904 self._loadindex(base, rev + 1) |
913 else: |
905 else: |
914 self._loadindex(base, rev + 1) |
906 self._loadindex(base, rev + 1) |
915 text = self.chunk(base, df=df) |
907 text = self.chunk(base, df=df) |
916 |
908 |
917 bins = [] |
909 bins = [self.chunk(r, df) for r in xrange(base + 1, rev + 1)] |
918 for r in xrange(base + 1, rev + 1): |
910 text = mdiff.patches(text, bins) |
919 bins.append(self.chunk(r, df=df)) |
|
920 |
|
921 text = self.patches(text, bins) |
|
922 |
|
923 p1, p2 = self.parents(node) |
911 p1, p2 = self.parents(node) |
924 if node != hash(text, p1, p2): |
912 if node != hash(text, p1, p2): |
925 raise RevlogError(_("integrity check failed on %s:%d") |
913 raise RevlogError(_("integrity check failed on %s:%d") |
926 % (self.datafile, rev)) |
914 % (self.datafile, rev)) |
927 |
915 |
996 offset = self.end(prev) |
984 offset = self.end(prev) |
997 |
985 |
998 if curr: |
986 if curr: |
999 if not d: |
987 if not d: |
1000 ptext = self.revision(self.node(prev)) |
988 ptext = self.revision(self.node(prev)) |
1001 d = self.diff(ptext, text) |
989 d = mdiff.textdiff(ptext, text) |
1002 data = compress(d) |
990 data = compress(d) |
1003 l = len(data[1]) + len(data[0]) |
991 l = len(data[1]) + len(data[0]) |
1004 dist = l + offset - self.start(base) |
992 dist = l + offset - self.start(base) |
1005 |
993 |
1006 # full versions are inserted when the needed deltas |
994 # full versions are inserted when the needed deltas |
1148 # flush our writes here so we can read it in revision |
1136 # flush our writes here so we can read it in revision |
1149 if dfh: |
1137 if dfh: |
1150 dfh.flush() |
1138 dfh.flush() |
1151 ifh.flush() |
1139 ifh.flush() |
1152 text = self.revision(chain) |
1140 text = self.revision(chain) |
1153 text = self.patches(text, [delta]) |
1141 text = mdiff.patches(text, [delta]) |
1154 chk = self._addrevision(text, transaction, link, p1, p2, None, |
1142 chk = self._addrevision(text, transaction, link, p1, p2, None, |
1155 ifh, dfh) |
1143 ifh, dfh) |
1156 if not dfh and not self._inline: |
1144 if not dfh and not self._inline: |
1157 # addrevision switched from inline to conventional |
1145 # addrevision switched from inline to conventional |
1158 # reopen the index |
1146 # reopen the index |