##// END OF EJS Templates
util: remove datapath and swith users over to resourceutil...
util: remove datapath and swith users over to resourceutil The util module no longer needs the datapath for injecting it into the i18n module, so we can remove it from there and update other users. Differential Revision: https://phab.mercurial-scm.org/D7436

File last commit:

r43809:313e3a27 default
r44070:5be909db default
Show More
changegroup.py
1693 lines | 56.6 KiB | text/x-python | PythonLexer
Martin Geisler
put license and copyright info into comment blocks
r8226 # changegroup.py - Mercurial changegroup manipulation functions
#
# Copyright 2006 Matt Mackall <mpm@selenic.com>
#
# This software may be used and distributed according to the terms of the
Matt Mackall
Update license to GPLv2+
r10263 # GNU General Public License version 2 or any later version.
Matt Mackall
Replace demandload with new demandimport
r3877
Gregory Szorc
changegroup: use absolute_import
r25921 from __future__ import absolute_import
import os
import struct
Pierre-Yves David
localrepo: move the addchangegroup method in changegroup module...
r20933 import weakref
Gregory Szorc
changegroup: use absolute_import
r25921
from .i18n import _
from .node import (
hex,
Gregory Szorc
changegroup: move ellipsisdata() from narrow...
r38919 nullid,
Gregory Szorc
changegroup: use absolute_import
r25921 nullrev,
short,
)
Gregory Szorc
py3: manually import pycompat.open into files that need it...
r43355 from .pycompat import open
Gregory Szorc
changegroup: use absolute_import
r25921
from . import (
error,
Gregory Szorc
changegroup: move file matcher from narrow extension...
r38830 match as matchmod,
Gregory Szorc
changegroup: use absolute_import
r25921 mdiff,
phases,
Pulkit Goyal
py3: convert the mode argument of os.fdopen to unicodes (2 of 2)
r30925 pycompat,
Pulkit Goyal
interfaces: create a new folder for interfaces and move repository.py in it...
r43078 util,
)
Augie Fackler
formatting: blacken the codebase...
r43346 from .interfaces import repository
Thomas Arendsen Hein
make incoming work via ssh (issue139); move chunk code into separate module....
r1981
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _CHANGEGROUPV1_DELTA_HEADER = struct.Struct(b"20s20s20s20s")
_CHANGEGROUPV2_DELTA_HEADER = struct.Struct(b"20s20s20s20s20s")
_CHANGEGROUPV3_DELTA_HEADER = struct.Struct(b">20s20s20s20s20sH")
Benoit Boissinot
bundler: make parsechunk return the base revision of the delta
r14141
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 LFS_REQUIREMENT = b'lfs'
Matt Harbison
lfs: move the 'supportedoutgoingversions' handling to changegroup.py...
r37150
Boris Feld
util: move 'readexactly' in the util module...
r35772 readexactly = util.readexactly
Mads Kiilerich
changegroup: verify all stream reads...
r13457
Augie Fackler
formatting: blacken the codebase...
r43346
Mads Kiilerich
changegroup: verify all stream reads...
r13457 def getchunk(stream):
"""return the next chunk from stream as a string"""
d = readexactly(stream, 4)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 l = struct.unpack(b">l", d)[0]
Thomas Arendsen Hein
make incoming work via ssh (issue139); move chunk code into separate module....
r1981 if l <= 4:
Mads Kiilerich
changegroup: don't accept odd chunk headers
r13458 if l:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b"invalid chunk length %d") % l)
return b""
Mads Kiilerich
changegroup: verify all stream reads...
r13457 return readexactly(stream, l - 4)
Thomas Arendsen Hein
make incoming work via ssh (issue139); move chunk code into separate module....
r1981
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Mackall
changegroup: avoid large copies...
r5368 def chunkheader(length):
Greg Ward
Improve some docstrings relating to changegroups and prepush().
r9437 """return a changegroup chunk header (string)"""
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return struct.pack(b">l", length + 4)
Thomas Arendsen Hein
make incoming work via ssh (issue139); move chunk code into separate module....
r1981
Augie Fackler
formatting: blacken the codebase...
r43346
Thomas Arendsen Hein
make incoming work via ssh (issue139); move chunk code into separate module....
r1981 def closechunk():
Greg Ward
Improve some docstrings relating to changegroups and prepush().
r9437 """return a changegroup chunk header (string) for a zero-length chunk"""
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return struct.pack(b">l", 0)
Thomas Arendsen Hein
make incoming work via ssh (issue139); move chunk code into separate module....
r1981
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
changegroup: pull _fileheader out of cgpacker...
r39017 def _fileheader(path):
"""Obtain a changegroup chunk header for a named path."""
return chunkheader(len(path)) + path
Augie Fackler
formatting: blacken the codebase...
r43346
Pierre-Yves David
changegroup: extract the file management part in its own function...
r26540 def writechunks(ui, chunks, filename, vfs=None):
"""Write chunks to a file and return its filename.
Matt Mackall
move write_bundle to changegroup.py
r3659
Pierre-Yves David
changegroup: extract the file management part in its own function...
r26540 The stream is assumed to be a bundle file.
Matt Mackall
move write_bundle to changegroup.py
r3659 Existing files will not be overwritten.
If no filename is specified, a temporary file is created.
"""
fh = None
cleanup = None
try:
if filename:
FUJIWARA Katsunori
changegroup: add "vfs" argument to "writebundle()" for relative access via vfs...
r20976 if vfs:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 fh = vfs.open(filename, b"wb")
FUJIWARA Katsunori
changegroup: add "vfs" argument to "writebundle()" for relative access via vfs...
r20976 else:
Gregory Szorc
changegroup: increase write buffer size to 128k...
r30212 # Increase default buffer size because default is usually
# small (4k is common on Linux).
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 fh = open(filename, b"wb", 131072)
Matt Mackall
move write_bundle to changegroup.py
r3659 else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 fd, filename = pycompat.mkstemp(prefix=b"hg-bundle-", suffix=b".hg")
Augie Fackler
cleanup: remove pointless r-prefixes on double-quoted strings...
r43809 fh = os.fdopen(fd, "wb")
Matt Mackall
move write_bundle to changegroup.py
r3659 cleanup = filename
Pierre-Yves David
changegroup: extract the file management part in its own function...
r26540 for c in chunks:
fh.write(c)
Matt Mackall
move write_bundle to changegroup.py
r3659 cleanup = None
return filename
finally:
if fh is not None:
fh.close()
if cleanup is not None:
FUJIWARA Katsunori
changegroup: add "vfs" argument to "writebundle()" for relative access via vfs...
r20976 if filename and vfs:
vfs.unlink(cleanup)
else:
os.unlink(cleanup)
Matt Mackall
create a readbundle function
r3660
Augie Fackler
formatting: blacken the codebase...
r43346
Sune Foldager
changegroup: rename bundle-related functions and classes...
r22390 class cg1unpacker(object):
Augie Fackler
changegroup: document the public surface area of cg?unpackers...
r26708 """Unpacker for cg1 changegroup streams.
A changegroup unpacker handles the framing of the revision data in
the wire format. Most consumers will want to use the apply()
method to add the changes from the changegroup to a repository.
If you're forwarding a changegroup unmodified to another consumer,
use getchunks(), which returns an iterator of changegroup
chunks. This is mostly useful for cases where you need to know the
data stream has ended by observing the end of the changegroup.
deltachunk() is useful only if you're applying delta data. Most
consumers should prefer apply() instead.
A few other public methods exist. Those are used only for
bundlerepo and some debug commands - their use is discouraged.
"""
Augie Fackler
formatting: blacken the codebase...
r43346
Sune Foldager
changegroup: rename bundle-related functions and classes...
r22390 deltaheader = _CHANGEGROUPV1_DELTA_HEADER
Gregory Szorc
changegroup: make delta header struct formatters actual structs...
r38932 deltaheadersize = deltaheader.size
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 version = b'01'
Augie Fackler
formatting: blacken the codebase...
r43346 _grouplistcount = 1 # One list of files after the manifests
Martin von Zweigbergk
changegroup: cg3 has two empty groups *after* manifests...
r27920
Gregory Szorc
bundle2: store changeset count when creating file bundles...
r29593 def __init__(self, fh, alg, extras=None):
Gregory Szorc
changegroup: use compression engines API...
r30354 if alg is None:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 alg = b'UN'
Gregory Szorc
changegroup: use compression engines API...
r30354 if alg not in util.compengines.supportedbundletypes:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b'unknown stream compression type: %s') % alg)
if alg == b'BZ':
alg = b'_truncatedBZ'
Gregory Szorc
changegroup: use compression engines API...
r30354
compengine = util.compengines.forbundletype(alg)
self._stream = compengine.decompressorreader(fh)
Matt Mackall
bundlerepo: remove duplication of bundle decompressors
r12044 self._type = alg
Gregory Szorc
bundle2: store changeset count when creating file bundles...
r29593 self.extras = extras or {}
Matt Mackall
bundle: refactor progress callback...
r12334 self.callback = None
Augie Fackler
changegroup: note why a few methods on cg1unpacker exist...
r26706
# These methods (compressed, read, seek, tell) all appear to only
# be used by bundlerepo, but it's a little hard to tell.
Matt Mackall
bundlerepo: remove duplication of bundle decompressors
r12044 def compressed(self):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return self._type is not None and self._type != b'UN'
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Mackall
bundle: introduce bundle class
r12043 def read(self, l):
return self._stream.read(l)
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Mackall
bundle: make unbundle object seekable...
r12330 def seek(self, pos):
return self._stream.seek(pos)
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Mackall
bundle: make unbundle object seekable...
r12330 def tell(self):
Matt Mackall
bundlerepo: use bundle objects everywhere
r12332 return self._stream.tell()
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Mackall
bundlerepo: restore close() method
r12347 def close(self):
return self._stream.close()
Matt Mackall
bundle: refactor progress callback...
r12334
Augie Fackler
changegroup: mark cg1unpacker.chunklength as private
r26707 def _chunklength(self):
Jim Hague
changegroup: fix typo introduced in 9f2c407caf34
r13459 d = readexactly(self._stream, 4)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 l = struct.unpack(b">l", d)[0]
Mads Kiilerich
changegroup: don't accept odd chunk headers
r13458 if l <= 4:
if l:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b"invalid chunk length %d") % l)
Mads Kiilerich
changegroup: don't accept odd chunk headers
r13458 return 0
if self.callback:
Matt Mackall
bundle: refactor progress callback...
r12334 self.callback()
Mads Kiilerich
changegroup: don't accept odd chunk headers
r13458 return l - 4
Matt Mackall
bundle: refactor progress callback...
r12334
Benoit Boissinot
unbundler: separate delta and header parsing...
r14144 def changelogheader(self):
"""v10 does not have a changelog header chunk"""
return {}
def manifestheader(self):
"""v10 does not have a manifest header chunk"""
return {}
def filelogheader(self):
"""return the header of the filelogs chunk, v10 only has the filename"""
Augie Fackler
changegroup: mark cg1unpacker.chunklength as private
r26707 l = self._chunklength()
Benoit Boissinot
unbundler: separate delta and header parsing...
r14144 if not l:
return {}
fname = readexactly(self._stream, l)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return {b'filename': fname}
Matt Mackall
bundle: refactor progress callback...
r12334
Benoit Boissinot
bundler: make parsechunk return the base revision of the delta
r14141 def _deltaheader(self, headertuple, prevnode):
node, p1, p2, cs = headertuple
if prevnode is None:
deltabase = p1
else:
deltabase = prevnode
Mike Edgar
changegroup: add flags field to cg3 delta header...
r27433 flags = 0
return node, p1, p2, deltabase, cs, flags
Benoit Boissinot
bundler: make parsechunk return the base revision of the delta
r14141
Benoit Boissinot
unbundler: separate delta and header parsing...
r14144 def deltachunk(self, prevnode):
Augie Fackler
changegroup: mark cg1unpacker.chunklength as private
r26707 l = self._chunklength()
Matt Mackall
bundle: move chunk parsing into unbundle class
r12336 if not l:
return {}
Benoit Boissinot
bundler: make parsechunk return the base revision of the delta
r14141 headerdata = readexactly(self._stream, self.deltaheadersize)
Gregory Szorc
changegroup: make delta header struct formatters actual structs...
r38932 header = self.deltaheader.unpack(headerdata)
Benoit Boissinot
bundler: make parsechunk return the base revision of the delta
r14141 delta = readexactly(self._stream, l - self.deltaheadersize)
Mike Edgar
changegroup: add flags field to cg3 delta header...
r27433 node, p1, p2, deltabase, cs, flags = self._deltaheader(header, prevnode)
Durham Goode
changegroup: remove dictionary creation from deltachunk...
r34295 return (node, p1, p2, cs, deltabase, delta, flags)
Matt Mackall
bundle: move chunk parsing into unbundle class
r12336
Pierre-Yves David
changegroup: move chunk extraction into a getchunks method of unbundle10...
r20999 def getchunks(self):
"""returns all the chunks contains in the bundle
Used when you need to forward the binary stream to a file or another
network API. To do so, it parse the changegroup data, otherwise it will
block in case of sshrepo because it don't know the end of the stream.
"""
Durham Goode
changegroup: fix to allow empty manifest parts...
r34093 # For changegroup 1 and 2, we expect 3 parts: changelog, manifestlog,
# and a list of filelogs. For changegroup 3, we expect 4 parts:
# changelog, manifestlog, a list of tree manifestlogs, and a list of
# filelogs.
#
# Changelog and manifestlog parts are terminated with empty chunks. The
# tree and file parts are a list of entry sections. Each entry section
# is a series of chunks terminating in an empty chunk. The list of these
# entry sections is terminated in yet another empty chunk, so we know
# we've reached the end of the tree/file list when we reach an empty
# chunk that was proceeded by no non-empty chunks.
parts = 0
while parts < 2 + self._grouplistcount:
noentries = True
Pierre-Yves David
changegroup: move chunk extraction into a getchunks method of unbundle10...
r20999 while True:
chunk = getchunk(self)
if not chunk:
Durham Goode
changegroup: fix to allow empty manifest parts...
r34093 # The first two empty chunks represent the end of the
# changelog and the manifestlog portions. The remaining
# empty chunks represent either A) the end of individual
# tree or file entries in the file list, or B) the end of
# the entire list. It's the end of the entire list if there
# were no entries (i.e. noentries is True).
if parts < 2:
parts += 1
elif noentries:
parts += 1
Pierre-Yves David
changegroup: move chunk extraction into a getchunks method of unbundle10...
r20999 break
Durham Goode
changegroup: fix to allow empty manifest parts...
r34093 noentries = False
Pierre-Yves David
changegroup: move chunk extraction into a getchunks method of unbundle10...
r20999 yield chunkheader(len(chunk))
pos = 0
while pos < len(chunk):
Augie Fackler
formatting: blacken the codebase...
r43346 next = pos + 2 ** 20
Pierre-Yves David
changegroup: move chunk extraction into a getchunks method of unbundle10...
r20999 yield chunk[pos:next]
pos = next
yield closechunk()
Martin von Zweigbergk
changegroup: use progress helper in apply() (API)...
r38365 def _unpackmanifests(self, repo, revmap, trp, prog):
self.callback = prog.increment
Augie Fackler
changegroup: move manifest unpacking into its own method...
r26712 # no need to check for empty manifest group here:
# if the result of the merge of 1 and 2 is the same in 3 and 4,
# no new manifest will be created and the manifest group will
# be empty during the pull
self.manifestheader()
Durham Goode
revlog: add revmap back to revlog.addgroup...
r34292 deltas = self.deltaiter()
Gregory Szorc
manifest: add getstorage() to manifestlog and use it globally...
r39280 repo.manifestlog.getstorage(b'').addgroup(deltas, revmap, trp)
Martin von Zweigbergk
progress: hide update(None) in a new complete() method...
r38392 prog.complete()
Martin von Zweigbergk
changegroup: exclude submanifests from manifest progress...
r28360 self.callback = None
Augie Fackler
changegroup: move manifest unpacking into its own method...
r26712
Augie Fackler
formatting: blacken the codebase...
r43346 def apply(
self,
repo,
tr,
srctype,
url,
targetphase=phases.draft,
expectedtotal=None,
):
Augie Fackler
changegroup: migrate addchangegroup() to forward to cg?unpacker.apply()...
r26695 """Add the changegroup returned by source.read() to this repo.
srctype is a string like 'push', 'pull', or 'unbundle'. url is
the URL of the repo where this changegroup is coming from.
Return an integer summarizing the change to this repo:
- nothing changed or no source: 0
- more heads than before: 1+added heads (2..n)
- fewer heads than before: -1-removed heads (-2..-n)
- number of heads stays the same: 1
"""
repo = repo.unfiltered()
Augie Fackler
formatting: blacken the codebase...
r43346
Augie Fackler
changegroup: migrate addchangegroup() to forward to cg?unpacker.apply()...
r26695 def csmap(x):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 repo.ui.debug(b"add changeset %s\n" % short(x))
Augie Fackler
changegroup: migrate addchangegroup() to forward to cg?unpacker.apply()...
r26695 return len(cl)
def revmap(x):
return cl.rev(x)
changegroup: move message about added changes to transaction summary...
r43167 changesets = 0
Augie Fackler
changegroup: migrate addchangegroup() to forward to cg?unpacker.apply()...
r26695
Pierre-Yves David
changegroup: fix the scope of a try finally...
r26880 try:
Martin von Zweigbergk
changegroup: delete "if True" and reflow
r32931 # The transaction may already carry source information. In this
# case we use the top level data. We overwrite the argument
# because we need to use the top level value (if they exist)
# in this function.
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 srctype = tr.hookargs.setdefault(b'source', srctype)
tr.hookargs.setdefault(b'url', url)
Augie Fackler
formatting: blacken the codebase...
r43346 repo.hook(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'prechangegroup', throw=True, **pycompat.strkwargs(tr.hookargs)
Augie Fackler
formatting: blacken the codebase...
r43346 )
Augie Fackler
changegroup: migrate addchangegroup() to forward to cg?unpacker.apply()...
r26695
Martin von Zweigbergk
changegroup: delete "if True" and reflow
r32931 # write changelog data to temp files so concurrent readers
# will not see an inconsistent view
cl = repo.changelog
cl.delayupdate(tr)
oldheads = set(cl.heads())
Augie Fackler
changegroup: migrate addchangegroup() to forward to cg?unpacker.apply()...
r26695
Martin von Zweigbergk
changegroup: delete "if True" and reflow
r32931 trp = weakref.proxy(tr)
# pull off the changeset group
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 repo.ui.status(_(b"adding changesets\n"))
Martin von Zweigbergk
changegroup: delete "if True" and reflow
r32931 clstart = len(cl)
Augie Fackler
formatting: blacken the codebase...
r43346 progress = repo.ui.makeprogress(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'changesets'), unit=_(b'chunks'), total=expectedtotal
Augie Fackler
formatting: blacken the codebase...
r43346 )
Martin von Zweigbergk
changegroup: use progress helper in apply() (API)...
r38365 self.callback = progress.increment
Augie Fackler
changegroup: migrate addchangegroup() to forward to cg?unpacker.apply()...
r26695
Augie Fackler
changegroup: avoid shadowing a set with an int...
r43790 efilesset = set()
Augie Fackler
formatting: blacken the codebase...
r43346
Martin von Zweigbergk
changegroup: delete "if True" and reflow
r32931 def onchangelog(cl, node):
Augie Fackler
changegroup: avoid shadowing a set with an int...
r43790 efilesset.update(cl.readfiles(node))
Augie Fackler
changegroup: migrate addchangegroup() to forward to cg?unpacker.apply()...
r26695
Martin von Zweigbergk
changegroup: delete "if True" and reflow
r32931 self.changelogheader()
Durham Goode
revlog: add revmap back to revlog.addgroup...
r34292 deltas = self.deltaiter()
cgnodes = cl.addgroup(deltas, csmap, trp, addrevisioncb=onchangelog)
Augie Fackler
changegroup: avoid shadowing a set with an int...
r43790 efiles = len(efilesset)
Augie Fackler
changegroup: migrate addchangegroup() to forward to cg?unpacker.apply()...
r26695
Martin von Zweigbergk
changegroup: remove option to allow empty changegroup (API)...
r33308 if not cgnodes:
Augie Fackler
formatting: blacken the codebase...
r43346 repo.ui.develwarn(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'applied empty changelog from changegroup',
config=b'warn-empty-changegroup',
Augie Fackler
formatting: blacken the codebase...
r43346 )
Martin von Zweigbergk
changegroup: delete "if True" and reflow
r32931 clend = len(cl)
changesets = clend - clstart
Martin von Zweigbergk
progress: hide update(None) in a new complete() method...
r38392 progress.complete()
Martin von Zweigbergk
changegroup: delete "if True" and reflow
r32931 self.callback = None
Augie Fackler
changegroup: migrate addchangegroup() to forward to cg?unpacker.apply()...
r26695
Martin von Zweigbergk
changegroup: delete "if True" and reflow
r32931 # pull off the manifest group
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 repo.ui.status(_(b"adding manifests\n"))
Martin von Zweigbergk
changegroup: use progress helper in apply() (API)...
r38365 # We know that we'll never have more manifests than we had
# changesets.
Augie Fackler
formatting: blacken the codebase...
r43346 progress = repo.ui.makeprogress(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'manifests'), unit=_(b'chunks'), total=changesets
Augie Fackler
formatting: blacken the codebase...
r43346 )
Martin von Zweigbergk
changegroup: use progress helper in apply() (API)...
r38365 self._unpackmanifests(repo, revmap, trp, progress)
Augie Fackler
changegroup: migrate addchangegroup() to forward to cg?unpacker.apply()...
r26695
Martin von Zweigbergk
changegroup: delete "if True" and reflow
r32931 needfiles = {}
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if repo.ui.configbool(b'server', b'validate'):
Martin von Zweigbergk
changegroup: delete "if True" and reflow
r32931 cl = repo.changelog
ml = repo.manifestlog
# validate incoming csets have their manifests
Gregory Szorc
global: use pycompat.xrange()...
r38806 for cset in pycompat.xrange(clstart, clend):
Martin von Zweigbergk
changegroup: delete "if True" and reflow
r32931 mfnode = cl.changelogrevision(cset).manifest
mfest = ml[mfnode].readdelta()
# store file cgnodes we must see
Gregory Szorc
py3: finish porting iteritems() to pycompat and remove source transformer...
r43376 for f, n in pycompat.iteritems(mfest):
Martin von Zweigbergk
changegroup: delete "if True" and reflow
r32931 needfiles.setdefault(f, set()).add(n)
Augie Fackler
changegroup: migrate addchangegroup() to forward to cg?unpacker.apply()...
r26695
Martin von Zweigbergk
changegroup: delete "if True" and reflow
r32931 # process the files
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 repo.ui.status(_(b"adding file changes\n"))
Martin von Zweigbergk
changegroup: delete "if True" and reflow
r32931 newrevs, newfiles = _addchangegroupfiles(
Augie Fackler
formatting: blacken the codebase...
r43346 repo, self, revmap, trp, efiles, needfiles
)
changegroup: move message about added changes to transaction summary...
r43167
# making sure the value exists
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 tr.changes.setdefault(b'changegroup-count-changesets', 0)
tr.changes.setdefault(b'changegroup-count-revisions', 0)
tr.changes.setdefault(b'changegroup-count-files', 0)
tr.changes.setdefault(b'changegroup-count-heads', 0)
changegroup: move message about added changes to transaction summary...
r43167
# some code use bundle operation for internal purpose. They usually
# set `ui.quiet` to do this outside of user sight. Size the report
# of such operation now happens at the end of the transaction, that
# ui.quiet has not direct effect on the output.
#
# To preserve this intend use an inelegant hack, we fail to report
# the change if `quiet` is set. We should probably move to
# something better, but this is a good first step to allow the "end
# of transaction report" to pass tests.
if not repo.ui.quiet:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 tr.changes[b'changegroup-count-changesets'] += changesets
tr.changes[b'changegroup-count-revisions'] += newrevs
tr.changes[b'changegroup-count-files'] += newfiles
Augie Fackler
changegroup: migrate addchangegroup() to forward to cg?unpacker.apply()...
r26695
Martin von Zweigbergk
changegroup: delete "if True" and reflow
r32931 deltaheads = 0
if oldheads:
heads = cl.heads()
changegroup: move message about added changes to transaction summary...
r43167 deltaheads += len(heads) - len(oldheads)
Martin von Zweigbergk
changegroup: delete "if True" and reflow
r32931 for h in heads:
if h not in oldheads and repo[h].closesbranch():
deltaheads -= 1
Augie Fackler
changegroup: migrate addchangegroup() to forward to cg?unpacker.apply()...
r26695
changegroup: move message about added changes to transaction summary...
r43167 # see previous comment about checking ui.quiet
if not repo.ui.quiet:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 tr.changes[b'changegroup-count-heads'] += deltaheads
Martin von Zweigbergk
changegroup: delete "if True" and reflow
r32931 repo.invalidatevolatilesets()
Augie Fackler
changegroup: migrate addchangegroup() to forward to cg?unpacker.apply()...
r26695
Martin von Zweigbergk
changegroup: delete "if True" and reflow
r32931 if changesets > 0:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if b'node' not in tr.hookargs:
tr.hookargs[b'node'] = hex(cl.node(clstart))
tr.hookargs[b'node_last'] = hex(cl.node(clend - 1))
Martin von Zweigbergk
changegroup: delete "if True" and reflow
r32931 hookargs = dict(tr.hookargs)
else:
hookargs = dict(tr.hookargs)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 hookargs[b'node'] = hex(cl.node(clstart))
hookargs[b'node_last'] = hex(cl.node(clend - 1))
Augie Fackler
formatting: blacken the codebase...
r43346 repo.hook(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'pretxnchangegroup',
Augie Fackler
formatting: blacken the codebase...
r43346 throw=True,
**pycompat.strkwargs(hookargs)
)
Augie Fackler
changegroup: migrate addchangegroup() to forward to cg?unpacker.apply()...
r26695
Gregory Szorc
global: use pycompat.xrange()...
r38806 added = [cl.node(r) for r in pycompat.xrange(clstart, clend)]
Boris Feld
phases: rework phase movement code in 'cg.apply' to use 'registernew'...
r33456 phaseall = None
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if srctype in (b'push', b'serve'):
Martin von Zweigbergk
changegroup: delete "if True" and reflow
r32931 # Old servers can not push the boundary themselves.
# New servers won't push the boundary if changeset already
# exists locally as secret
#
# We should not use added here but the list of all change in
# the bundle
if repo.publishing():
Boris Feld
phases: rework phase movement code in 'cg.apply' to use 'registernew'...
r33456 targetphase = phaseall = phases.public
Martin von Zweigbergk
changegroup: delete "if True" and reflow
r32931 else:
Boris Feld
phases: rework phase movement code in 'cg.apply' to use 'registernew'...
r33456 # closer target phase computation
Martin von Zweigbergk
changegroup: delete "if True" and reflow
r32931 # Those changesets have been pushed from the
# outside, their phases are going to be pushed
# alongside. Therefor `targetphase` is
# ignored.
Boris Feld
phases: rework phase movement code in 'cg.apply' to use 'registernew'...
r33456 targetphase = phaseall = phases.draft
if added:
phases.registernew(repo, tr, targetphase, added)
if phaseall is not None:
phases.advanceboundary(repo, tr, phaseall, cgnodes)
Augie Fackler
changegroup: migrate addchangegroup() to forward to cg?unpacker.apply()...
r26695
Martin von Zweigbergk
changegroup: delete "if True" and reflow
r32931 if changesets > 0:
Augie Fackler
changegroup: migrate addchangegroup() to forward to cg?unpacker.apply()...
r26695
Martin von Zweigbergk
changegroup: delete "if True" and reflow
r32931 def runhooks():
# These hooks run when the lock releases, not when the
# transaction closes. So it's possible for the changelog
# to have changed since we last saw it.
if clstart >= len(repo):
return
Augie Fackler
changegroup: migrate addchangegroup() to forward to cg?unpacker.apply()...
r26695
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 repo.hook(b"changegroup", **pycompat.strkwargs(hookargs))
Bryan O'Sullivan
with: use context manager for transaction in changegroup apply...
r27867
Martin von Zweigbergk
changegroup: delete "if True" and reflow
r32931 for n in added:
args = hookargs.copy()
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 args[b'node'] = hex(n)
del args[b'node_last']
repo.hook(b"incoming", **pycompat.strkwargs(args))
Augie Fackler
changegroup: migrate addchangegroup() to forward to cg?unpacker.apply()...
r26695
Augie Fackler
formatting: blacken the codebase...
r43346 newheads = [h for h in repo.heads() if h not in oldheads]
repo.ui.log(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b"incoming",
b"%d incoming changes - new heads: %s\n",
Augie Fackler
formatting: blacken the codebase...
r43346 len(added),
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b', '.join([hex(c[:6]) for c in newheads]),
Augie Fackler
formatting: blacken the codebase...
r43346 )
Augie Fackler
changegroup: migrate addchangegroup() to forward to cg?unpacker.apply()...
r26695
Augie Fackler
formatting: blacken the codebase...
r43346 tr.addpostclose(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'changegroup-runhooks-%020i' % clstart,
Augie Fackler
formatting: blacken the codebase...
r43346 lambda tr: repo._afterlock(runhooks),
)
Augie Fackler
changegroup: migrate addchangegroup() to forward to cg?unpacker.apply()...
r26695 finally:
repo.ui.flush()
# never return 0 here:
Martin von Zweigbergk
changegroup: rename "dh" to the clearer "deltaheads"...
r32870 if deltaheads < 0:
Martin von Zweigbergk
bundle2: record changegroup data in 'op.records' (API)...
r33030 ret = deltaheads - 1
Augie Fackler
changegroup: migrate addchangegroup() to forward to cg?unpacker.apply()...
r26695 else:
Martin von Zweigbergk
bundle2: record changegroup data in 'op.records' (API)...
r33030 ret = deltaheads + 1
Boris Feld
changegroup: stop returning and recording added nodes in 'cg.apply'...
r33461 return ret
Augie Fackler
changegroup: migrate addchangegroup() to forward to cg?unpacker.apply()...
r26695
Durham Goode
revlog: add revmap back to revlog.addgroup...
r34292 def deltaiter(self):
Durham Goode
changegroup: remove changegroup dependency from revlog.addgroup...
r34147 """
returns an iterator of the deltas in this changegroup
Useful for passing to the underlying storage system to be stored.
"""
chain = None
for chunkdata in iter(lambda: self.deltachunk(chain), {}):
Durham Goode
changegroup: remove dictionary creation from deltachunk...
r34295 # Chunkdata: (node, p1, p2, cs, deltabase, delta, flags)
yield chunkdata
chain = chunkdata[0]
Durham Goode
changegroup: remove changegroup dependency from revlog.addgroup...
r34147
Augie Fackler
formatting: blacken the codebase...
r43346
Sune Foldager
changegroup: introduce cg2packer/unpacker...
r23181 class cg2unpacker(cg1unpacker):
Augie Fackler
changegroup: document the public surface area of cg?unpackers...
r26708 """Unpacker for cg2 streams.
cg2 streams add support for generaldelta, so the delta header
format is slightly different. All other features about the data
remain the same.
"""
Augie Fackler
formatting: blacken the codebase...
r43346
Sune Foldager
changegroup: introduce cg2packer/unpacker...
r23181 deltaheader = _CHANGEGROUPV2_DELTA_HEADER
Gregory Szorc
changegroup: make delta header struct formatters actual structs...
r38932 deltaheadersize = deltaheader.size
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 version = b'02'
Sune Foldager
changegroup: introduce cg2packer/unpacker...
r23181
def _deltaheader(self, headertuple, prevnode):
node, p1, p2, deltabase, cs = headertuple
Mike Edgar
changegroup: add flags field to cg3 delta header...
r27433 flags = 0
return node, p1, p2, deltabase, cs, flags
Sune Foldager
changegroup: introduce cg2packer/unpacker...
r23181
Augie Fackler
formatting: blacken the codebase...
r43346
Augie Fackler
changegroup: introduce cg3, which has support for exchanging treemanifests...
r27432 class cg3unpacker(cg2unpacker):
"""Unpacker for cg3 streams.
Mike Edgar
changegroup: add flags field to cg3 delta header...
r27433 cg3 streams add support for exchanging treemanifests and revlog
Martin von Zweigbergk
changegroup3: add empty chunk separating directories and files...
r27753 flags. It adds the revlog flags to the delta header and an empty chunk
separating manifests and files.
Augie Fackler
changegroup: introduce cg3, which has support for exchanging treemanifests...
r27432 """
Augie Fackler
formatting: blacken the codebase...
r43346
Mike Edgar
changegroup: add flags field to cg3 delta header...
r27433 deltaheader = _CHANGEGROUPV3_DELTA_HEADER
Gregory Szorc
changegroup: make delta header struct formatters actual structs...
r38932 deltaheadersize = deltaheader.size
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 version = b'03'
Augie Fackler
formatting: blacken the codebase...
r43346 _grouplistcount = 2 # One list of manifests and one list of files
Augie Fackler
changegroup: introduce cg3, which has support for exchanging treemanifests...
r27432
Mike Edgar
changegroup: add flags field to cg3 delta header...
r27433 def _deltaheader(self, headertuple, prevnode):
node, p1, p2, deltabase, cs, flags = headertuple
return node, p1, p2, deltabase, cs, flags
Martin von Zweigbergk
changegroup: use progress helper in apply() (API)...
r38365 def _unpackmanifests(self, repo, revmap, trp, prog):
super(cg3unpacker, self)._unpackmanifests(repo, revmap, trp, prog)
Augie Fackler
changegroup: use `iter(callable, sentinel)` instead of while True...
r29724 for chunkdata in iter(self.filelogheader, {}):
Martin von Zweigbergk
changegroup3: move treemanifest support into _unpackmanifests()...
r27754 # If we get here, there are directory manifests in the changegroup
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 d = chunkdata[b"filename"]
repo.ui.debug(b"adding %s revisions\n" % d)
Durham Goode
revlog: add revmap back to revlog.addgroup...
r34292 deltas = self.deltaiter()
Gregory Szorc
manifest: add getstorage() to manifestlog and use it globally...
r39280 if not repo.manifestlog.getstorage(d).addgroup(deltas, revmap, trp):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b"received dir revlog group is empty"))
Martin von Zweigbergk
changegroup3: move treemanifest support into _unpackmanifests()...
r27754
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Mackall
bundle: push chunkbuffer down into decompress...
r12329 class headerlessfixup(object):
def __init__(self, fh, h):
self._h = h
self._fh = fh
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Mackall
bundle: push chunkbuffer down into decompress...
r12329 def read(self, n):
if self._h:
d, self._h = self._h[:n], self._h[n:]
if len(d) < n:
Mads Kiilerich
changegroup: verify all stream reads...
r13457 d += readexactly(self._fh, n - len(d))
Matt Mackall
bundle: push chunkbuffer down into decompress...
r12329 return d
Mads Kiilerich
changegroup: verify all stream reads...
r13457 return readexactly(self._fh, n)
Matt Mackall
bundle: push chunkbuffer down into decompress...
r12329
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
changegroup: emit revisiondelta instances from deltagroup()...
r39050 def _revisiondeltatochunks(delta, headerfn):
"""Serialize a revisiondelta to changegroup chunks."""
Gregory Szorc
changegroup: differentiate between fulltext and diff based deltas...
r39052
# The captured revision delta may be encoded as a delta against
# a base revision or as a full revision. The changegroup format
# requires that everything on the wire be deltas. So for full
# revisions, we need to invent a header that says to rewrite
# data.
if delta.delta is not None:
prefix, data = b'', delta.delta
elif delta.basenode == nullid:
data = delta.revision
prefix = mdiff.trivialdiffheader(len(data))
else:
data = delta.revision
Augie Fackler
formatting: blacken the codebase...
r43346 prefix = mdiff.replacediffheader(delta.baserevisionsize, len(data))
Gregory Szorc
changegroup: differentiate between fulltext and diff based deltas...
r39052
Gregory Szorc
changegroup: emit revisiondelta instances from deltagroup()...
r39050 meta = headerfn(delta)
Gregory Szorc
changegroup: differentiate between fulltext and diff based deltas...
r39052
yield chunkheader(len(meta) + len(prefix) + len(data))
Gregory Szorc
changegroup: emit revisiondelta instances from deltagroup()...
r39050 yield meta
Gregory Szorc
changegroup: differentiate between fulltext and diff based deltas...
r39052 if prefix:
yield prefix
yield data
Gregory Szorc
changegroup: emit revisiondelta instances from deltagroup()...
r39050
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
changegroup: remove _clnodetorev...
r39033 def _sortnodesellipsis(store, nodes, cl, lookup):
Gregory Szorc
changegroup: port to emitrevisions() (issue5976)...
r39901 """Sort nodes for changegroup generation."""
Gregory Szorc
changegroup: pass sorted revisions into group() (API)...
r39018 # Ellipses serving mode.
#
# In a perfect world, we'd generate better ellipsis-ified graphs
# for non-changelog revlogs. In practice, we haven't started doing
# that yet, so the resulting DAGs for the manifestlog and filelogs
# are actually full of bogus parentage on all the ellipsis
# nodes. This has the side effect that, while the contents are
# correct, the individual DAGs might be completely out of whack in
# a case like 882681bc3166 and its ancestors (back about 10
# revisions or so) in the main hg repo.
#
# The one invariant we *know* holds is that the new (potentially
# bogus) DAG shape will be valid if we order the nodes in the
# order that they're introduced in dramatis personae by the
# changelog, so what we do is we sort the non-changelog histories
# by the order in which they are used by the changelog.
Gregory Szorc
changegroup: remove _clnodetorev...
r39033 key = lambda n: cl.rev(lookup(n))
Gregory Szorc
changegroup: port to emitrevisions() (issue5976)...
r39901 return sorted(nodes, key=key)
Gregory Szorc
changegroup: pass sorted revisions into group() (API)...
r39018
Augie Fackler
formatting: blacken the codebase...
r43346
def _resolvenarrowrevisioninfo(
cl,
store,
ischangelog,
rev,
linkrev,
linknode,
clrevtolocalrev,
fullclnodes,
precomputedellipsis,
):
Gregory Szorc
changegroup: make _revisiondeltanarrow() a standalone function...
r39040 linkparents = precomputedellipsis[linkrev]
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
changegroup: make _revisiondeltanarrow() a standalone function...
r39040 def local(clrev):
"""Turn a changelog revnum into a local revnum.
The ellipsis dag is stored as revnums on the changelog,
but when we're producing ellipsis entries for
non-changelog revlogs, we need to turn those numbers into
something local. This does that for us, and during the
changelog sending phase will also expand the stored
mappings as needed.
"""
if clrev == nullrev:
return nullrev
if ischangelog:
return clrev
# Walk the ellipsis-ized changelog breadth-first looking for a
# change that has been linked from the current revlog.
#
# For a flat manifest revlog only a single step should be necessary
# as all relevant changelog entries are relevant to the flat
# manifest.
#
# For a filelog or tree manifest dirlog however not every changelog
# entry will have been relevant, so we need to skip some changelog
# nodes even after ellipsis-izing.
walk = [clrev]
while walk:
p = walk[0]
walk = walk[1:]
if p in clrevtolocalrev:
return clrevtolocalrev[p]
elif p in fullclnodes:
Augie Fackler
formatting: blacken the codebase...
r43346 walk.extend([pp for pp in cl.parentrevs(p) if pp != nullrev])
Gregory Szorc
changegroup: make _revisiondeltanarrow() a standalone function...
r39040 elif p in precomputedellipsis:
Augie Fackler
formatting: blacken the codebase...
r43346 walk.extend(
[pp for pp in precomputedellipsis[p] if pp != nullrev]
)
Gregory Szorc
changegroup: make _revisiondeltanarrow() a standalone function...
r39040 else:
# In this case, we've got an ellipsis with parents
# outside the current bundle (likely an
# incremental pull). We "know" that we can use the
# value of this same revlog at whatever revision
# is pointed to by linknode. "Know" is in scare
# quotes because I haven't done enough examination
# of edge cases to convince myself this is really
# a fact - it works for all the (admittedly
# thorough) cases in our testsuite, but I would be
# somewhat unsurprised to find a case in the wild
# where this breaks down a bit. That said, I don't
# know if it would hurt anything.
for i in pycompat.xrange(rev, 0, -1):
if store.linkrev(i) == clrev:
return i
# We failed to resolve a parent for this node, so
# we crash the changegroup construction.
raise error.Abort(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'unable to resolve parent while packing %r %r'
b' for changeset %r' % (store.indexfile, rev, clrev)
Augie Fackler
formatting: blacken the codebase...
r43346 )
Gregory Szorc
changegroup: make _revisiondeltanarrow() a standalone function...
r39040
return nullrev
Augie Fackler
formatting: blacken the codebase...
r43346 if not linkparents or (store.parentrevs(rev) == (nullrev, nullrev)):
Gregory Szorc
changegroup: make _revisiondeltanarrow() a standalone function...
r39040 p1, p2 = nullrev, nullrev
elif len(linkparents) == 1:
Augie Fackler
formatting: blacken the codebase...
r43346 (p1,) = sorted(local(p) for p in linkparents)
Gregory Szorc
changegroup: make _revisiondeltanarrow() a standalone function...
r39040 p2 = nullrev
else:
p1, p2 = sorted(local(p) for p in linkparents)
Gregory Szorc
changegroup: introduce requests to define delta generation...
r39054 p1node, p2node = store.node(p1), store.node(p2)
Gregory Szorc
changegroup: make _revisiondeltanarrow() a standalone function...
r39040
Gregory Szorc
changegroup: port to emitrevisions() (issue5976)...
r39901 return p1node, p2node, linknode
Gregory Szorc
changegroup: make _revisiondeltanarrow() a standalone function...
r39040
Augie Fackler
formatting: blacken the codebase...
r43346
def deltagroup(
repo,
store,
nodes,
ischangelog,
lookup,
forcedeltaparentprev,
topic=None,
ellipses=False,
clrevtolocalrev=None,
fullclnodes=None,
precomputedellipsis=None,
):
Gregory Szorc
changegroup: emit revisiondelta instances from deltagroup()...
r39050 """Calculate deltas for a set of revisions.
Gregory Szorc
changegroup: extract cgpacker.group() to standalone function...
r39045
Gregory Szorc
changegroup: emit revisiondelta instances from deltagroup()...
r39050 Is a generator of ``revisiondelta`` instances.
Gregory Szorc
changegroup: extract cgpacker.group() to standalone function...
r39045
Gregory Szorc
changegroup: change topics during generation...
r39275 If topic is not None, progress detail will be generated using this
topic name (e.g. changesets, manifests, etc).
Gregory Szorc
changegroup: extract cgpacker.group() to standalone function...
r39045 """
Gregory Szorc
changegroup: move node sorting into deltagroup()...
r39265 if not nodes:
Gregory Szorc
changegroup: extract cgpacker.group() to standalone function...
r39045 return
cl = repo.changelog
Gregory Szorc
changegroup: move node sorting into deltagroup()...
r39265 if ischangelog:
Gregory Szorc
changegroup: port to emitrevisions() (issue5976)...
r39901 # `hg log` shows changesets in storage order. To preserve order
# across clones, send out changesets in storage order.
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 nodesorder = b'storage'
Gregory Szorc
changegroup: move node sorting into deltagroup()...
r39265 elif ellipses:
Gregory Szorc
changegroup: port to emitrevisions() (issue5976)...
r39901 nodes = _sortnodesellipsis(store, nodes, cl, lookup)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 nodesorder = b'nodes'
Gregory Szorc
changegroup: move node sorting into deltagroup()...
r39265 else:
Gregory Szorc
changegroup: port to emitrevisions() (issue5976)...
r39901 nodesorder = None
Gregory Szorc
changegroup: move node sorting into deltagroup()...
r39265
Gregory Szorc
changegroup: port to emitrevisions() (issue5976)...
r39901 # Perform ellipses filtering and revision massaging. We do this before
# emitrevisions() because a) filtering out revisions creates less work
# for emitrevisions() b) dropping revisions would break emitrevisions()'s
# assumptions about delta choices and we would possibly send a delta
# referencing a missing base revision.
#
# Also, calling lookup() has side-effects with regards to populating
# data structures. If we don't call lookup() for each node or if we call
# lookup() after the first pass through each node, things can break -
# possibly intermittently depending on the python hash seed! For that
# reason, we store a mapping of all linknodes during the initial node
# pass rather than use lookup() on the output side.
if ellipses:
filtered = []
adjustedparents = {}
linknodes = {}
Gregory Szorc
changegroup: extract cgpacker.group() to standalone function...
r39045
Gregory Szorc
changegroup: port to emitrevisions() (issue5976)...
r39901 for node in nodes:
rev = store.rev(node)
linknode = lookup(node)
Gregory Szorc
changegroup: extract cgpacker.group() to standalone function...
r39045 linkrev = cl.rev(linknode)
Gregory Szorc
changegroup: port to emitrevisions() (issue5976)...
r39901 clrevtolocalrev[linkrev] = rev
Gregory Szorc
changegroup: extract cgpacker.group() to standalone function...
r39045
Gregory Szorc
changegroup: port to emitrevisions() (issue5976)...
r39901 # If linknode is in fullclnodes, it means the corresponding
# changeset was a full changeset and is being sent unaltered.
Gregory Szorc
changegroup: extract cgpacker.group() to standalone function...
r39045 if linknode in fullclnodes:
Gregory Szorc
changegroup: port to emitrevisions() (issue5976)...
r39901 linknodes[node] = linknode
Gregory Szorc
changegroup: introduce requests to define delta generation...
r39054
Gregory Szorc
changegroup: port to emitrevisions() (issue5976)...
r39901 # If the corresponding changeset wasn't in the set computed
# as relevant to us, it should be dropped outright.
Gregory Szorc
changegroup: extract cgpacker.group() to standalone function...
r39045 elif linkrev not in precomputedellipsis:
Gregory Szorc
changegroup: port to emitrevisions() (issue5976)...
r39901 continue
Gregory Szorc
changegroup: extract cgpacker.group() to standalone function...
r39045 else:
Gregory Szorc
changegroup: port to emitrevisions() (issue5976)...
r39901 # We could probably do this later and avoid the dict
# holding state. But it likely doesn't matter.
p1node, p2node, linknode = _resolvenarrowrevisioninfo(
Augie Fackler
formatting: blacken the codebase...
r43346 cl,
store,
ischangelog,
rev,
linkrev,
linknode,
clrevtolocalrev,
fullclnodes,
precomputedellipsis,
)
Gregory Szorc
changegroup: port to emitrevisions() (issue5976)...
r39901
adjustedparents[node] = (p1node, p2node)
linknodes[node] = linknode
filtered.append(node)
nodes = filtered
Gregory Szorc
changegroup: extract cgpacker.group() to standalone function...
r39045
Gregory Szorc
changegroup: introduce requests to define delta generation...
r39054 # We expect the first pass to be fast, so we only engage the progress
# meter for constructing the revision deltas.
progress = None
Gregory Szorc
changegroup: change topics during generation...
r39275 if topic is not None:
Augie Fackler
formatting: blacken the codebase...
r43346 progress = repo.ui.makeprogress(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 topic, unit=_(b'chunks'), total=len(nodes)
Augie Fackler
formatting: blacken the codebase...
r43346 )
Gregory Szorc
changegroup: introduce requests to define delta generation...
r39054
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 configtarget = repo.ui.config(b'devel', b'bundle.delta')
if configtarget not in (b'', b'p1', b'full'):
Boris Feld
changegroup: allow to force delta to be against p1...
r40458 msg = _("""config "devel.bundle.delta" as unknown value: %s""")
repo.ui.warn(msg % configtarget)
Boris Feld
storage: also use `deltamode argument` for ifiledata...
r40457 deltamode = repository.CG_DELTAMODE_STD
if forcedeltaparentprev:
deltamode = repository.CG_DELTAMODE_PREV
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 elif configtarget == b'p1':
Boris Feld
changegroup: allow to force delta to be against p1...
r40458 deltamode = repository.CG_DELTAMODE_P1
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 elif configtarget == b'full':
Boris Feld
changegroup: add a option to create bundle with full snapshot only...
r40459 deltamode = repository.CG_DELTAMODE_FULL
Boris Feld
storage: also use `deltamode argument` for ifiledata...
r40457
Gregory Szorc
changegroup: port to emitrevisions() (issue5976)...
r39901 revisions = store.emitrevisions(
nodes,
nodesorder=nodesorder,
revisiondata=True,
assumehaveparentrevisions=not ellipses,
Augie Fackler
formatting: blacken the codebase...
r43346 deltamode=deltamode,
)
Gregory Szorc
changegroup: port to emitrevisions() (issue5976)...
r39901
for i, revision in enumerate(revisions):
Gregory Szorc
changegroup: introduce requests to define delta generation...
r39054 if progress:
progress.update(i + 1)
Gregory Szorc
changegroup: port to emitrevisions() (issue5976)...
r39901 if ellipses:
linknode = linknodes[revision.node]
if revision.node in adjustedparents:
p1node, p2node = adjustedparents[revision.node]
revision.p1node = p1node
revision.p2node = p2node
Gregory Szorc
repository: define and use revision flag constants...
r40083 revision.flags |= repository.REVISION_FLAG_ELLIPSIS
Gregory Szorc
changegroup: port to emitrevisions() (issue5976)...
r39901
else:
linknode = lookup(revision.node)
revision.linknode = linknode
yield revision
Gregory Szorc
changegroup: introduce requests to define delta generation...
r39054
Gregory Szorc
changegroup: extract cgpacker.group() to standalone function...
r39045 if progress:
progress.complete()
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
changegroup: rename cg1packer to cgpacker...
r38938 class cgpacker(object):
Augie Fackler
formatting: blacken the codebase...
r43346 def __init__(
self,
repo,
oldmatcher,
matcher,
version,
builddeltaheader,
manifestsend,
forcedeltaparentprev=False,
bundlecaps=None,
ellipses=False,
shallow=False,
ellipsisroots=None,
fullnodes=None,
):
Sune Foldager
bundle-ng: move gengroup into bundler, pass repo object to bundler...
r19202 """Given a source repo, construct a bundler.
Durham Goode
changegroup: add bundlecaps back...
r32287
Martin von Zweigbergk
narrow: when widening, don't include manifests the client already has...
r40380 oldmatcher is a matcher that matches on files the client already has.
These will not be included in the changegroup.
matcher is a matcher that matches on files to include in the
Gregory Szorc
changegroup: move file matcher from narrow extension...
r38830 changegroup. Used to facilitate sparse changegroups.
Gregory Szorc
changegroup: refactor delta parent code...
r39053 forcedeltaparentprev indicates whether delta parents must be against
the previous revision in a delta group. This should only be used for
compatibility with changegroup version 1.
Gregory Szorc
changegroup: control delta parent behavior via constructor...
r38937
Gregory Szorc
changegroup: pass function to build delta header into constructor...
r38933 builddeltaheader is a callable that constructs the header for a group
delta.
Gregory Szorc
changegroup: pass end of manifests marker into constructor...
r38934 manifestsend is a chunk to send after manifests have been fully emitted.
Gregory Szorc
changegroup: specify ellipses mode explicitly...
r38944 ellipses indicates whether ellipsis serving mode is enabled.
Durham Goode
changegroup: add bundlecaps back...
r32287 bundlecaps is optional and can be used to specify the set of
capabilities which can be used to build the bundle. While bundlecaps is
unused in core Mercurial, extensions rely on this feature to communicate
capabilities to customize the changegroup packer.
Gregory Szorc
changegroup: declare shallow flag in constructor...
r38940
shallow indicates whether shallow data might be sent. The packer may
need to pack file contents not introduced by the changes being packed.
Gregory Szorc
changegroup: move fullnodes into cgpacker...
r38945
Gregory Szorc
changegroup: rename _fullnodes to _fullclnodes...
r39032 fullnodes is the set of changelog nodes which should not be ellipsis
nodes. We store this rather than the set of nodes that should be
ellipsis because for very large histories we expect this to be
significantly smaller.
Sune Foldager
bundle-ng: move gengroup into bundler, pass repo object to bundler...
r19202 """
Martin von Zweigbergk
narrow: when widening, don't include manifests the client already has...
r40380 assert oldmatcher
assert matcher
self._oldmatcher = oldmatcher
self._matcher = matcher
Gregory Szorc
changegroup: move file matcher from narrow extension...
r38830
Gregory Szorc
changegroup: pass version into constructor...
r38931 self.version = version
Gregory Szorc
changegroup: refactor delta parent code...
r39053 self._forcedeltaparentprev = forcedeltaparentprev
Gregory Szorc
changegroup: pass function to build delta header into constructor...
r38933 self._builddeltaheader = builddeltaheader
Gregory Szorc
changegroup: pass end of manifests marker into constructor...
r38934 self._manifestsend = manifestsend
Gregory Szorc
changegroup: specify ellipses mode explicitly...
r38944 self._ellipses = ellipses
Gregory Szorc
changegroup: pass version into constructor...
r38931
Durham Goode
changegroup: add bundlecaps back...
r32287 # Set of capabilities we can use to build the bundle.
if bundlecaps is None:
bundlecaps = set()
self._bundlecaps = bundlecaps
Gregory Szorc
changegroup: declare shallow flag in constructor...
r38940 self._isshallow = shallow
Gregory Szorc
changegroup: rename _fullnodes to _fullclnodes...
r39032 self._fullclnodes = fullnodes
Gregory Szorc
changegroup: control reordering via constructor argument...
r38936
Gregory Szorc
changegroup: pass ellipsis roots into cgpacker constructor...
r38943 # Maps ellipsis revs to their roots at the changelog level.
self._precomputedellipsis = ellipsisroots
Sune Foldager
bundle-ng: move gengroup into bundler, pass repo object to bundler...
r19202 self._repo = repo
Gregory Szorc
changegroup: control reordering via constructor argument...
r38936
Mads Kiilerich
bundle: when verbose, show what takes up the space in the generated bundle...
r23748 if self._repo.ui.verbose and not self._repo.ui.debugflag:
self._verbosenote = self._repo.ui.note
else:
self._verbosenote = lambda s: None
Augie Fackler
formatting: blacken the codebase...
r43346 def generate(
self, commonrevs, clnodes, fastpathlinkrev, source, changelog=True
):
Pulkit Goyal
changegroup: add functionality to skip adding changelog data to changegroup...
r39708 """Yield a sequence of changegroup byte chunks.
If changelog is False, changelog data won't be added to changegroup
"""
Gregory Szorc
changegroup: factor changelog chunk generation into own function...
r39012
Sune Foldager
bundle-ng: move gengroup into bundler, pass repo object to bundler...
r19202 repo = self._repo
Martin von Zweigbergk
changegroup: drop _changelog and _manifest properties...
r24978 cl = repo.changelog
Benoit Boissinot
bundle-ng: move bundle generation to changegroup.py
r19204
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self._verbosenote(_(b'uncompressed size of bundle content:\n'))
Gregory Szorc
changegroup: factor changelog chunk generation into own function...
r39012 size = 0
Augie Fackler
formatting: blacken the codebase...
r43346 clstate, deltas = self._generatechangelog(
cl, clnodes, generate=changelog
)
Gregory Szorc
changegroup: emit revisiondelta instances from deltagroup()...
r39050 for delta in deltas:
Augie Fackler
formatting: blacken the codebase...
r43346 for chunk in _revisiondeltatochunks(delta, self._builddeltaheader):
Pulkit Goyal
changegroup: don't try to build changelog chunks if not required...
r41491 size += len(chunk)
yield chunk
Gregory Szorc
changegroup: factor changelog chunk generation into own function...
r39012
Gregory Szorc
changegroup: emit delta group close chunk outside of deltagroup()...
r39046 close = closechunk()
size += len(close)
yield closechunk()
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self._verbosenote(_(b'%8.i (changelog)\n') % size)
Gregory Szorc
changegroup: factor changelog chunk generation into own function...
r39012
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 clrevorder = clstate[b'clrevorder']
manifests = clstate[b'manifests']
changedfiles = clstate[b'changedfiles']
Gregory Szorc
changegroup: factor changelog chunk generation into own function...
r39012
# We need to make sure that the linkrev in the changegroup refers to
# the first changeset that introduced the manifest or file revision.
# The fastpath is usually safer than the slowpath, because the filelogs
# are walked in revlog order.
#
Gregory Szorc
changegroup: remove reordering control (BC)...
r39897 # When taking the slowpath when the manifest revlog uses generaldelta,
# the manifest may be walked in the "wrong" order. Without 'clrevorder',
# we would get an incorrect linkrev (see fix in cc0ff93d0c0c).
Gregory Szorc
changegroup: factor changelog chunk generation into own function...
r39012 #
# When taking the fastpath, we are only vulnerable to reordering
Gregory Szorc
changegroup: remove reordering control (BC)...
r39897 # of the changelog itself. The changelog never uses generaldelta and is
# never reordered. To handle this case, we simply take the slowpath,
# which already has the 'clrevorder' logic. This was also fixed in
# cc0ff93d0c0c.
Gregory Szorc
changegroup: factor changelog chunk generation into own function...
r39012 # Treemanifests don't work correctly with fastpathlinkrev
# either, because we don't discover which directory nodes to
# send along with files. This could probably be fixed.
fastpathlinkrev = fastpathlinkrev and (
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'treemanifest' not in repo.requirements
Augie Fackler
formatting: blacken the codebase...
r43346 )
Gregory Szorc
changegroup: factor changelog chunk generation into own function...
r39012
fnodes = {} # needed file nodes
Gregory Szorc
changegroup: move size tracking and end of manifests to generate()...
r39047 size = 0
Gregory Szorc
changegroup: move manifest chunk emission to generate()...
r39048 it = self.generatemanifests(
Augie Fackler
formatting: blacken the codebase...
r43346 commonrevs,
clrevorder,
fastpathlinkrev,
manifests,
fnodes,
source,
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 clstate[b'clrevtomanifestrev'],
Augie Fackler
formatting: blacken the codebase...
r43346 )
Gregory Szorc
changegroup: move manifest chunk emission to generate()...
r39048
Gregory Szorc
changegroup: rename dir to tree to avoid shadowing a built-in...
r39269 for tree, deltas in it:
if tree:
Gregory Szorc
changegroup: move manifest chunk emission to generate()...
r39048 assert self.version == b'03'
Gregory Szorc
changegroup: rename dir to tree to avoid shadowing a built-in...
r39269 chunk = _fileheader(tree)
Gregory Szorc
changegroup: move manifest chunk emission to generate()...
r39048 size += len(chunk)
yield chunk
Gregory Szorc
changegroup: emit revisiondelta instances from deltagroup()...
r39050 for delta in deltas:
chunks = _revisiondeltatochunks(delta, self._builddeltaheader)
for chunk in chunks:
size += len(chunk)
yield chunk
Gregory Szorc
changegroup: move manifest chunk emission to generate()...
r39048
close = closechunk()
size += len(close)
yield close
Gregory Szorc
changegroup: factor changelog chunk generation into own function...
r39012
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self._verbosenote(_(b'%8.i (manifests)\n') % size)
Gregory Szorc
changegroup: move size tracking and end of manifests to generate()...
r39047 yield self._manifestsend
Gregory Szorc
changegroup: pass mfdicts properly...
r39019 mfdicts = None
if self._ellipses and self._isshallow:
Augie Fackler
formatting: blacken the codebase...
r43346 mfdicts = [
(self._repo.manifestlog[n].read(), lr)
Gregory Szorc
py3: finish porting iteritems() to pycompat and remove source transformer...
r43376 for (n, lr) in pycompat.iteritems(manifests)
Augie Fackler
formatting: blacken the codebase...
r43346 ]
Gregory Szorc
changegroup: factor changelog chunk generation into own function...
r39012
Gregory Szorc
changegroup: rename mfs to manifests...
r39274 manifests.clear()
Gregory Szorc
changegroup: factor changelog chunk generation into own function...
r39012 clrevs = set(cl.rev(x) for x in clnodes)
Augie Fackler
formatting: blacken the codebase...
r43346 it = self.generatefiles(
changedfiles,
commonrevs,
source,
mfdicts,
fastpathlinkrev,
fnodes,
clrevs,
)
Gregory Szorc
changegroup: move file chunk emission to generate()...
r39049
Gregory Szorc
changegroup: emit revisiondelta instances from deltagroup()...
r39050 for path, deltas in it:
Gregory Szorc
changegroup: move file chunk emission to generate()...
r39049 h = _fileheader(path)
size = len(h)
yield h
Gregory Szorc
changegroup: emit revisiondelta instances from deltagroup()...
r39050 for delta in deltas:
chunks = _revisiondeltatochunks(delta, self._builddeltaheader)
for chunk in chunks:
size += len(chunk)
yield chunk
Gregory Szorc
changegroup: move file chunk emission to generate()...
r39049
close = closechunk()
size += len(close)
yield close
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self._verbosenote(_(b'%8.i %s\n') % (size, path))
Gregory Szorc
changegroup: factor changelog chunk generation into own function...
r39012
Gregory Szorc
changegroup: inline _close()...
r39038 yield closechunk()
Gregory Szorc
changegroup: factor changelog chunk generation into own function...
r39012
if clnodes:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 repo.hook(b'outgoing', node=hex(clnodes[0]), source=source)
Gregory Szorc
changegroup: factor changelog chunk generation into own function...
r39012
Pulkit Goyal
changegroup: don't try to build changelog chunks if not required...
r41491 def _generatechangelog(self, cl, nodes, generate=True):
Gregory Szorc
changegroup: factor changelog chunk generation into own function...
r39012 """Generate data for changelog chunks.
Returns a 2-tuple of a dict containing state and an iterable of
byte chunks. The state will not be fully populated until the
chunk stream has been fully consumed.
Pulkit Goyal
changegroup: don't try to build changelog chunks if not required...
r41491
if generate is False, the state will be fully populated and no chunk
stream will be yielded
Gregory Szorc
changegroup: factor changelog chunk generation into own function...
r39012 """
Durham Goode
changegroup: fix file linkrevs during reorders (issue4462)...
r23381 clrevorder = {}
Gregory Szorc
changegroup: rename mfs to manifests...
r39274 manifests = {}
Gregory Szorc
changegroup: factor changelog chunk generation into own function...
r39012 mfl = self._repo.manifestlog
Martin von Zweigbergk
changegroup: drop special-casing of flat manifests...
r28241 changedfiles = set()
Gregory Szorc
changegroup: track changelog to manifest revision map explicitly...
r39034 clrevtomanifestrev = {}
Benoit Boissinot
bundle-ng: move bundle generation to changegroup.py
r19204
Pulkit Goyal
changegroup: initialize the state variable a bit earlier...
r41490 state = {
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'clrevorder': clrevorder,
b'manifests': manifests,
b'changedfiles': changedfiles,
b'clrevtomanifestrev': clrevtomanifestrev,
Pulkit Goyal
changegroup: initialize the state variable a bit earlier...
r41490 }
Pulkit Goyal
changegroup: don't try to build changelog chunks if not required...
r41491 if not (generate or self._ellipses):
# sort the nodes in storage order
nodes = sorted(nodes, key=cl.rev)
for node in nodes:
c = cl.changelogrevision(node)
clrevorder[node] = len(clrevorder)
# record the first changeset introducing this manifest version
manifests.setdefault(c.manifest, node)
# Record a complete list of potentially-changed files in
# this manifest.
changedfiles.update(c.files)
return state, ()
Gregory Szorc
changegroup: move generate() modifications from narrow...
r38926 # Callback for the changelog, used to collect changed files and
# manifest nodes.
Benoit Boissinot
bundle-ng: simplify lookup and state handling...
r19207 # Returns the linkrev node (identity in the changelog case).
def lookupcl(x):
Gregory Szorc
changegroup: clean up changelog callback...
r39273 c = cl.changelogrevision(x)
Durham Goode
changegroup: fix file linkrevs during reorders (issue4462)...
r23381 clrevorder[x] = len(clrevorder)
Gregory Szorc
changegroup: move generate() modifications from narrow...
r38926
Gregory Szorc
changegroup: specify ellipses mode explicitly...
r38944 if self._ellipses:
Gregory Szorc
changegroup: rename mfs to manifests...
r39274 # Only update manifests if x is going to be sent. Otherwise we
Gregory Szorc
changegroup: move generate() modifications from narrow...
r38926 # end up with bogus linkrevs specified for manifests and
# we skip some manifest nodes that we should otherwise
# have sent.
Augie Fackler
formatting: blacken the codebase...
r43346 if (
x in self._fullclnodes
or cl.rev(x) in self._precomputedellipsis
):
Gregory Szorc
changegroup: clean up changelog callback...
r39273
manifestnode = c.manifest
Gregory Szorc
changegroup: move generate() modifications from narrow...
r38926 # Record the first changeset introducing this manifest
# version.
Gregory Szorc
changegroup: rename mfs to manifests...
r39274 manifests.setdefault(manifestnode, x)
Gregory Szorc
changegroup: move generate() modifications from narrow...
r38926 # Set this narrow-specific dict so we have the lowest
# manifest revnum to look up for this cl revnum. (Part of
# mapping changelog ellipsis parents to manifest ellipsis
# parents)
Gregory Szorc
changegroup: clean up changelog callback...
r39273 clrevtomanifestrev.setdefault(
Augie Fackler
formatting: blacken the codebase...
r43346 cl.rev(x), mfl.rev(manifestnode)
)
Gregory Szorc
changegroup: move generate() modifications from narrow...
r38926 # We can't trust the changed files list in the changeset if the
# client requested a shallow clone.
Gregory Szorc
changegroup: declare shallow flag in constructor...
r38940 if self._isshallow:
Gregory Szorc
changegroup: clean up changelog callback...
r39273 changedfiles.update(mfl[c.manifest].read().keys())
Gregory Szorc
changegroup: move generate() modifications from narrow...
r38926 else:
Gregory Szorc
changegroup: clean up changelog callback...
r39273 changedfiles.update(c.files)
Gregory Szorc
changegroup: move generate() modifications from narrow...
r38926 else:
# record the first changeset introducing this manifest version
Gregory Szorc
changegroup: rename mfs to manifests...
r39274 manifests.setdefault(c.manifest, x)
Gregory Szorc
changegroup: move generate() modifications from narrow...
r38926 # Record a complete list of potentially-changed files in
# this manifest.
Gregory Szorc
changegroup: clean up changelog callback...
r39273 changedfiles.update(c.files)
Gregory Szorc
changegroup: move generate() modifications from narrow...
r38926
Benoit Boissinot
bundle-ng: simplify lookup and state handling...
r19207 return x
Benoit Boissinot
bundle-ng: move bundle generation to changegroup.py
r19204
Gregory Szorc
changegroup: extract cgpacker.group() to standalone function...
r39045 gen = deltagroup(
Augie Fackler
formatting: blacken the codebase...
r43346 self._repo,
cl,
nodes,
True,
lookupcl,
Gregory Szorc
changegroup: refactor delta parent code...
r39053 self._forcedeltaparentprev,
Gregory Szorc
changegroup: extract cgpacker.group() to standalone function...
r39045 ellipses=self._ellipses,
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 topic=_(b'changesets'),
Gregory Szorc
changegroup: extract cgpacker.group() to standalone function...
r39045 clrevtolocalrev={},
fullclnodes=self._fullclnodes,
Augie Fackler
formatting: blacken the codebase...
r43346 precomputedellipsis=self._precomputedellipsis,
)
Martin von Zweigbergk
changegroup: extract generatemanifests()...
r28227
Gregory Szorc
changegroup: factor changelog chunk generation into own function...
r39012 return state, gen
Martin von Zweigbergk
changegroup: extract generatemanifests()...
r28227
Augie Fackler
formatting: blacken the codebase...
r43346 def generatemanifests(
self,
commonrevs,
clrevorder,
fastpathlinkrev,
manifests,
fnodes,
source,
clrevtolocalrev,
):
Durham Goode
changegroup: add source parameter to generatemanifests...
r34148 """Returns an iterator of changegroup chunks containing manifests.
`source` is unused here, but is used by extensions like remotefilelog to
change what is sent based in pulls vs pushes, etc.
"""
Martin von Zweigbergk
changegroup: extract generatemanifests()...
r28227 repo = self._repo
Durham Goode
manifest: get rid of manifest.readshallowfast...
r30294 mfl = repo.manifestlog
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 tmfnodes = {b'': manifests}
Martin von Zweigbergk
changegroup: extract generatemanifests()...
r28227
Benoit Boissinot
bundle-ng: simplify lookup and state handling...
r19207 # Callback for the manifest, used to collect linkrevs for filelog
# revisions.
# Returns the linkrev node (collected in lookupcl).
Gregory Szorc
changegroup: rename dir to tree to avoid shadowing a built-in...
r39269 def makelookupmflinknode(tree, nodes):
Martin von Zweigbergk
changegroup: introduce makelookupmflinknode(dir)...
r28231 if fastpathlinkrev:
Gregory Szorc
changegroup: rename dir to tree to avoid shadowing a built-in...
r39269 assert not tree
Augie Fackler
changegroup: suppress pytype error that's wrong...
r43791 return (
manifests.__getitem__ # pytype: disable=unsupported-operands
)
Martin von Zweigbergk
changegroup: introduce makelookupmflinknode(dir)...
r28231
Augie Fackler
changegroup: remove one special case from lookupmflinknode...
r27239 def lookupmflinknode(x):
"""Callback for looking up the linknode for manifests.
Augie Fackler
changegroup: document manifest linkrev callback some more...
r27219
Augie Fackler
changegroup: remove one special case from lookupmflinknode...
r27239 Returns the linkrev node for the specified manifest.
Augie Fackler
changegroup: document manifest linkrev callback some more...
r27219
Augie Fackler
changegroup: remove one special case from lookupmflinknode...
r27239 SIDE EFFECT:
Augie Fackler
changegroup: introduce cg3, which has support for exchanging treemanifests...
r27432 1) fclnodes gets populated with the list of relevant
file nodes if we're not using fastpathlinkrev
2) When treemanifests are in use, collects treemanifest nodes
to send
Augie Fackler
changegroup: document manifest linkrev callback some more...
r27219
Augie Fackler
changegroup: introduce cg3, which has support for exchanging treemanifests...
r27432 Note that this means manifests must be completely sent to
the client before you can trust the list of files and
treemanifests to send.
Augie Fackler
changegroup: remove one special case from lookupmflinknode...
r27239 """
Kyle Lippincott
changegroup: use any node, not min(), in treemanifest's generatemanifests...
r35013 clnode = nodes[x]
Gregory Szorc
changegroup: rename dir to tree to avoid shadowing a built-in...
r39269 mdata = mfl.get(tree, x).readfast(shallow=True)
Martin von Zweigbergk
changegroup: drop special-casing of flat manifests...
r28241 for p, n, fl in mdata.iterentries():
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if fl == b't': # subdirectory manifest
subtree = tree + p + b'/'
Gregory Szorc
changegroup: rename dir to tree to avoid shadowing a built-in...
r39269 tmfclnodes = tmfnodes.setdefault(subtree, {})
Martin von Zweigbergk
changegroup: drop special-casing of flat manifests...
r28241 tmfclnode = tmfclnodes.setdefault(n, clnode)
if clrevorder[clnode] < clrevorder[tmfclnode]:
tmfclnodes[n] = clnode
else:
Gregory Szorc
changegroup: rename dir to tree to avoid shadowing a built-in...
r39269 f = tree + p
Martin von Zweigbergk
changegroup: fix treemanifests on merges...
r28240 fclnodes = fnodes.setdefault(f, {})
fclnode = fclnodes.setdefault(n, clnode)
if clrevorder[clnode] < clrevorder[fclnode]:
fclnodes[n] = clnode
Augie Fackler
changegroup: remove one special case from lookupmflinknode...
r27239 return clnode
Augie Fackler
formatting: blacken the codebase...
r43346
Martin von Zweigbergk
changegroup: introduce makelookupmflinknode(dir)...
r28231 return lookupmflinknode
Sune Foldager
bundle-ng: simplify bundle10.generate...
r19206
Martin von Zweigbergk
changegroup: write root manifests and subdir manifests in a single loop...
r28232 while tmfnodes:
Gregory Szorc
changegroup: rename dir to tree to avoid shadowing a built-in...
r39269 tree, nodes = tmfnodes.popitem()
Kyle Lippincott
changegroup: avoid instantiating storage if we are not using it...
r40700
Martin von Zweigbergk
match: use '' instead of '.' for root directory (API)...
r42528 should_visit = self._matcher.visitdir(tree[:-1])
Kyle Lippincott
changegroup: avoid instantiating storage if we are not using it...
r40700 if tree and not should_visit:
continue
Gregory Szorc
manifest: add getstorage() to manifestlog and use it globally...
r39280 store = mfl.getstorage(tree)
Gregory Szorc
changegroup: inline _prune() into call sites...
r39043
Kyle Lippincott
changegroup: avoid instantiating storage if we are not using it...
r40700 if not should_visit:
Augie Fackler
changegroup: reintroduce some comments that have gotten lost over the years...
r39769 # No nodes to send because this directory is out of
# the client's view of the repository (probably
Kyle Lippincott
changegroup: avoid instantiating storage if we are not using it...
r40700 # because of narrow clones). Do this even for the root
# directory (tree=='')
Gregory Szorc
changegroup: inline _prune() into call sites...
r39043 prunednodes = []
else:
Augie Fackler
changegroup: reintroduce some comments that have gotten lost over the years...
r39769 # Avoid sending any manifest nodes we can prove the
# client already has by checking linkrevs. See the
# related comment in generatefiles().
Augie Fackler
changegroup: tease out a temporary prune method for manifests...
r39768 prunednodes = self._prunemanifests(store, nodes, commonrevs)
Kyle Lippincott
changegroup: avoid instantiating storage if we are not using it...
r40700
Gregory Szorc
changegroup: rename dir to tree to avoid shadowing a built-in...
r39269 if tree and not prunednodes:
Gregory Szorc
changegroup: invert conditional and dedent...
r39041 continue
Gregory Szorc
changegroup: rename dir to tree to avoid shadowing a built-in...
r39269 lookupfn = makelookupmflinknode(tree, nodes)
Gregory Szorc
changegroup: pass sorted revisions into group() (API)...
r39018
Gregory Szorc
changegroup: emit revisiondelta instances from deltagroup()...
r39050 deltas = deltagroup(
Augie Fackler
formatting: blacken the codebase...
r43346 self._repo,
store,
prunednodes,
False,
lookupfn,
Gregory Szorc
changegroup: remove reordering control (BC)...
r39897 self._forcedeltaparentprev,
Gregory Szorc
changegroup: pass all state into group()...
r39044 ellipses=self._ellipses,
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 topic=_(b'manifests'),
Gregory Szorc
changegroup: pass all state into group()...
r39044 clrevtolocalrev=clrevtolocalrev,
fullclnodes=self._fullclnodes,
Augie Fackler
formatting: blacken the codebase...
r43346 precomputedellipsis=self._precomputedellipsis,
)
Gregory Szorc
changegroup: pass all state into group()...
r39044
Martin von Zweigbergk
match: use '' instead of '.' for root directory (API)...
r42528 if not self._oldmatcher.visitdir(store.tree[:-1]):
Martin von Zweigbergk
narrow: when widening, don't include manifests the client already has...
r40380 yield tree, deltas
else:
# 'deltas' is a generator and we need to consume it even if
# we are not going to send it because a side-effect is that
# it updates tmdnodes (via lookupfn)
for d in deltas:
pass
if not tree:
yield tree, []
Gregory Szorc
changegroup: emit delta group close chunk outside of deltagroup()...
r39046
Augie Fackler
changegroup: tease out a temporary prune method for manifests...
r39768 def _prunemanifests(self, store, nodes, commonrevs):
Martin von Zweigbergk
changegroup: move non-pruning of non-ellipsis manifests to _prunemanifests()...
r41933 if not self._ellipses:
# In non-ellipses case and large repositories, it is better to
# prevent calling of store.rev and store.linkrev on a lot of
# nodes as compared to sending some extra data
return nodes.copy()
Augie Fackler
changegroup: tease out a temporary prune method for manifests...
r39768 # This is split out as a separate method to allow filtering
# commonrevs in extension code.
#
# TODO(augie): this shouldn't be required, instead we should
# make filtering of revisions to send delegated to the store
# layer.
frev, flr = store.rev, store.linkrev
return [n for n in nodes if flr(frev(n)) not in commonrevs]
Martin von Zweigbergk
changegroup: document that 'source' parameter exists for extensions...
r24897 # The 'source' parameter is useful for extensions
Augie Fackler
formatting: blacken the codebase...
r43346 def generatefiles(
self,
changedfiles,
commonrevs,
source,
mfdicts,
fastpathlinkrev,
fnodes,
clrevs,
):
changedfiles = [
f
for f in changedfiles
if self._matcher(f) and not self._oldmatcher(f)
]
Gregory Szorc
changegroup: move generatefiles() from narrow...
r38925
Gregory Szorc
changegroup: define linknodes callbacks in generatefiles()...
r39035 if not fastpathlinkrev:
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
changegroup: define linknodes callbacks in generatefiles()...
r39035 def normallinknodes(unused, fname):
return fnodes.get(fname, {})
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
changegroup: define linknodes callbacks in generatefiles()...
r39035 else:
cln = self._repo.changelog.node
def normallinknodes(store, fname):
flinkrev = store.linkrev
fnode = store.node
revs = ((r, flinkrev(r)) for r in store)
Augie Fackler
formatting: blacken the codebase...
r43346 return dict(
(fnode(r), cln(lr)) for r, lr in revs if lr in clrevs
)
Gregory Szorc
changegroup: define linknodes callbacks in generatefiles()...
r39035
Gregory Szorc
changegroup: pass clrevtolocalrev to each group...
r39037 clrevtolocalrev = {}
Gregory Szorc
changegroup: declare shallow flag in constructor...
r38940 if self._isshallow:
Gregory Szorc
changegroup: move generatefiles() from narrow...
r38925 # In a shallow clone, the linknodes callback needs to also include
# those file nodes that are in the manifests we sent but weren't
# introduced by those manifests.
commonctxs = [self._repo[c] for c in commonrevs]
clrev = self._repo.changelog.rev
def linknodes(flog, fname):
for c in commonctxs:
try:
fnode = c.filenode(fname)
Gregory Szorc
changegroup: pass clrevtolocalrev to each group...
r39037 clrevtolocalrev[c.rev()] = flog.rev(fnode)
Gregory Szorc
changegroup: move generatefiles() from narrow...
r38925 except error.ManifestLookupError:
pass
Gregory Szorc
changegroup: define linknodes callbacks in generatefiles()...
r39035 links = normallinknodes(flog, fname)
Gregory Szorc
changegroup: move generatefiles() from narrow...
r38925 if len(links) != len(mfdicts):
for mf, lr in mfdicts:
fnode = mf.get(fname, None)
if fnode in links:
links[fnode] = min(links[fnode], lr, key=clrev)
elif fnode:
links[fnode] = lr
return links
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
changegroup: define linknodes callbacks in generatefiles()...
r39035 else:
linknodes = normallinknodes
Gregory Szorc
changegroup: move generatefiles() from narrow...
r38925
Durham Goode
bundle: move file chunk generation to it's own function...
r19334 repo = self._repo
Augie Fackler
formatting: blacken the codebase...
r43346 progress = repo.ui.makeprogress(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'files'), unit=_(b'files'), total=len(changedfiles)
Augie Fackler
formatting: blacken the codebase...
r43346 )
Durham Goode
bundle: move file chunk generation to it's own function...
r19334 for i, fname in enumerate(sorted(changedfiles)):
filerevlog = repo.file(fname)
if not filerevlog:
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b"empty or missing file data for %s") % fname
Augie Fackler
formatting: blacken the codebase...
r43346 )
Durham Goode
bundle: move file chunk generation to it's own function...
r19334
Gregory Szorc
changegroup: pass clrevtolocalrev to each group...
r39037 clrevtolocalrev.clear()
Durham Goode
bundle: move file chunk generation to it's own function...
r19334 linkrevnodes = linknodes(filerevlog, fname)
Benoit Boissinot
bundle-ng: simplify lookup and state handling...
r19207 # Lookup for filenodes, we collected the linkrev nodes above in the
# fastpath case and with lookupmf in the slowpath case.
def lookupfilelog(x):
return linkrevnodes[x]
Gregory Szorc
changegroup: inline _prune() into call sites...
r39043 frev, flr = filerevlog.rev, filerevlog.linkrev
Augie Fackler
changegroup: reintroduce some comments that have gotten lost over the years...
r39769 # Skip sending any filenode we know the client already
# has. This avoids over-sending files relatively
# inexpensively, so it's not a problem if we under-filter
# here.
Augie Fackler
formatting: blacken the codebase...
r43346 filenodes = [
n for n in linkrevnodes if flr(frev(n)) not in commonrevs
]
Gregory Szorc
changegroup: inline _prune() into call sites...
r39043
Gregory Szorc
changegroup: invert conditional and dedent...
r39056 if not filenodes:
continue
Gregory Szorc
changegroup: pass sorted revisions into group() (API)...
r39018
Gregory Szorc
changegroup: invert conditional and dedent...
r39056 progress.update(i + 1, item=fname)
Gregory Szorc
changegroup: pass all state into group()...
r39044
Gregory Szorc
changegroup: invert conditional and dedent...
r39056 deltas = deltagroup(
Augie Fackler
formatting: blacken the codebase...
r43346 self._repo,
filerevlog,
filenodes,
False,
lookupfilelog,
Gregory Szorc
changegroup: remove reordering control (BC)...
r39897 self._forcedeltaparentprev,
Gregory Szorc
changegroup: invert conditional and dedent...
r39056 ellipses=self._ellipses,
clrevtolocalrev=clrevtolocalrev,
fullclnodes=self._fullclnodes,
Augie Fackler
formatting: blacken the codebase...
r43346 precomputedellipsis=self._precomputedellipsis,
)
Gregory Szorc
changegroup: invert conditional and dedent...
r39056
yield fname, deltas
Gregory Szorc
changegroup: emit delta group close chunk outside of deltagroup()...
r39046
Martin von Zweigbergk
changegroup: use progress helper...
r38429 progress.complete()
Sune Foldager
bundle-ng: move group into the bundler...
r19200
Augie Fackler
formatting: blacken the codebase...
r43346
def _makecg1packer(
repo,
oldmatcher,
matcher,
bundlecaps,
ellipses=False,
shallow=False,
ellipsisroots=None,
fullnodes=None,
):
Gregory Szorc
changegroup: pass function to build delta header into constructor...
r38933 builddeltaheader = lambda d: _CHANGEGROUPV1_DELTA_HEADER.pack(
Augie Fackler
formatting: blacken the codebase...
r43346 d.node, d.p1node, d.p2node, d.linknode
)
Augie Fackler
changegroup: introduce cg3, which has support for exchanging treemanifests...
r27432
Augie Fackler
formatting: blacken the codebase...
r43346 return cgpacker(
repo,
oldmatcher,
matcher,
b'01',
builddeltaheader=builddeltaheader,
manifestsend=b'',
forcedeltaparentprev=True,
bundlecaps=bundlecaps,
ellipses=ellipses,
shallow=shallow,
ellipsisroots=ellipsisroots,
fullnodes=fullnodes,
)
Gregory Szorc
changegroup: define functions for creating changegroup packers...
r38930
Augie Fackler
formatting: blacken the codebase...
r43346
def _makecg2packer(
repo,
oldmatcher,
matcher,
bundlecaps,
ellipses=False,
shallow=False,
ellipsisroots=None,
fullnodes=None,
):
Gregory Szorc
changegroup: pass function to build delta header into constructor...
r38933 builddeltaheader = lambda d: _CHANGEGROUPV2_DELTA_HEADER.pack(
Augie Fackler
formatting: blacken the codebase...
r43346 d.node, d.p1node, d.p2node, d.basenode, d.linknode
)
Gregory Szorc
changegroup: pass function to build delta header into constructor...
r38933
Augie Fackler
formatting: blacken the codebase...
r43346 return cgpacker(
repo,
oldmatcher,
matcher,
b'02',
builddeltaheader=builddeltaheader,
manifestsend=b'',
bundlecaps=bundlecaps,
ellipses=ellipses,
shallow=shallow,
ellipsisroots=ellipsisroots,
fullnodes=fullnodes,
)
Gregory Szorc
changegroup: define functions for creating changegroup packers...
r38930
Gregory Szorc
changegroup: pass function to build delta header into constructor...
r38933
Augie Fackler
formatting: blacken the codebase...
r43346 def _makecg3packer(
repo,
oldmatcher,
matcher,
bundlecaps,
ellipses=False,
shallow=False,
ellipsisroots=None,
fullnodes=None,
):
builddeltaheader = lambda d: _CHANGEGROUPV3_DELTA_HEADER.pack(
d.node, d.p1node, d.p2node, d.basenode, d.linknode, d.flags
)
Gregory Szorc
changegroup: define functions for creating changegroup packers...
r38930
Augie Fackler
formatting: blacken the codebase...
r43346 return cgpacker(
repo,
oldmatcher,
matcher,
b'03',
builddeltaheader=builddeltaheader,
manifestsend=closechunk(),
bundlecaps=bundlecaps,
ellipses=ellipses,
shallow=shallow,
ellipsisroots=ellipsisroots,
fullnodes=fullnodes,
)
_packermap = {
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'01': (_makecg1packer, cg1unpacker),
Augie Fackler
formatting: blacken the codebase...
r43346 # cg2 adds support for exchanging generaldelta
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'02': (_makecg2packer, cg2unpacker),
Augie Fackler
formatting: blacken the codebase...
r43346 # cg3 adds support for exchanging revlog flags and treemanifests
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'03': (_makecg3packer, cg3unpacker),
Augie Fackler
changegroup: reformat packermap and add comment...
r26709 }
Pierre-Yves David
changegroup: add a "packermap" dictionary to track different packer versions...
r23168
Augie Fackler
formatting: blacken the codebase...
r43346
Pierre-Yves David
changegroup: pass 'repo' to allsupportedversions...
r30627 def allsupportedversions(repo):
Martin von Zweigbergk
changegroup: don't support versions 01 and 02 with treemanifests...
r27928 versions = set(_packermap.keys())
changegroup: use positive logic for treemanifest changegroup3 logic...
r43329 needv03 = False
Augie Fackler
formatting: blacken the codebase...
r43346 if (
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 repo.ui.configbool(b'experimental', b'changegroup3')
or repo.ui.configbool(b'experimental', b'treemanifest')
or b'treemanifest' in repo.requirements
Augie Fackler
formatting: blacken the codebase...
r43346 ):
changegroup: use positive logic for treemanifest changegroup3 logic...
r43329 # we keep version 03 because we need to to exchange treemanifest data
#
# we also keep vresion 01 and 02, because it is possible for repo to
# contains both normal and tree manifest at the same time. so using
# older version to pull data is viable
#
# (or even to push subset of history)
needv03 = True
sidedata: use only changegroup3 if sidedata is in use...
r43402 if b'exp-sidedata-flag' in repo.requirements:
needv03 = True
# don't attempt to use 01/02 until we do sidedata cleaning
versions.discard(b'01')
versions.discard(b'02')
changegroup: use positive logic for treemanifest changegroup3 logic...
r43329 if not needv03:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 versions.discard(b'03')
Martin von Zweigbergk
changegroup: fix pulling to treemanifest repo from flat repo (issue5066)...
r27953 return versions
Augie Fackler
formatting: blacken the codebase...
r43346
Martin von Zweigbergk
changegroup: fix pulling to treemanifest repo from flat repo (issue5066)...
r27953 # Changegroup versions that can be applied to the repo
def supportedincomingversions(repo):
Pierre-Yves David
changegroup: simplify logic around enabling changegroup 03...
r30628 return allsupportedversions(repo)
Martin von Zweigbergk
changegroup: fix pulling to treemanifest repo from flat repo (issue5066)...
r27953
Augie Fackler
formatting: blacken the codebase...
r43346
Martin von Zweigbergk
changegroup: fix pulling to treemanifest repo from flat repo (issue5066)...
r27953 # Changegroup versions that can be created from the repo
def supportedoutgoingversions(repo):
Pierre-Yves David
changegroup: pass 'repo' to allsupportedversions...
r30627 versions = allsupportedversions(repo)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if b'treemanifest' in repo.requirements:
Martin von Zweigbergk
changegroup: don't support versions 01 and 02 with treemanifests...
r27928 # Versions 01 and 02 support only flat manifests and it's just too
# expensive to convert between the flat manifest and tree manifest on
# the fly. Since tree manifests are hashed differently, all of history
# would have to be converted. Instead, we simply don't even pretend to
# support versions 01 and 02.
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 versions.discard(b'01')
versions.discard(b'02')
Martin von Zweigbergk
narrow: move requirement constant from changegroup to repository...
r38871 if repository.NARROW_REQUIREMENT in repo.requirements:
Martin von Zweigbergk
narrow: move changegroup.supportedoutgoingversions() override to core...
r36483 # Versions 01 and 02 don't support revlog flags, and we need to
# support that for stripping and unbundling to work.
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 versions.discard(b'01')
versions.discard(b'02')
Matt Harbison
lfs: move the 'supportedoutgoingversions' handling to changegroup.py...
r37150 if LFS_REQUIREMENT in repo.requirements:
# Versions 01 and 02 don't support revlog flags, and we need to
# mark LFS entries with REVIDX_EXTSTORED.
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 versions.discard(b'01')
versions.discard(b'02')
Matt Harbison
lfs: move the 'supportedoutgoingversions' handling to changegroup.py...
r37150
Martin von Zweigbergk
changegroup3: introduce experimental.changegroup3 boolean config...
r27752 return versions
Martin von Zweigbergk
changegroup: hide packermap behind methods...
r27751
Augie Fackler
formatting: blacken the codebase...
r43346
Martin von Zweigbergk
repair: preserve phase also when not using generaldelta (issue5678)...
r34179 def localversion(repo):
# Finds the best version to use for bundles that are meant to be used
# locally, such as those from strip and shelve, and temporary bundles.
return max(supportedoutgoingversions(repo))
Augie Fackler
formatting: blacken the codebase...
r43346
Martin von Zweigbergk
changegroup: introduce safeversion()...
r27929 def safeversion(repo):
# Finds the smallest version that it's safe to assume clients of the repo
Martin von Zweigbergk
shelve: use cg3 for treemanifests...
r27931 # will support. For example, all hg versions that support generaldelta also
# support changegroup 02.
Martin von Zweigbergk
changegroup: fix pulling to treemanifest repo from flat repo (issue5066)...
r27953 versions = supportedoutgoingversions(repo)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if b'generaldelta' in repo.requirements:
versions.discard(b'01')
Martin von Zweigbergk
changegroup: introduce safeversion()...
r27929 assert versions
return min(versions)
Augie Fackler
formatting: blacken the codebase...
r43346
def getbundler(
version,
repo,
bundlecaps=None,
oldmatcher=None,
matcher=None,
ellipses=False,
shallow=False,
ellipsisroots=None,
fullnodes=None,
):
Martin von Zweigbergk
changegroup: fix pulling to treemanifest repo from flat repo (issue5066)...
r27953 assert version in supportedoutgoingversions(repo)
Gregory Szorc
changegroup: move file matcher from narrow extension...
r38830
Martin von Zweigbergk
narrow: when widening, don't include manifests the client already has...
r40380 if matcher is None:
Martin von Zweigbergk
match: delete unused root and cwd arguments from {always,never,exact}() (API)...
r41825 matcher = matchmod.always()
Martin von Zweigbergk
narrow: when widening, don't include manifests the client already has...
r40380 if oldmatcher is None:
Martin von Zweigbergk
match: delete unused root and cwd arguments from {always,never,exact}() (API)...
r41825 oldmatcher = matchmod.never()
Gregory Szorc
changegroup: move file matcher from narrow extension...
r38830
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if version == b'01' and not matcher.always():
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.ProgrammingError(
Martin von Zweigbergk
cleanup: join string literals that are already on one line...
r43387 b'version 01 changegroups do not support sparse file matchers'
Augie Fackler
formatting: blacken the codebase...
r43346 )
Gregory Szorc
changegroup: move file matcher from narrow extension...
r38830
Gregory Szorc
changegroup: specify ellipses mode explicitly...
r38944 if ellipses and version in (b'01', b'02'):
raise error.Abort(
Augie Fackler
formatting: blacken the codebase...
r43346 _(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'ellipsis nodes require at least cg3 on client and server, '
b'but negotiated version %s'
Augie Fackler
formatting: blacken the codebase...
r43346 )
% version
)
Gregory Szorc
changegroup: specify ellipses mode explicitly...
r38944
Gregory Szorc
changegroup: move file matcher from narrow extension...
r38830 # Requested files could include files not in the local store. So
# filter those out.
Martin von Zweigbergk
narrow: when widening, don't include manifests the client already has...
r40380 matcher = repo.narrowmatch(matcher)
Gregory Szorc
changegroup: move file matcher from narrow extension...
r38830
Gregory Szorc
changegroup: define functions for creating changegroup packers...
r38930 fn = _packermap[version][0]
Augie Fackler
formatting: blacken the codebase...
r43346 return fn(
repo,
oldmatcher,
matcher,
bundlecaps,
ellipses=ellipses,
shallow=shallow,
ellipsisroots=ellipsisroots,
fullnodes=fullnodes,
)
Martin von Zweigbergk
changegroup: hide packermap behind methods...
r27751
Gregory Szorc
bundle2: store changeset count when creating file bundles...
r29593 def getunbundler(version, fh, alg, extras=None):
return _packermap[version][1](fh, alg, extras=extras)
Martin von Zweigbergk
changegroup: hide packermap behind methods...
r27751
Augie Fackler
formatting: blacken the codebase...
r43346
Pierre-Yves David
localrepo: move the changegroupinfo method in changegroup module...
r20926 def _changegroupinfo(repo, nodes, source):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if repo.ui.verbose or source == b'bundle':
repo.ui.status(_(b"%d changesets found\n") % len(nodes))
Pierre-Yves David
localrepo: move the changegroupinfo method in changegroup module...
r20926 if repo.ui.debugflag:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 repo.ui.debug(b"list of changesets:\n")
Pierre-Yves David
localrepo: move the changegroupinfo method in changegroup module...
r20926 for node in nodes:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 repo.ui.debug(b"%s\n" % hex(node))
Pierre-Yves David
localrepo: move the changegroupinfo method in changegroup module...
r20926
Durham Goode
changegroup: replace getsubset with makechangegroup...
r34098
Augie Fackler
formatting: blacken the codebase...
r43346 def makechangegroup(
repo, outgoing, version, source, fastpath=False, bundlecaps=None
):
cgstream = makestream(
repo,
outgoing,
version,
source,
fastpath=fastpath,
bundlecaps=bundlecaps,
)
return getunbundler(
version,
util.chunkbuffer(cgstream),
None,
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 {b'clcount': len(outgoing.missing)},
Augie Fackler
formatting: blacken the codebase...
r43346 )
def makestream(
repo,
outgoing,
version,
source,
fastpath=False,
bundlecaps=None,
matcher=None,
):
bundler = getbundler(version, repo, bundlecaps=bundlecaps, matcher=matcher)
Durham Goode
changegroup: rename getsubsetraw to makestream...
r34105
Pierre-Yves David
localrepo: move the _changegroupsubset method in changegroup module...
r20925 repo = repo.unfiltered()
commonrevs = outgoing.common
csets = outgoing.missing
heads = outgoing.missingheads
# We go through the fast path if we get told to, or if all (unfiltered
# heads have been requested (since we then know there all linkrevs will
# be pulled by the client).
heads.sort()
fastpathlinkrev = fastpath or (
Augie Fackler
formatting: blacken the codebase...
r43346 repo.filtername is None and heads == sorted(repo.heads())
)
Pierre-Yves David
localrepo: move the _changegroupsubset method in changegroup module...
r20925
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 repo.hook(b'preoutgoing', throw=True, source=source)
Pierre-Yves David
localrepo: move the changegroupinfo method in changegroup module...
r20926 _changegroupinfo(repo, csets, source)
Sune Foldager
changegroup: introduce "raw" versions of some commands...
r23177 return bundler.generate(commonrevs, csets, fastpathlinkrev, source)
Augie Fackler
formatting: blacken the codebase...
r43346
Martin von Zweigbergk
changegroup: progress for added files is not measured in "chunks"...
r28361 def _addchangegroupfiles(repo, source, revmap, trp, expectedfiles, needfiles):
Pierre-Yves David
localrepo: move the addchangegroupfiles method in changegroup module...
r20932 revisions = 0
files = 0
Augie Fackler
formatting: blacken the codebase...
r43346 progress = repo.ui.makeprogress(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'files'), unit=_(b'files'), total=expectedfiles
Augie Fackler
formatting: blacken the codebase...
r43346 )
Augie Fackler
changegroup: use `iter(callable, sentinel)` instead of while True...
r29724 for chunkdata in iter(source.filelogheader, {}):
Martin von Zweigbergk
changegroup: progress for added files is not measured in "chunks"...
r28361 files += 1
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 f = chunkdata[b"filename"]
repo.ui.debug(b"adding %s revisions\n" % f)
Martin von Zweigbergk
changegroup: use progress helper...
r38401 progress.increment()
Martin von Zweigbergk
changegroup3: move treemanifest support into _unpackmanifests()...
r27754 fl = repo.file(f)
Pierre-Yves David
localrepo: move the addchangegroupfiles method in changegroup module...
r20932 o = len(fl)
Mike Edgar
revlog: in addgroup, reject ill-formed deltas based on censored nodes...
r24120 try:
Durham Goode
revlog: add revmap back to revlog.addgroup...
r34292 deltas = source.deltaiter()
if not fl.addgroup(deltas, revmap, trp):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b"received file revlog group is empty"))
Gregory Szorc
global: mass rewrite to use modern exception syntax...
r25660 except error.CensoredBaseError as e:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b"received delta base is censored: %s") % e)
Martin von Zweigbergk
changegroup3: move treemanifest support into _unpackmanifests()...
r27754 revisions += len(fl) - o
Pierre-Yves David
localrepo: move the addchangegroupfiles method in changegroup module...
r20932 if f in needfiles:
needs = needfiles[f]
Gregory Szorc
global: use pycompat.xrange()...
r38806 for new in pycompat.xrange(o, len(fl)):
Pierre-Yves David
localrepo: move the addchangegroupfiles method in changegroup module...
r20932 n = fl.node(new)
if n in needs:
needs.remove(n)
else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b"received spurious file revlog entry"))
Pierre-Yves David
localrepo: move the addchangegroupfiles method in changegroup module...
r20932 if not needs:
del needfiles[f]
Martin von Zweigbergk
changegroup: use progress helper...
r38401 progress.complete()
Pierre-Yves David
localrepo: move the addchangegroupfiles method in changegroup module...
r20932
Gregory Szorc
py3: finish porting iteritems() to pycompat and remove source transformer...
r43376 for f, needs in pycompat.iteritems(needfiles):
Pierre-Yves David
localrepo: move the addchangegroupfiles method in changegroup module...
r20932 fl = repo.file(f)
for n in needs:
try:
fl.rev(n)
except error.LookupError:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'missing file data for %s:%s - run hg verify')
Augie Fackler
formatting: blacken the codebase...
r43346 % (f, hex(n))
)
Pierre-Yves David
localrepo: move the addchangegroupfiles method in changegroup module...
r20932
return revisions, files