Beispiel #1
0
            def putcommit(
                self,
                files,
                copies,
                parents,
                commit,
                source,
                revmap,
                full,
                cleanp2,
            ):
                pc = super(lfssink, self).putcommit
                node = pc(
                    files,
                    copies,
                    parents,
                    commit,
                    source,
                    revmap,
                    full,
                    cleanp2,
                )

                if b'lfs' not in self.repo.requirements:
                    ctx = self.repo[node]

                    # The file list may contain removed files, so check for
                    # membership before assuming it is in the context.
                    if any(f in ctx and ctx[f].islfs() for f, n in files):
                        self.repo.requirements.add(b'lfs')
                        scmutil.writereporequirements(self.repo)

                return node
Beispiel #2
0
def _handlenarrowspecs(op, inpart):
    data = inpart.read()
    inc, exc = data.split(b'\0')
    includepats = set(inc.splitlines())
    excludepats = set(exc.splitlines())
    narrowspec.validatepatterns(includepats)
    narrowspec.validatepatterns(excludepats)

    if requirements.NARROW_REQUIREMENT not in op.repo.requirements:
        op.repo.requirements.add(requirements.NARROW_REQUIREMENT)
        scmutil.writereporequirements(op.repo)
    op.repo.setnarrowpats(includepats, excludepats)
    narrowspec.copytoworkingcopy(op.repo)
Beispiel #3
0
def _handlechangespec_2(op, inpart):
    # XXX: This bundle2 handling is buggy and should be removed after hg5.2 is
    # released. New servers will send a mandatory bundle2 part named
    # 'Narrowspec' and will send specs as data instead of params.
    # Refer to issue5952 and 6019
    includepats = set(inpart.params.get(_SPECPART_INCLUDE, b'').splitlines())
    excludepats = set(inpart.params.get(_SPECPART_EXCLUDE, b'').splitlines())
    narrowspec.validatepatterns(includepats)
    narrowspec.validatepatterns(excludepats)

    if not requirements.NARROW_REQUIREMENT in op.repo.requirements:
        op.repo.requirements.add(requirements.NARROW_REQUIREMENT)
        scmutil.writereporequirements(op.repo)
    op.repo.setnarrowpats(includepats, excludepats)
    narrowspec.copytoworkingcopy(op.repo)
Beispiel #4
0
        def pull_shallow(orig, self, *args, **kwargs):
            if not isenabled(self):
                repos.append(self.unfiltered())
                # set up the client hooks so the post-clone update works
                setupclient(self.ui, self.unfiltered())

                # setupclient fixed the class on the repo itself
                # but we also need to fix it on the repoview
                if isinstance(self, repoview.repoview):
                    self.__class__.__bases__ = (
                        self.__class__.__bases__[0],
                        self.unfiltered().__class__,
                    )
                self.requirements.add(constants.SHALLOWREPO_REQUIREMENT)
                with self.lock():
                    # acquire store lock before writing requirements as some
                    # requirements might be written to .hg/store/requires
                    scmutil.writereporequirements(self)

                # Since setupclient hadn't been called, exchange.pull was not
                # wrapped. So we need to manually invoke our version of it.
                return exchangepull(orig, self, *args, **kwargs)
            else:
                return orig(self, *args, **kwargs)
Beispiel #5
0
def lfconvert(ui, src, dest, *pats, **opts):
    """convert a normal repository to a largefiles repository

    Convert repository SOURCE to a new repository DEST, identical to
    SOURCE except that certain files will be converted as largefiles:
    specifically, any file that matches any PATTERN *or* whose size is
    above the minimum size threshold is converted as a largefile. The
    size used to determine whether or not to track a file as a
    largefile is the size of the first version of the file. The
    minimum size can be specified either with --size or in
    configuration as ``largefiles.size``.

    After running this command you will need to make sure that
    largefiles is enabled anywhere you intend to push the new
    repository.

    Use --to-normal to convert largefiles back to normal files; after
    this, the DEST repository can be used without largefiles at all."""

    opts = pycompat.byteskwargs(opts)
    if opts[b'to_normal']:
        tolfile = False
    else:
        tolfile = True
        size = lfutil.getminsize(ui, True, opts.get(b'size'), default=None)

    if not hg.islocal(src):
        raise error.Abort(_(b'%s is not a local Mercurial repo') % src)
    if not hg.islocal(dest):
        raise error.Abort(_(b'%s is not a local Mercurial repo') % dest)

    rsrc = hg.repository(ui, src)
    ui.status(_(b'initializing destination %s\n') % dest)
    rdst = hg.repository(ui, dest, create=True)

    success = False
    dstwlock = dstlock = None
    try:
        # Get a list of all changesets in the source.  The easy way to do this
        # is to simply walk the changelog, using changelog.nodesbetween().
        # Take a look at mercurial/revlog.py:639 for more details.
        # Use a generator instead of a list to decrease memory usage
        ctxs = (rsrc[ctx]
                for ctx in rsrc.changelog.nodesbetween(None, rsrc.heads())[0])
        revmap = {nullid: nullid}
        if tolfile:
            # Lock destination to prevent modification while it is converted to.
            # Don't need to lock src because we are just reading from its
            # history which can't change.
            dstwlock = rdst.wlock()
            dstlock = rdst.lock()

            lfiles = set()
            normalfiles = set()
            if not pats:
                pats = ui.configlist(lfutil.longname, b'patterns')
            if pats:
                matcher = matchmod.match(rsrc.root, b'', list(pats))
            else:
                matcher = None

            lfiletohash = {}
            with ui.makeprogress(
                    _(b'converting revisions'),
                    unit=_(b'revisions'),
                    total=rsrc[b'tip'].rev(),
            ) as progress:
                for ctx in ctxs:
                    progress.update(ctx.rev())
                    _lfconvert_addchangeset(
                        rsrc,
                        rdst,
                        ctx,
                        revmap,
                        lfiles,
                        normalfiles,
                        matcher,
                        size,
                        lfiletohash,
                    )

            if rdst.wvfs.exists(lfutil.shortname):
                rdst.wvfs.rmtree(lfutil.shortname)

            for f in lfiletohash.keys():
                if rdst.wvfs.isfile(f):
                    rdst.wvfs.unlink(f)
                try:
                    rdst.wvfs.removedirs(rdst.wvfs.dirname(f))
                except OSError:
                    pass

            # If there were any files converted to largefiles, add largefiles
            # to the destination repository's requirements.
            if lfiles:
                rdst.requirements.add(b'largefiles')
                scmutil.writereporequirements(rdst)
        else:

            class lfsource(filemap.filemap_source):
                def __init__(self, ui, source):
                    super(lfsource, self).__init__(ui, source, None)
                    self.filemapper.rename[lfutil.shortname] = b'.'

                def getfile(self, name, rev):
                    realname, realrev = rev
                    f = super(lfsource, self).getfile(name, rev)

                    if (not realname.startswith(lfutil.shortnameslash)
                            or f[0] is None):
                        return f

                    # Substitute in the largefile data for the hash
                    hash = f[0].strip()
                    path = lfutil.findfile(rsrc, hash)

                    if path is None:
                        raise error.Abort(
                            _(b"missing largefile for '%s' in %s") %
                            (realname, realrev))
                    return util.readfile(path), f[1]

            class converter(convcmd.converter):
                def __init__(self, ui, source, dest, revmapfile, opts):
                    src = lfsource(ui, source)

                    super(converter, self).__init__(ui, src, dest, revmapfile,
                                                    opts)

            found, missing = downloadlfiles(ui, rsrc)
            if missing != 0:
                raise error.Abort(_(b"all largefiles must be present locally"))

            orig = convcmd.converter
            convcmd.converter = converter

            try:
                convcmd.convert(ui,
                                src,
                                dest,
                                source_type=b'hg',
                                dest_type=b'hg')
            finally:
                convcmd.converter = orig
        success = True
    finally:
        if tolfile:
            rdst.dirstate.clear()
            release(dstlock, dstwlock)
        if not success:
            # we failed, remove the new directory
            shutil.rmtree(rdst.root)
Beispiel #6
0
 def checkrequireslfiles(ui, repo, **kwargs):
     if b'largefiles' not in repo.requirements and any(
             lfutil.shortname + b'/' in f[0]
             for f in repo.store.datafiles()):
         repo.requirements.add(b'largefiles')
         scmutil.writereporequirements(repo)