##// END OF EJS Templates
changegroup: control delta parent behavior via constructor...
Gregory Szorc -
r38937:23ae0c07 default
parent child Browse files
Show More
@@ -521,8 +521,8 b' class revisiondelta(object):'
521
521
522 class cg1packer(object):
522 class cg1packer(object):
523 def __init__(self, repo, filematcher, version, allowreorder,
523 def __init__(self, repo, filematcher, version, allowreorder,
524 builddeltaheader, manifestsend, sendtreemanifests,
524 useprevdelta, builddeltaheader, manifestsend,
525 bundlecaps=None):
525 sendtreemanifests, bundlecaps=None):
526 """Given a source repo, construct a bundler.
526 """Given a source repo, construct a bundler.
527
527
528 filematcher is a matcher that matches on files to include in the
528 filematcher is a matcher that matches on files to include in the
@@ -532,6 +532,9 b' class cg1packer(object):'
532 This value is used when ``bundle.reorder`` is ``auto`` or isn't
532 This value is used when ``bundle.reorder`` is ``auto`` or isn't
533 set.
533 set.
534
534
535 useprevdelta controls whether revisions should always delta against
536 the previous revision in the changegroup.
537
535 builddeltaheader is a callable that constructs the header for a group
538 builddeltaheader is a callable that constructs the header for a group
536 delta.
539 delta.
537
540
@@ -548,6 +551,7 b' class cg1packer(object):'
548 self._filematcher = filematcher
551 self._filematcher = filematcher
549
552
550 self.version = version
553 self.version = version
554 self._useprevdelta = useprevdelta
551 self._builddeltaheader = builddeltaheader
555 self._builddeltaheader = builddeltaheader
552 self._manifestsend = manifestsend
556 self._manifestsend = manifestsend
553 self._sendtreemanifests = sendtreemanifests
557 self._sendtreemanifests = sendtreemanifests
@@ -950,9 +954,51 b' class cg1packer(object):'
950 progress.complete()
954 progress.complete()
951
955
952 def deltaparent(self, store, rev, p1, p2, prev):
956 def deltaparent(self, store, rev, p1, p2, prev):
953 if not store.candelta(prev, rev):
957 if self._useprevdelta:
954 raise error.ProgrammingError('cg1 should not be used in this case')
958 if not store.candelta(prev, rev):
955 return prev
959 raise error.ProgrammingError(
960 'cg1 should not be used in this case')
961 return prev
962
963 # Narrow ellipses mode.
964 if util.safehasattr(self, 'full_nodes'):
965 # TODO: send better deltas when in narrow mode.
966 #
967 # changegroup.group() loops over revisions to send,
968 # including revisions we'll skip. What this means is that
969 # `prev` will be a potentially useless delta base for all
970 # ellipsis nodes, as the client likely won't have it. In
971 # the future we should do bookkeeping about which nodes
972 # have been sent to the client, and try to be
973 # significantly smarter about delta bases. This is
974 # slightly tricky because this same code has to work for
975 # all revlogs, and we don't have the linkrev/linknode here.
976 return p1
977
978 dp = store.deltaparent(rev)
979 if dp == nullrev and store.storedeltachains:
980 # Avoid sending full revisions when delta parent is null. Pick prev
981 # in that case. It's tempting to pick p1 in this case, as p1 will
982 # be smaller in the common case. However, computing a delta against
983 # p1 may require resolving the raw text of p1, which could be
984 # expensive. The revlog caches should have prev cached, meaning
985 # less CPU for changegroup generation. There is likely room to add
986 # a flag and/or config option to control this behavior.
987 base = prev
988 elif dp == nullrev:
989 # revlog is configured to use full snapshot for a reason,
990 # stick to full snapshot.
991 base = nullrev
992 elif dp not in (p1, p2, prev):
993 # Pick prev when we can't be sure remote has the base revision.
994 return prev
995 else:
996 base = dp
997
998 if base != nullrev and not store.candelta(base, rev):
999 base = nullrev
1000
1001 return base
956
1002
957 def revchunk(self, store, rev, prev, linknode):
1003 def revchunk(self, store, rev, prev, linknode):
958 if util.safehasattr(self, 'full_nodes'):
1004 if util.safehasattr(self, 'full_nodes'):
@@ -1125,51 +1171,13 b' class cg1packer(object):'
1125 deltachunks=(diffheader, data),
1171 deltachunks=(diffheader, data),
1126 )
1172 )
1127
1173
1128 class cg2packer(cg1packer):
1129 def deltaparent(self, store, rev, p1, p2, prev):
1130 # Narrow ellipses mode.
1131 if util.safehasattr(self, 'full_nodes'):
1132 # TODO: send better deltas when in narrow mode.
1133 #
1134 # changegroup.group() loops over revisions to send,
1135 # including revisions we'll skip. What this means is that
1136 # `prev` will be a potentially useless delta base for all
1137 # ellipsis nodes, as the client likely won't have it. In
1138 # the future we should do bookkeeping about which nodes
1139 # have been sent to the client, and try to be
1140 # significantly smarter about delta bases. This is
1141 # slightly tricky because this same code has to work for
1142 # all revlogs, and we don't have the linkrev/linknode here.
1143 return p1
1144
1145 dp = store.deltaparent(rev)
1146 if dp == nullrev and store.storedeltachains:
1147 # Avoid sending full revisions when delta parent is null. Pick prev
1148 # in that case. It's tempting to pick p1 in this case, as p1 will
1149 # be smaller in the common case. However, computing a delta against
1150 # p1 may require resolving the raw text of p1, which could be
1151 # expensive. The revlog caches should have prev cached, meaning
1152 # less CPU for changegroup generation. There is likely room to add
1153 # a flag and/or config option to control this behavior.
1154 base = prev
1155 elif dp == nullrev:
1156 # revlog is configured to use full snapshot for a reason,
1157 # stick to full snapshot.
1158 base = nullrev
1159 elif dp not in (p1, p2, prev):
1160 # Pick prev when we can't be sure remote has the base revision.
1161 return prev
1162 else:
1163 base = dp
1164 if base != nullrev and not store.candelta(base, rev):
1165 base = nullrev
1166 return base
1167
1168 def _makecg1packer(repo, filematcher, bundlecaps):
1174 def _makecg1packer(repo, filematcher, bundlecaps):
1169 builddeltaheader = lambda d: _CHANGEGROUPV1_DELTA_HEADER.pack(
1175 builddeltaheader = lambda d: _CHANGEGROUPV1_DELTA_HEADER.pack(
1170 d.node, d.p1node, d.p2node, d.linknode)
1176 d.node, d.p1node, d.p2node, d.linknode)
1171
1177
1172 return cg1packer(repo, filematcher, b'01', allowreorder=None,
1178 return cg1packer(repo, filematcher, b'01',
1179 useprevdelta=True,
1180 allowreorder=None,
1173 builddeltaheader=builddeltaheader,
1181 builddeltaheader=builddeltaheader,
1174 manifestsend=b'', sendtreemanifests=False,
1182 manifestsend=b'', sendtreemanifests=False,
1175 bundlecaps=bundlecaps)
1183 bundlecaps=bundlecaps)
@@ -1181,7 +1189,9 b' def _makecg2packer(repo, filematcher, bu'
1181 # Since generaldelta is directly supported by cg2, reordering
1189 # Since generaldelta is directly supported by cg2, reordering
1182 # generally doesn't help, so we disable it by default (treating
1190 # generally doesn't help, so we disable it by default (treating
1183 # bundle.reorder=auto just like bundle.reorder=False).
1191 # bundle.reorder=auto just like bundle.reorder=False).
1184 return cg2packer(repo, filematcher, b'02', allowreorder=False,
1192 return cg1packer(repo, filematcher, b'02',
1193 useprevdelta=False,
1194 allowreorder=False,
1185 builddeltaheader=builddeltaheader,
1195 builddeltaheader=builddeltaheader,
1186 manifestsend=b'', sendtreemanifests=False,
1196 manifestsend=b'', sendtreemanifests=False,
1187 bundlecaps=bundlecaps)
1197 bundlecaps=bundlecaps)
@@ -1190,7 +1200,9 b' def _makecg3packer(repo, filematcher, bu'
1190 builddeltaheader = lambda d: _CHANGEGROUPV3_DELTA_HEADER.pack(
1200 builddeltaheader = lambda d: _CHANGEGROUPV3_DELTA_HEADER.pack(
1191 d.node, d.p1node, d.p2node, d.basenode, d.linknode, d.flags)
1201 d.node, d.p1node, d.p2node, d.basenode, d.linknode, d.flags)
1192
1202
1193 return cg2packer(repo, filematcher, b'03', allowreorder=False,
1203 return cg1packer(repo, filematcher, b'03',
1204 useprevdelta=False,
1205 allowreorder=False,
1194 builddeltaheader=builddeltaheader,
1206 builddeltaheader=builddeltaheader,
1195 manifestsend=closechunk(), sendtreemanifests=True,
1207 manifestsend=closechunk(), sendtreemanifests=True,
1196 bundlecaps=bundlecaps)
1208 bundlecaps=bundlecaps)
General Comments 0
You need to be logged in to leave comments. Login now