Mercurial > public > mercurial-scm > hg
comparison mercurial/localrepo.py @ 19202:0455fc94ae00
bundle-ng: move gengroup into bundler, pass repo object to bundler
No semantic changes made.
author | Sune Foldager <cryo@cyanite.org> |
---|---|
date | Fri, 10 May 2013 21:35:49 +0200 |
parents | 309c439cdbaa |
children | 627cd7842e5d |
comparison
equal
deleted
inserted
replaced
19201:309c439cdbaa | 19202:0455fc94ae00 |
---|---|
1842 bundlecaps = None | 1842 bundlecaps = None |
1843 # create a changegroup from local | 1843 # create a changegroup from local |
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: |
1851 cg = self.getlocalbundle('push', outgoing, bundlecaps) | 1851 cg = self.getlocalbundle('push', outgoing, bundlecaps) |
1852 | 1852 |
1990 if not bases: | 1990 if not bases: |
1991 bases = [nullid] | 1991 bases = [nullid] |
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): |
1999 """Like getbundle, but taking a discovery.outgoing as an argument. | 1999 """Like getbundle, but taking a discovery.outgoing as an argument. |
2000 | 2000 |
2001 This is only implemented for local repos and reuses potentially | 2001 This is only implemented for local repos and reuses potentially |
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, |
2009 bundler, | 2009 bundler, |
2010 source) | 2010 source) |
2031 bundlecaps=bundlecaps) | 2031 bundlecaps=bundlecaps) |
2032 | 2032 |
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 = self.changelog | 2036 cl = bundler._changelog |
2037 mf = self.manifest | 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() |
2046 if heads == sorted(self.heads()): | 2045 if heads == sorted(self.heads()): |
2047 return self._changegroup(csets, bundler, source) | 2046 return self._changegroup(csets, bundler, source) |
2061 _changesets = _('changesets') | 2060 _changesets = _('changesets') |
2062 _manifests = _('manifests') | 2061 _manifests = _('manifests') |
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]) |
2069 mfs.setdefault(c[0], x) | 2069 mfs.setdefault(c[0], x) |
2070 count[0] += 1 | 2070 count[0] += 1 |
2085 progress(_bundling, count[0], item=fstate[0], | 2085 progress(_bundling, count[0], item=fstate[0], |
2086 unit=_files, total=count[1]) | 2086 unit=_files, total=count[1]) |
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') | 2090 |
2091 if reorder == 'auto': | 2091 def getmfnodes(): |
2092 reorder = None | |
2093 else: | |
2094 reorder = util.parsebool(reorder) | |
2095 | |
2096 def gengroup(): | |
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() |
2114 | 2098 return changedfiles |
2115 # Go through all our files in order sorted by name. | 2099 def getfilenodes(fname, filerevlog): |
2116 count[:] = [0, len(changedfiles)] | 2100 fstate[0] = fname |
2117 for fname in sorted(changedfiles): | 2101 fstate[1] = fnodes.pop(fname, {}) |
2118 filerevlog = self.file(fname) | 2102 return prune(filerevlog, fstate[1]) |
2119 if not len(filerevlog): | 2103 |
2120 raise util.Abort(_("empty or missing revlog for %s") | 2104 gengroup = bundler.generate(csets, getmfnodes, getfiles, getfilenodes, |
2121 % fname) | 2105 source) |
2122 fstate[0] = fname | 2106 return changegroup.unbundle10(util.chunkbuffer(gengroup), 'UN') |
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) |
2143 return self.changegroupsubset(basenodes, self.heads(), source) | 2110 return self.changegroupsubset(basenodes, self.heads(), source) |
2144 | 2111 |
2151 This is much easier than the previous function as we can assume that | 2118 This is much easier than the previous function as we can assume that |
2152 the recipient has any changenode we aren't sending them. | 2119 the recipient has any changenode we aren't sending them. |
2153 | 2120 |
2154 nodes is the set of nodes to send""" | 2121 nodes is the set of nodes to send""" |
2155 | 2122 |
2156 cl = self.changelog | 2123 cl = bundler._changelog |
2157 mf = self.manifest | 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) |
2165 | 2131 |
2166 revset = set([cl.rev(n) for n in nodes]) | 2132 revset = set([cl.rev(n) for n in nodes]) |
2174 _changesets = _('changesets') | 2140 _changesets = _('changesets') |
2175 _manifests = _('manifests') | 2141 _manifests = _('manifests') |
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]) |
2182 mfs.setdefault(c[0], x) | 2149 mfs.setdefault(c[0], x) |
2183 count[0] += 1 | 2150 count[0] += 1 |
2193 progress(_bundling, count[0], item=fstate[0], | 2160 progress(_bundling, count[0], item=fstate[0], |
2194 total=count[1], unit=_files) | 2161 total=count[1], unit=_files) |
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') | 2165 |
2199 if reorder == 'auto': | 2166 def getmfnodes(): |
2200 reorder = None | 2167 bundler.count[:] = [0, len(mfs)] |
2201 else: | 2168 return gennodelst(mf) |
2202 reorder = util.parsebool(reorder) | 2169 def getfiles(): |
2203 | 2170 return changedfiles |
2204 def gengroup(): | 2171 def getfilenodes(fname, filerevlog): |
2205 '''yield a sequence of changegroup chunks (strings)''' | 2172 fstate[0] = fname |
2206 # construct a list of all changed files | 2173 return gennodelst(filerevlog) |
2207 | 2174 |
2208 count[:] = [0, len(nodes)] | 2175 gengroup = bundler.generate(nodes, getmfnodes, getfiles, getfilenodes, |
2209 for chunk in bundler.group(nodes, cl, reorder=reorder): | 2176 source) |
2210 yield chunk | 2177 return changegroup.unbundle10(util.chunkbuffer(gengroup), 'UN') |
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 | |
2218 count[:] = [0, len(changedfiles)] | |
2219 for fname in sorted(changedfiles): | |
2220 filerevlog = self.file(fname) | |
2221 if not len(filerevlog): | |
2222 raise util.Abort(_("empty or missing revlog for %s") | |
2223 % fname) | |
2224 fstate[0] = fname | |
2225 nodelist = 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 | |
2234 if nodes: | |
2235 self.hook('outgoing', node=hex(nodes[0]), source=source) | |
2236 | |
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): |
2241 """Add the changegroup returned by source.read() to this repo. | 2181 """Add the changegroup returned by source.read() to this repo. |
2242 srctype is a string like 'push', 'pull', or 'unbundle'. url is | 2182 srctype is a string like 'push', 'pull', or 'unbundle'. url is |