Show More
@@ -100,7 +100,7 b' def toposort_postorderreverse(ui, rl):' | |||||
100 | result.reverse() |
|
100 | result.reverse() | |
101 | return result |
|
101 | return result | |
102 |
|
102 | |||
103 | def writerevs(ui, r1, r2, order, tr): |
|
103 | def writerevs(ui, repo, r1, r2, order, tr): | |
104 |
|
104 | |||
105 | ui.status(_('writing revs\n')) |
|
105 | ui.status(_('writing revs\n')) | |
106 |
|
106 | |||
@@ -117,7 +117,7 b' def writerevs(ui, r1, r2, order, tr):' | |||||
117 | unlookup = lambda x: int(x, 10) |
|
117 | unlookup = lambda x: int(x, 10) | |
118 |
|
118 | |||
119 | try: |
|
119 | try: | |
120 | bundler = changegroup.bundle10() |
|
120 | bundler = changegroup.bundle10(repo) | |
121 | bundler.start(lookup) |
|
121 | bundler.start(lookup) | |
122 | group = util.chunkbuffer(bundler.group(order, r1)) |
|
122 | group = util.chunkbuffer(bundler.group(order, r1)) | |
123 | group = changegroup.unbundle10(group, "UN") |
|
123 | group = changegroup.unbundle10(group, "UN") | |
@@ -238,7 +238,7 b' def shrink(ui, repo, **opts):' | |||||
238 | suboptimal += 1 |
|
238 | suboptimal += 1 | |
239 | ui.note(_('%d suboptimal nodes\n') % suboptimal) |
|
239 | ui.note(_('%d suboptimal nodes\n') % suboptimal) | |
240 |
|
240 | |||
241 | writerevs(ui, r1, r2, order, tr) |
|
241 | writerevs(ui, repo, r1, r2, order, tr) | |
242 | report(ui, r1, r2) |
|
242 | report(ui, r1, r2) | |
243 | tr.close() |
|
243 | tr.close() | |
244 | except: # re-raises |
|
244 | except: # re-raises |
@@ -6,7 +6,7 b'' | |||||
6 | # GNU General Public License version 2 or any later version. |
|
6 | # GNU General Public License version 2 or any later version. | |
7 |
|
7 | |||
8 | from i18n import _ |
|
8 | from i18n import _ | |
9 | from node import nullrev |
|
9 | from node import nullrev, hex | |
10 | import mdiff, util, dagutil |
|
10 | import mdiff, util, dagutil | |
11 | import struct, os, bz2, zlib, tempfile |
|
11 | import struct, os, bz2, zlib, tempfile | |
12 |
|
12 | |||
@@ -225,11 +225,26 b' def readbundle(fh, fname):' | |||||
225 |
|
225 | |||
226 | class bundle10(object): |
|
226 | class bundle10(object): | |
227 | deltaheader = _BUNDLE10_DELTA_HEADER |
|
227 | deltaheader = _BUNDLE10_DELTA_HEADER | |
228 | def __init__(self, bundlecaps=None): |
|
228 | def __init__(self, repo, bundlecaps=None): | |
|
229 | """Given a source repo, construct a bundler. | |||
|
230 | ||||
|
231 | bundlecaps is optional and can be used to specify the set of | |||
|
232 | capabilities which can be used to build the bundle. | |||
|
233 | """ | |||
229 | # Set of capabilities we can use to build the bundle. |
|
234 | # Set of capabilities we can use to build the bundle. | |
230 | if bundlecaps is None: |
|
235 | if bundlecaps is None: | |
231 | bundlecaps = set() |
|
236 | bundlecaps = set() | |
232 | self._bundlecaps = bundlecaps |
|
237 | self._bundlecaps = bundlecaps | |
|
238 | self._changelog = repo.changelog | |||
|
239 | self._manifest = repo.manifest | |||
|
240 | reorder = repo.ui.config('bundle', 'reorder', 'auto') | |||
|
241 | if reorder == 'auto': | |||
|
242 | reorder = None | |||
|
243 | else: | |||
|
244 | reorder = util.parsebool(reorder) | |||
|
245 | self._repo = repo | |||
|
246 | self._reorder = reorder | |||
|
247 | self.count = [0, 0] | |||
233 | def start(self, lookup): |
|
248 | def start(self, lookup): | |
234 | self._lookup = lookup |
|
249 | self._lookup = lookup | |
235 | def close(self): |
|
250 | def close(self): | |
@@ -276,6 +291,43 b' class bundle10(object):' | |||||
276 |
|
291 | |||
277 | yield self.close() |
|
292 | yield self.close() | |
278 |
|
293 | |||
|
294 | def generate(self, clnodes, getmfnodes, getfiles, getfilenodes, source): | |||
|
295 | '''yield a sequence of changegroup chunks (strings)''' | |||
|
296 | repo = self._repo | |||
|
297 | cl = self._changelog | |||
|
298 | mf = self._manifest | |||
|
299 | reorder = self._reorder | |||
|
300 | progress = repo.ui.progress | |||
|
301 | count = self.count | |||
|
302 | _bundling = _('bundling') | |||
|
303 | ||||
|
304 | count[:] = [0, len(clnodes)] | |||
|
305 | for chunk in self.group(clnodes, cl, reorder=reorder): | |||
|
306 | yield chunk | |||
|
307 | progress(_bundling, None) | |||
|
308 | ||||
|
309 | for chunk in self.group(getmfnodes(), mf, reorder=reorder): | |||
|
310 | yield chunk | |||
|
311 | progress(_bundling, None) | |||
|
312 | ||||
|
313 | changedfiles = getfiles() | |||
|
314 | count[:] = [0, len(changedfiles)] | |||
|
315 | for fname in sorted(changedfiles): | |||
|
316 | filerevlog = repo.file(fname) | |||
|
317 | if not len(filerevlog): | |||
|
318 | raise util.Abort(_("empty or missing revlog for %s") | |||
|
319 | % fname) | |||
|
320 | nodelist = getfilenodes(fname, filerevlog) | |||
|
321 | if nodelist: | |||
|
322 | count[0] += 1 | |||
|
323 | yield self.fileheader(fname) | |||
|
324 | for chunk in self.group(nodelist, filerevlog, reorder): | |||
|
325 | yield chunk | |||
|
326 | yield self.close() | |||
|
327 | progress(_bundling, None) | |||
|
328 | ||||
|
329 | if clnodes: | |||
|
330 | repo.hook('outgoing', node=hex(clnodes[0]), source=source) | |||
279 |
|
331 | |||
280 | def revchunk(self, revlog, rev, prev): |
|
332 | def revchunk(self, revlog, rev, prev): | |
281 | node = revlog.node(rev) |
|
333 | node = revlog.node(rev) |
@@ -1844,7 +1844,7 b' class localrepository(object):' | |||||
1844 | if revs is None and not outgoing.excluded: |
|
1844 | if revs is None and not outgoing.excluded: | |
1845 | # push everything, |
|
1845 | # push everything, | |
1846 | # use the fast path, no race possible on push |
|
1846 | # use the fast path, no race possible on push | |
1847 | bundler = changegroup.bundle10(bundlecaps) |
|
1847 | bundler = changegroup.bundle10(self, bundlecaps) | |
1848 | cg = self._changegroup(outgoing.missing, bundler, |
|
1848 | cg = self._changegroup(outgoing.missing, bundler, | |
1849 | 'push') |
|
1849 | 'push') | |
1850 | else: |
|
1850 | else: | |
@@ -1992,7 +1992,7 b' class localrepository(object):' | |||||
1992 | csets, bases, heads = cl.nodesbetween(bases, heads) |
|
1992 | csets, bases, heads = cl.nodesbetween(bases, heads) | |
1993 | # We assume that all ancestors of bases are known |
|
1993 | # We assume that all ancestors of bases are known | |
1994 | common = cl.ancestors([cl.rev(n) for n in bases]) |
|
1994 | common = cl.ancestors([cl.rev(n) for n in bases]) | |
1995 | bundler = changegroup.bundle10() |
|
1995 | bundler = changegroup.bundle10(self) | |
1996 | return self._changegroupsubset(common, csets, heads, bundler, source) |
|
1996 | return self._changegroupsubset(common, csets, heads, bundler, source) | |
1997 |
|
1997 | |||
1998 | def getlocalbundle(self, source, outgoing, bundlecaps=None): |
|
1998 | def getlocalbundle(self, source, outgoing, bundlecaps=None): | |
@@ -2002,7 +2002,7 b' class localrepository(object):' | |||||
2002 | precomputed sets in outgoing.""" |
|
2002 | precomputed sets in outgoing.""" | |
2003 | if not outgoing.missing: |
|
2003 | if not outgoing.missing: | |
2004 | return None |
|
2004 | return None | |
2005 | bundler = changegroup.bundle10(bundlecaps) |
|
2005 | bundler = changegroup.bundle10(self, bundlecaps) | |
2006 | return self._changegroupsubset(outgoing.common, |
|
2006 | return self._changegroupsubset(outgoing.common, | |
2007 | outgoing.missing, |
|
2007 | outgoing.missing, | |
2008 | outgoing.missingheads, |
|
2008 | outgoing.missingheads, | |
@@ -2033,13 +2033,12 b' class localrepository(object):' | |||||
2033 | @unfilteredmethod |
|
2033 | @unfilteredmethod | |
2034 | def _changegroupsubset(self, commonrevs, csets, heads, bundler, source): |
|
2034 | def _changegroupsubset(self, commonrevs, csets, heads, bundler, source): | |
2035 |
|
2035 | |||
2036 |
cl = |
|
2036 | cl = bundler._changelog | |
2037 |
mf = |
|
2037 | mf = bundler._manifest | |
2038 | mfs = {} # needed manifests |
|
2038 | mfs = {} # needed manifests | |
2039 | fnodes = {} # needed file nodes |
|
2039 | fnodes = {} # needed file nodes | |
2040 | changedfiles = set() |
|
2040 | changedfiles = set() | |
2041 | fstate = ['', {}] |
|
2041 | fstate = ['', {}] | |
2042 | count = [0, 0] |
|
|||
2043 |
|
2042 | |||
2044 | # can we go through the fast path ? |
|
2043 | # can we go through the fast path ? | |
2045 | heads.sort() |
|
2044 | heads.sort() | |
@@ -2063,6 +2062,7 b' class localrepository(object):' | |||||
2063 | _files = _('files') |
|
2062 | _files = _('files') | |
2064 |
|
2063 | |||
2065 | def lookup(revlog, x): |
|
2064 | def lookup(revlog, x): | |
|
2065 | count = bundler.count | |||
2066 | if revlog == cl: |
|
2066 | if revlog == cl: | |
2067 | c = cl.read(x) |
|
2067 | c = cl.read(x) | |
2068 | changedfiles.update(c[3]) |
|
2068 | changedfiles.update(c[3]) | |
@@ -2087,56 +2087,23 b' class localrepository(object):' | |||||
2087 | return fstate[1][x] |
|
2087 | return fstate[1][x] | |
2088 |
|
2088 | |||
2089 | bundler.start(lookup) |
|
2089 | bundler.start(lookup) | |
2090 | reorder = self.ui.config('bundle', 'reorder', 'auto') |
|
|||
2091 | if reorder == 'auto': |
|
|||
2092 | reorder = None |
|
|||
2093 | else: |
|
|||
2094 | reorder = util.parsebool(reorder) |
|
|||
2095 |
|
2090 | |||
2096 |
def ge |
|
2091 | def getmfnodes(): | |
2097 | # Create a changenode group generator that will call our functions |
|
|||
2098 | # back to lookup the owning changenode and collect information. |
|
|||
2099 | count[:] = [0, len(csets)] |
|
|||
2100 | for chunk in bundler.group(csets, cl, reorder=reorder): |
|
|||
2101 | yield chunk |
|
|||
2102 | progress(_bundling, None) |
|
|||
2103 |
|
||||
2104 | # Create a generator for the manifestnodes that calls our lookup |
|
|||
2105 | # and data collection functions back. |
|
|||
2106 | for f in changedfiles: |
|
2092 | for f in changedfiles: | |
2107 | fnodes[f] = {} |
|
2093 | fnodes[f] = {} | |
2108 | count[:] = [0, len(mfs)] |
|
2094 | bundler.count[:] = [0, len(mfs)] | |
2109 | for chunk in bundler.group(prune(mf, mfs), mf, reorder=reorder): |
|
2095 | return prune(mf, mfs) | |
2110 | yield chunk |
|
2096 | def getfiles(): | |
2111 | progress(_bundling, None) |
|
|||
2112 |
|
||||
2113 | mfs.clear() |
|
2097 | mfs.clear() | |
|
2098 | return changedfiles | |||
|
2099 | def getfilenodes(fname, filerevlog): | |||
|
2100 | fstate[0] = fname | |||
|
2101 | fstate[1] = fnodes.pop(fname, {}) | |||
|
2102 | return prune(filerevlog, fstate[1]) | |||
2114 |
|
2103 | |||
2115 | # Go through all our files in order sorted by name. |
|
2104 | gengroup = bundler.generate(csets, getmfnodes, getfiles, getfilenodes, | |
2116 | count[:] = [0, len(changedfiles)] |
|
2105 | source) | |
2117 | for fname in sorted(changedfiles): |
|
2106 | return changegroup.unbundle10(util.chunkbuffer(gengroup), 'UN') | |
2118 | filerevlog = self.file(fname) |
|
|||
2119 | if not len(filerevlog): |
|
|||
2120 | raise util.Abort(_("empty or missing revlog for %s") |
|
|||
2121 | % fname) |
|
|||
2122 | fstate[0] = fname |
|
|||
2123 | fstate[1] = fnodes.pop(fname, {}) |
|
|||
2124 |
|
||||
2125 | nodelist = prune(filerevlog, fstate[1]) |
|
|||
2126 | if nodelist: |
|
|||
2127 | count[0] += 1 |
|
|||
2128 | yield bundler.fileheader(fname) |
|
|||
2129 | for chunk in bundler.group(nodelist, filerevlog, reorder): |
|
|||
2130 | yield chunk |
|
|||
2131 |
|
||||
2132 | # Signal that no more groups are left. |
|
|||
2133 | yield bundler.close() |
|
|||
2134 | progress(_bundling, None) |
|
|||
2135 |
|
||||
2136 | if csets: |
|
|||
2137 | self.hook('outgoing', node=hex(csets[0]), source=source) |
|
|||
2138 |
|
||||
2139 | return changegroup.unbundle10(util.chunkbuffer(gengroup()), 'UN') |
|
|||
2140 |
|
2107 | |||
2141 | def changegroup(self, basenodes, source): |
|
2108 | def changegroup(self, basenodes, source): | |
2142 | # to avoid a race we use changegroupsubset() (issue1320) |
|
2109 | # to avoid a race we use changegroupsubset() (issue1320) | |
@@ -2153,12 +2120,11 b' class localrepository(object):' | |||||
2153 |
|
2120 | |||
2154 | nodes is the set of nodes to send""" |
|
2121 | nodes is the set of nodes to send""" | |
2155 |
|
2122 | |||
2156 |
cl = |
|
2123 | cl = bundler._changelog | |
2157 |
mf = |
|
2124 | mf = bundler._manifest | |
2158 | mfs = {} |
|
2125 | mfs = {} | |
2159 | changedfiles = set() |
|
2126 | changedfiles = set() | |
2160 | fstate = [''] |
|
2127 | fstate = [''] | |
2161 | count = [0, 0] |
|
|||
2162 |
|
2128 | |||
2163 | self.hook('preoutgoing', throw=True, source=source) |
|
2129 | self.hook('preoutgoing', throw=True, source=source) | |
2164 | self.changegroupinfo(nodes, source) |
|
2130 | self.changegroupinfo(nodes, source) | |
@@ -2176,6 +2142,7 b' class localrepository(object):' | |||||
2176 | _files = _('files') |
|
2142 | _files = _('files') | |
2177 |
|
2143 | |||
2178 | def lookup(revlog, x): |
|
2144 | def lookup(revlog, x): | |
|
2145 | count = bundler.count | |||
2179 | if revlog == cl: |
|
2146 | if revlog == cl: | |
2180 | c = cl.read(x) |
|
2147 | c = cl.read(x) | |
2181 | changedfiles.update(c[3]) |
|
2148 | changedfiles.update(c[3]) | |
@@ -2195,46 +2162,19 b' class localrepository(object):' | |||||
2195 | return cl.node(revlog.linkrev(revlog.rev(x))) |
|
2162 | return cl.node(revlog.linkrev(revlog.rev(x))) | |
2196 |
|
2163 | |||
2197 | bundler.start(lookup) |
|
2164 | bundler.start(lookup) | |
2198 | reorder = self.ui.config('bundle', 'reorder', 'auto') |
|
|||
2199 | if reorder == 'auto': |
|
|||
2200 | reorder = None |
|
|||
2201 | else: |
|
|||
2202 | reorder = util.parsebool(reorder) |
|
|||
2203 |
|
||||
2204 | def gengroup(): |
|
|||
2205 | '''yield a sequence of changegroup chunks (strings)''' |
|
|||
2206 | # construct a list of all changed files |
|
|||
2207 |
|
||||
2208 | count[:] = [0, len(nodes)] |
|
|||
2209 | for chunk in bundler.group(nodes, cl, reorder=reorder): |
|
|||
2210 | yield chunk |
|
|||
2211 | progress(_bundling, None) |
|
|||
2212 |
|
||||
2213 | count[:] = [0, len(mfs)] |
|
|||
2214 | for chunk in bundler.group(gennodelst(mf), mf, reorder=reorder): |
|
|||
2215 | yield chunk |
|
|||
2216 | progress(_bundling, None) |
|
|||
2217 |
|
2165 | |||
2218 | count[:] = [0, len(changedfiles)] |
|
2166 | def getmfnodes(): | |
2219 | for fname in sorted(changedfiles): |
|
2167 | bundler.count[:] = [0, len(mfs)] | |
2220 | filerevlog = self.file(fname) |
|
2168 | return gennodelst(mf) | |
2221 | if not len(filerevlog): |
|
2169 | def getfiles(): | |
2222 | raise util.Abort(_("empty or missing revlog for %s") |
|
2170 | return changedfiles | |
2223 | % fname) |
|
2171 | def getfilenodes(fname, filerevlog): | |
2224 |
|
|
2172 | fstate[0] = fname | |
2225 |
|
|
2173 | return gennodelst(filerevlog) | |
2226 | if nodelist: |
|
|||
2227 | count[0] += 1 |
|
|||
2228 | yield bundler.fileheader(fname) |
|
|||
2229 | for chunk in bundler.group(nodelist, filerevlog, reorder): |
|
|||
2230 | yield chunk |
|
|||
2231 | yield bundler.close() |
|
|||
2232 | progress(_bundling, None) |
|
|||
2233 |
|
2174 | |||
2234 | if nodes: |
|
2175 | gengroup = bundler.generate(nodes, getmfnodes, getfiles, getfilenodes, | |
2235 | self.hook('outgoing', node=hex(nodes[0]), source=source) |
|
2176 | source) | |
2236 |
|
2177 | return changegroup.unbundle10(util.chunkbuffer(gengroup), 'UN') | ||
2237 | return changegroup.unbundle10(util.chunkbuffer(gengroup()), 'UN') |
|
|||
2238 |
|
2178 | |||
2239 | @unfilteredmethod |
|
2179 | @unfilteredmethod | |
2240 | def addchangegroup(self, source, srctype, url, emptyok=False): |
|
2180 | def addchangegroup(self, source, srctype, url, emptyok=False): |
General Comments 0
You need to be logged in to leave comments.
Login now