hgext/remotefilelog/shallowbundle.py
changeset 43077 687b865b95ad
parent 43076 2372284d9457
child 43506 9f70512ae2cf
equal deleted inserted replaced
43076:2372284d9457 43077:687b865b95ad
    77             if isinstance(repo, bundlerepo.bundlerepository):
    77             if isinstance(repo, bundlerepo.bundlerepository):
    78                 # If the bundle contains filelogs, we can't pull from it, since
    78                 # If the bundle contains filelogs, we can't pull from it, since
    79                 # bundlerepo is heavily tied to revlogs. Instead require that
    79                 # bundlerepo is heavily tied to revlogs. Instead require that
    80                 # the user use unbundle instead.
    80                 # the user use unbundle instead.
    81                 # Force load the filelog data.
    81                 # Force load the filelog data.
    82                 bundlerepo.bundlerepository.file(repo, 'foo')
    82                 bundlerepo.bundlerepository.file(repo, b'foo')
    83                 if repo._cgfilespos:
    83                 if repo._cgfilespos:
    84                     raise error.Abort(
    84                     raise error.Abort(
    85                         "cannot pull from full bundles",
    85                         b"cannot pull from full bundles",
    86                         hint="use `hg unbundle` instead",
    86                         hint=b"use `hg unbundle` instead",
    87                     )
    87                     )
    88                 return []
    88                 return []
    89             filestosend = self.shouldaddfilegroups(source)
    89             filestosend = self.shouldaddfilegroups(source)
    90             if filestosend == NoFiles:
    90             if filestosend == NoFiles:
    91                 changedfiles = list(
    91                 changedfiles = list(
    97     def shouldaddfilegroups(self, source):
    97     def shouldaddfilegroups(self, source):
    98         repo = self._repo
    98         repo = self._repo
    99         if not shallowutil.isenabled(repo):
    99         if not shallowutil.isenabled(repo):
   100             return AllFiles
   100             return AllFiles
   101 
   101 
   102         if source == "push" or source == "bundle":
   102         if source == b"push" or source == b"bundle":
   103             return AllFiles
   103             return AllFiles
   104 
   104 
   105         caps = self._bundlecaps or []
   105         caps = self._bundlecaps or []
   106         if source == "serve" or source == "pull":
   106         if source == b"serve" or source == b"pull":
   107             if constants.BUNDLE2_CAPABLITY in caps:
   107             if constants.BUNDLE2_CAPABLITY in caps:
   108                 return LocalFiles
   108                 return LocalFiles
   109             else:
   109             else:
   110                 # Serving to a full repo requires us to serve everything
   110                 # Serving to a full repo requires us to serve everything
   111                 repo.ui.warn(_("pulling from a shallow repo\n"))
   111                 repo.ui.warn(_(b"pulling from a shallow repo\n"))
   112                 return AllFiles
   112                 return AllFiles
   113 
   113 
   114         return NoFiles
   114         return NoFiles
   115 
   115 
   116     def prune(self, rlog, missing, commonrevs):
   116     def prune(self, rlog, missing, commonrevs):
   126             if fctx.linkrev() not in commonrevs:
   126             if fctx.linkrev() not in commonrevs:
   127                 results.append(fnode)
   127                 results.append(fnode)
   128         return results
   128         return results
   129 
   129 
   130     def nodechunk(self, revlog, node, prevnode, linknode):
   130     def nodechunk(self, revlog, node, prevnode, linknode):
   131         prefix = ''
   131         prefix = b''
   132         if prevnode == nullid:
   132         if prevnode == nullid:
   133             delta = revlog.rawdata(node)
   133             delta = revlog.rawdata(node)
   134             prefix = mdiff.trivialdiffheader(len(delta))
   134             prefix = mdiff.trivialdiffheader(len(delta))
   135         else:
   135         else:
   136             # Actually uses remotefilelog.revdiff which works on nodes, not revs
   136             # Actually uses remotefilelog.revdiff which works on nodes, not revs
   150         return orig(repo, outgoing, version, source, *args, **kwargs)
   150         return orig(repo, outgoing, version, source, *args, **kwargs)
   151 
   151 
   152     original = repo.shallowmatch
   152     original = repo.shallowmatch
   153     try:
   153     try:
   154         # if serving, only send files the clients has patterns for
   154         # if serving, only send files the clients has patterns for
   155         if source == 'serve':
   155         if source == b'serve':
   156             bundlecaps = kwargs.get(r'bundlecaps')
   156             bundlecaps = kwargs.get(r'bundlecaps')
   157             includepattern = None
   157             includepattern = None
   158             excludepattern = None
   158             excludepattern = None
   159             for cap in bundlecaps or []:
   159             for cap in bundlecaps or []:
   160                 if cap.startswith("includepattern="):
   160                 if cap.startswith(b"includepattern="):
   161                     raw = cap[len("includepattern=") :]
   161                     raw = cap[len(b"includepattern=") :]
   162                     if raw:
   162                     if raw:
   163                         includepattern = raw.split('\0')
   163                         includepattern = raw.split(b'\0')
   164                 elif cap.startswith("excludepattern="):
   164                 elif cap.startswith(b"excludepattern="):
   165                     raw = cap[len("excludepattern=") :]
   165                     raw = cap[len(b"excludepattern=") :]
   166                     if raw:
   166                     if raw:
   167                         excludepattern = raw.split('\0')
   167                         excludepattern = raw.split(b'\0')
   168             if includepattern or excludepattern:
   168             if includepattern or excludepattern:
   169                 repo.shallowmatch = match.match(
   169                 repo.shallowmatch = match.match(
   170                     repo.root, '', None, includepattern, excludepattern
   170                     repo.root, b'', None, includepattern, excludepattern
   171                 )
   171                 )
   172             else:
   172             else:
   173                 repo.shallowmatch = match.always()
   173                 repo.shallowmatch = match.always()
   174         return orig(repo, outgoing, version, source, *args, **kwargs)
   174         return orig(repo, outgoing, version, source, *args, **kwargs)
   175     finally:
   175     finally:
   190     # revision may depend on a different file's revision (in the case
   190     # revision may depend on a different file's revision (in the case
   191     # of a rename/copy), so we must lay all revisions down across all
   191     # of a rename/copy), so we must lay all revisions down across all
   192     # files in topological order.
   192     # files in topological order.
   193 
   193 
   194     # read all the file chunks but don't add them
   194     # read all the file chunks but don't add them
   195     progress = repo.ui.makeprogress(_('files'), total=expectedfiles)
   195     progress = repo.ui.makeprogress(_(b'files'), total=expectedfiles)
   196     while True:
   196     while True:
   197         chunkdata = source.filelogheader()
   197         chunkdata = source.filelogheader()
   198         if not chunkdata:
   198         if not chunkdata:
   199             break
   199             break
   200         f = chunkdata["filename"]
   200         f = chunkdata[b"filename"]
   201         repo.ui.debug("adding %s revisions\n" % f)
   201         repo.ui.debug(b"adding %s revisions\n" % f)
   202         progress.increment()
   202         progress.increment()
   203 
   203 
   204         if not repo.shallowmatch(f):
   204         if not repo.shallowmatch(f):
   205             fl = repo.file(f)
   205             fl = repo.file(f)
   206             deltas = source.deltaiter()
   206             deltas = source.deltaiter()
   222             if f not in visited:
   222             if f not in visited:
   223                 newfiles += 1
   223                 newfiles += 1
   224                 visited.add(f)
   224                 visited.add(f)
   225 
   225 
   226         if chain is None:
   226         if chain is None:
   227             raise error.Abort(_("received file revlog group is empty"))
   227             raise error.Abort(_(b"received file revlog group is empty"))
   228 
   228 
   229     processed = set()
   229     processed = set()
   230 
   230 
   231     def available(f, node, depf, depnode):
   231     def available(f, node, depf, depnode):
   232         if depnode != nullid and (depf, depnode) not in processed:
   232         if depnode != nullid and (depf, depnode) not in processed:
   264         if (f, node) in processed:
   264         if (f, node) in processed:
   265             continue
   265             continue
   266 
   266 
   267         skipcount += 1
   267         skipcount += 1
   268         if skipcount > len(queue) + 1:
   268         if skipcount > len(queue) + 1:
   269             raise error.Abort(_("circular node dependency"))
   269             raise error.Abort(_(b"circular node dependency"))
   270 
   270 
   271         fl = repo.file(f)
   271         fl = repo.file(f)
   272 
   272 
   273         revisiondata = revisiondatas[(f, node)]
   273         revisiondata = revisiondatas[(f, node)]
   274         # revisiondata: (node, p1, p2, cs, deltabase, delta, flags)
   274         # revisiondata: (node, p1, p2, cs, deltabase, delta, flags)
   281         text = mdiff.patch(base, delta)
   281         text = mdiff.patch(base, delta)
   282         if not isinstance(text, bytes):
   282         if not isinstance(text, bytes):
   283             text = bytes(text)
   283             text = bytes(text)
   284 
   284 
   285         meta, text = shallowutil.parsemeta(text)
   285         meta, text = shallowutil.parsemeta(text)
   286         if 'copy' in meta:
   286         if b'copy' in meta:
   287             copyfrom = meta['copy']
   287             copyfrom = meta[b'copy']
   288             copynode = bin(meta['copyrev'])
   288             copynode = bin(meta[b'copyrev'])
   289             if not available(f, node, copyfrom, copynode):
   289             if not available(f, node, copyfrom, copynode):
   290                 continue
   290                 continue
   291 
   291 
   292         for p in [p1, p2]:
   292         for p in [p1, p2]:
   293             if p != nullid:
   293             if p != nullid: