##// END OF EJS Templates
narrow: when widening, don't include manifests the client already has...
Martin von Zweigbergk -
r40699:2c5835b4 default
parent child Browse files
Show More
@@ -117,7 +117,7 b' def getbundlechangegrouppart_narrow(bund'
117 repo, set(), common, known, newmatch)
117 repo, set(), common, known, newmatch)
118 if newvisit:
118 if newvisit:
119 packer = changegroup.getbundler(version, repo,
119 packer = changegroup.getbundler(version, repo,
120 filematcher=newmatch,
120 matcher=newmatch,
121 ellipses=True,
121 ellipses=True,
122 shallow=depth is not None,
122 shallow=depth is not None,
123 ellipsisroots=newellipsis,
123 ellipsisroots=newellipsis,
@@ -135,7 +135,7 b' def getbundlechangegrouppart_narrow(bund'
135 repo.ui.debug('Found %d relevant revs\n' % len(relevant_nodes))
135 repo.ui.debug('Found %d relevant revs\n' % len(relevant_nodes))
136 if visitnodes:
136 if visitnodes:
137 packer = changegroup.getbundler(version, repo,
137 packer = changegroup.getbundler(version, repo,
138 filematcher=newmatch,
138 matcher=newmatch,
139 ellipses=True,
139 ellipses=True,
140 shallow=depth is not None,
140 shallow=depth is not None,
141 ellipsisroots=ellipsisroots,
141 ellipsisroots=ellipsisroots,
@@ -12,7 +12,6 b' from mercurial import ('
12 error,
12 error,
13 extensions,
13 extensions,
14 hg,
14 hg,
15 match as matchmod,
16 narrowspec,
15 narrowspec,
17 pycompat,
16 pycompat,
18 wireprototypes,
17 wireprototypes,
@@ -82,9 +81,8 b' def narrow_widen(repo, proto, oldinclude'
82 exclude=newexcludes)
81 exclude=newexcludes)
83 oldmatch = narrowspec.match(repo.root, include=oldincludes,
82 oldmatch = narrowspec.match(repo.root, include=oldincludes,
84 exclude=oldexcludes)
83 exclude=oldexcludes)
85 diffmatch = matchmod.differencematcher(newmatch, oldmatch)
86
84
87 bundler = bundle2.widen_bundle(repo, diffmatch, common, known,
85 bundler = bundle2.widen_bundle(repo, oldmatch, newmatch, common, known,
88 cgversion, ellipses)
86 cgversion, ellipses)
89 except error.Abort as exc:
87 except error.Abort as exc:
90 bundler = bundle2.bundle20(repo.ui)
88 bundler = bundle2.bundle20(repo.ui)
@@ -2278,12 +2278,13 b' def handlestreamv2bundle(op, part):'
2278 streamclone.applybundlev2(repo, part, filecount, bytecount,
2278 streamclone.applybundlev2(repo, part, filecount, bytecount,
2279 requirements)
2279 requirements)
2280
2280
2281 def widen_bundle(repo, diffmatcher, common, known, cgversion, ellipses):
2281 def widen_bundle(repo, oldmatcher, newmatcher, common, known, cgversion,
2282 ellipses):
2282 """generates bundle2 for widening a narrow clone
2283 """generates bundle2 for widening a narrow clone
2283
2284
2284 repo is the localrepository instance
2285 repo is the localrepository instance
2285 diffmatcher is a differencemacther of '(newincludes, newexcludes) -
2286 oldmatcher matches what the client already has
2286 (oldincludes, oldexcludes)'
2287 newmatcher matches what the client needs (including what it already has)
2287 common is set of common heads between server and client
2288 common is set of common heads between server and client
2288 known is a set of revs known on the client side (used in ellipses)
2289 known is a set of revs known on the client side (used in ellipses)
2289 cgversion is the changegroup version to send
2290 cgversion is the changegroup version to send
@@ -2300,7 +2301,8 b' def widen_bundle(repo, diffmatcher, comm'
2300 # XXX: we should only send the filelogs (and treemanifest). user
2301 # XXX: we should only send the filelogs (and treemanifest). user
2301 # already has the changelog and manifest
2302 # already has the changelog and manifest
2302 packer = changegroup.getbundler(cgversion, repo,
2303 packer = changegroup.getbundler(cgversion, repo,
2303 filematcher=diffmatcher,
2304 oldmatcher=oldmatcher,
2305 matcher=newmatcher,
2304 fullnodes=commonnodes)
2306 fullnodes=commonnodes)
2305 cgdata = packer.generate(set([nodemod.nullid]), list(commonnodes),
2307 cgdata = packer.generate(set([nodemod.nullid]), list(commonnodes),
2306 False, 'narrow_widen', changelog=False)
2308 False, 'narrow_widen', changelog=False)
@@ -727,14 +727,17 b' def deltagroup(repo, store, nodes, ischa'
727 progress.complete()
727 progress.complete()
728
728
729 class cgpacker(object):
729 class cgpacker(object):
730 def __init__(self, repo, filematcher, version,
730 def __init__(self, repo, oldmatcher, matcher, version,
731 builddeltaheader, manifestsend,
731 builddeltaheader, manifestsend,
732 forcedeltaparentprev=False,
732 forcedeltaparentprev=False,
733 bundlecaps=None, ellipses=False,
733 bundlecaps=None, ellipses=False,
734 shallow=False, ellipsisroots=None, fullnodes=None):
734 shallow=False, ellipsisroots=None, fullnodes=None):
735 """Given a source repo, construct a bundler.
735 """Given a source repo, construct a bundler.
736
736
737 filematcher is a matcher that matches on files to include in the
737 oldmatcher is a matcher that matches on files the client already has.
738 These will not be included in the changegroup.
739
740 matcher is a matcher that matches on files to include in the
738 changegroup. Used to facilitate sparse changegroups.
741 changegroup. Used to facilitate sparse changegroups.
739
742
740 forcedeltaparentprev indicates whether delta parents must be against
743 forcedeltaparentprev indicates whether delta parents must be against
@@ -761,8 +764,10 b' class cgpacker(object):'
761 ellipsis because for very large histories we expect this to be
764 ellipsis because for very large histories we expect this to be
762 significantly smaller.
765 significantly smaller.
763 """
766 """
764 assert filematcher
767 assert oldmatcher
765 self._filematcher = filematcher
768 assert matcher
769 self._oldmatcher = oldmatcher
770 self._matcher = matcher
766
771
767 self.version = version
772 self.version = version
768 self._forcedeltaparentprev = forcedeltaparentprev
773 self._forcedeltaparentprev = forcedeltaparentprev
@@ -1027,7 +1032,7 b' class cgpacker(object):'
1027 tree, nodes = tmfnodes.popitem()
1032 tree, nodes = tmfnodes.popitem()
1028 store = mfl.getstorage(tree)
1033 store = mfl.getstorage(tree)
1029
1034
1030 if not self._filematcher.visitdir(store.tree[:-1] or '.'):
1035 if not self._matcher.visitdir(store.tree[:-1] or '.'):
1031 # No nodes to send because this directory is out of
1036 # No nodes to send because this directory is out of
1032 # the client's view of the repository (probably
1037 # the client's view of the repository (probably
1033 # because of narrow clones).
1038 # because of narrow clones).
@@ -1051,7 +1056,16 b' class cgpacker(object):'
1051 fullclnodes=self._fullclnodes,
1056 fullclnodes=self._fullclnodes,
1052 precomputedellipsis=self._precomputedellipsis)
1057 precomputedellipsis=self._precomputedellipsis)
1053
1058
1054 yield tree, deltas
1059 if not self._oldmatcher.visitdir(store.tree[:-1] or '.'):
1060 yield tree, deltas
1061 else:
1062 # 'deltas' is a generator and we need to consume it even if
1063 # we are not going to send it because a side-effect is that
1064 # it updates tmdnodes (via lookupfn)
1065 for d in deltas:
1066 pass
1067 if not tree:
1068 yield tree, []
1055
1069
1056 def _prunemanifests(self, store, nodes, commonrevs):
1070 def _prunemanifests(self, store, nodes, commonrevs):
1057 # This is split out as a separate method to allow filtering
1071 # This is split out as a separate method to allow filtering
@@ -1066,7 +1080,8 b' class cgpacker(object):'
1066 # The 'source' parameter is useful for extensions
1080 # The 'source' parameter is useful for extensions
1067 def generatefiles(self, changedfiles, commonrevs, source,
1081 def generatefiles(self, changedfiles, commonrevs, source,
1068 mfdicts, fastpathlinkrev, fnodes, clrevs):
1082 mfdicts, fastpathlinkrev, fnodes, clrevs):
1069 changedfiles = list(filter(self._filematcher, changedfiles))
1083 changedfiles = [f for f in changedfiles
1084 if self._matcher(f) and not self._oldmatcher(f)]
1070
1085
1071 if not fastpathlinkrev:
1086 if not fastpathlinkrev:
1072 def normallinknodes(unused, fname):
1087 def normallinknodes(unused, fname):
@@ -1151,12 +1166,13 b' class cgpacker(object):'
1151
1166
1152 progress.complete()
1167 progress.complete()
1153
1168
1154 def _makecg1packer(repo, filematcher, bundlecaps, ellipses=False,
1169 def _makecg1packer(repo, oldmatcher, matcher, bundlecaps,
1155 shallow=False, ellipsisroots=None, fullnodes=None):
1170 ellipses=False, shallow=False, ellipsisroots=None,
1171 fullnodes=None):
1156 builddeltaheader = lambda d: _CHANGEGROUPV1_DELTA_HEADER.pack(
1172 builddeltaheader = lambda d: _CHANGEGROUPV1_DELTA_HEADER.pack(
1157 d.node, d.p1node, d.p2node, d.linknode)
1173 d.node, d.p1node, d.p2node, d.linknode)
1158
1174
1159 return cgpacker(repo, filematcher, b'01',
1175 return cgpacker(repo, oldmatcher, matcher, b'01',
1160 builddeltaheader=builddeltaheader,
1176 builddeltaheader=builddeltaheader,
1161 manifestsend=b'',
1177 manifestsend=b'',
1162 forcedeltaparentprev=True,
1178 forcedeltaparentprev=True,
@@ -1166,12 +1182,13 b' def _makecg1packer(repo, filematcher, bu'
1166 ellipsisroots=ellipsisroots,
1182 ellipsisroots=ellipsisroots,
1167 fullnodes=fullnodes)
1183 fullnodes=fullnodes)
1168
1184
1169 def _makecg2packer(repo, filematcher, bundlecaps, ellipses=False,
1185 def _makecg2packer(repo, oldmatcher, matcher, bundlecaps,
1170 shallow=False, ellipsisroots=None, fullnodes=None):
1186 ellipses=False, shallow=False, ellipsisroots=None,
1187 fullnodes=None):
1171 builddeltaheader = lambda d: _CHANGEGROUPV2_DELTA_HEADER.pack(
1188 builddeltaheader = lambda d: _CHANGEGROUPV2_DELTA_HEADER.pack(
1172 d.node, d.p1node, d.p2node, d.basenode, d.linknode)
1189 d.node, d.p1node, d.p2node, d.basenode, d.linknode)
1173
1190
1174 return cgpacker(repo, filematcher, b'02',
1191 return cgpacker(repo, oldmatcher, matcher, b'02',
1175 builddeltaheader=builddeltaheader,
1192 builddeltaheader=builddeltaheader,
1176 manifestsend=b'',
1193 manifestsend=b'',
1177 bundlecaps=bundlecaps,
1194 bundlecaps=bundlecaps,
@@ -1180,12 +1197,13 b' def _makecg2packer(repo, filematcher, bu'
1180 ellipsisroots=ellipsisroots,
1197 ellipsisroots=ellipsisroots,
1181 fullnodes=fullnodes)
1198 fullnodes=fullnodes)
1182
1199
1183 def _makecg3packer(repo, filematcher, bundlecaps, ellipses=False,
1200 def _makecg3packer(repo, oldmatcher, matcher, bundlecaps,
1184 shallow=False, ellipsisroots=None, fullnodes=None):
1201 ellipses=False, shallow=False, ellipsisroots=None,
1202 fullnodes=None):
1185 builddeltaheader = lambda d: _CHANGEGROUPV3_DELTA_HEADER.pack(
1203 builddeltaheader = lambda d: _CHANGEGROUPV3_DELTA_HEADER.pack(
1186 d.node, d.p1node, d.p2node, d.basenode, d.linknode, d.flags)
1204 d.node, d.p1node, d.p2node, d.basenode, d.linknode, d.flags)
1187
1205
1188 return cgpacker(repo, filematcher, b'03',
1206 return cgpacker(repo, oldmatcher, matcher, b'03',
1189 builddeltaheader=builddeltaheader,
1207 builddeltaheader=builddeltaheader,
1190 manifestsend=closechunk(),
1208 manifestsend=closechunk(),
1191 bundlecaps=bundlecaps,
1209 bundlecaps=bundlecaps,
@@ -1252,15 +1270,17 b' def safeversion(repo):'
1252 assert versions
1270 assert versions
1253 return min(versions)
1271 return min(versions)
1254
1272
1255 def getbundler(version, repo, bundlecaps=None, filematcher=None,
1273 def getbundler(version, repo, bundlecaps=None, oldmatcher=None,
1256 ellipses=False, shallow=False, ellipsisroots=None,
1274 matcher=None, ellipses=False, shallow=False,
1257 fullnodes=None):
1275 ellipsisroots=None, fullnodes=None):
1258 assert version in supportedoutgoingversions(repo)
1276 assert version in supportedoutgoingversions(repo)
1259
1277
1260 if filematcher is None:
1278 if matcher is None:
1261 filematcher = matchmod.alwaysmatcher(repo.root, '')
1279 matcher = matchmod.alwaysmatcher(repo.root, '')
1280 if oldmatcher is None:
1281 oldmatcher = matchmod.nevermatcher(repo.root, '')
1262
1282
1263 if version == '01' and not filematcher.always():
1283 if version == '01' and not matcher.always():
1264 raise error.ProgrammingError('version 01 changegroups do not support '
1284 raise error.ProgrammingError('version 01 changegroups do not support '
1265 'sparse file matchers')
1285 'sparse file matchers')
1266
1286
@@ -1271,10 +1291,10 b' def getbundler(version, repo, bundlecaps'
1271
1291
1272 # Requested files could include files not in the local store. So
1292 # Requested files could include files not in the local store. So
1273 # filter those out.
1293 # filter those out.
1274 filematcher = repo.narrowmatch(filematcher)
1294 matcher = repo.narrowmatch(matcher)
1275
1295
1276 fn = _packermap[version][0]
1296 fn = _packermap[version][0]
1277 return fn(repo, filematcher, bundlecaps, ellipses=ellipses,
1297 return fn(repo, oldmatcher, matcher, bundlecaps, ellipses=ellipses,
1278 shallow=shallow, ellipsisroots=ellipsisroots,
1298 shallow=shallow, ellipsisroots=ellipsisroots,
1279 fullnodes=fullnodes)
1299 fullnodes=fullnodes)
1280
1300
@@ -1297,9 +1317,9 b' def makechangegroup(repo, outgoing, vers'
1297 {'clcount': len(outgoing.missing) })
1317 {'clcount': len(outgoing.missing) })
1298
1318
1299 def makestream(repo, outgoing, version, source, fastpath=False,
1319 def makestream(repo, outgoing, version, source, fastpath=False,
1300 bundlecaps=None, filematcher=None):
1320 bundlecaps=None, matcher=None):
1301 bundler = getbundler(version, repo, bundlecaps=bundlecaps,
1321 bundler = getbundler(version, repo, bundlecaps=bundlecaps,
1302 filematcher=filematcher)
1322 matcher=matcher)
1303
1323
1304 repo = repo.unfiltered()
1324 repo = repo.unfiltered()
1305 commonrevs = outgoing.common
1325 commonrevs = outgoing.common
@@ -2153,14 +2153,12 b' def _getbundlechangegrouppart(bundler, r'
2153 if kwargs.get(r'narrow', False):
2153 if kwargs.get(r'narrow', False):
2154 include = sorted(filter(bool, kwargs.get(r'includepats', [])))
2154 include = sorted(filter(bool, kwargs.get(r'includepats', [])))
2155 exclude = sorted(filter(bool, kwargs.get(r'excludepats', [])))
2155 exclude = sorted(filter(bool, kwargs.get(r'excludepats', [])))
2156 filematcher = narrowspec.match(repo.root, include=include,
2156 matcher = narrowspec.match(repo.root, include=include, exclude=exclude)
2157 exclude=exclude)
2158 else:
2157 else:
2159 filematcher = None
2158 matcher = None
2160
2159
2161 cgstream = changegroup.makestream(repo, outgoing, version, source,
2160 cgstream = changegroup.makestream(repo, outgoing, version, source,
2162 bundlecaps=bundlecaps,
2161 bundlecaps=bundlecaps, matcher=matcher)
2163 filematcher=filematcher)
2164
2162
2165 part = bundler.newpart('changegroup', data=cgstream)
2163 part = bundler.newpart('changegroup', data=cgstream)
2166 if cgversions:
2164 if cgversions:
General Comments 0
You need to be logged in to leave comments. Login now