view hgext/infinitepush/infinitepushcommands.py @ 37188:de4c2f3af97f

infinitepush: remove backupcommands.py This file contains command pushbackup and pullbackup which are used to store things to infinitepush. This is an advanced functionality which we don't require as of now. Also this uses shareutil.py from fb-hgext/ which is not there in core. Therefore this patch deletes the file and the config option which belongs to the backup thing. If we need this functionality in future, we can always move this file back. Differential Revision: https://phab.mercurial-scm.org/D2097
author Pulkit Goyal <7895pulkit@gmail.com>
date Sat, 03 Feb 2018 17:54:55 +0530
parents 03ff17a4bf53
children
line wrap: on
line source

# Copyright 2016 Facebook, Inc.
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
"""
config::

    [infinitepush]
    # limit number of files in the node metadata. This is to make sure we don't
    # waste too much space on huge codemod commits.
    metadatafilelimit = 100
"""

from __future__ import absolute_import

import json

from mercurial.node import bin
from mercurial.i18n import _

from mercurial import (
    copies as copiesmod,
    encoding,
    error,
    hg,
    patch,
    registrar,
    scmutil,
    util,
)

from . import (
    common,
)

downloadbundle = common.downloadbundle

cmdtable = {}
command = registrar.command(cmdtable)

@command('debugfillinfinitepushmetadata',
         [('', 'node', [], 'node to fill metadata for')])
def debugfillinfinitepushmetadata(ui, repo, **opts):
    '''Special command that fills infinitepush metadata for a node
    '''

    nodes = opts['node']
    if not nodes:
        raise error.Abort(_('nodes are not specified'))

    filelimit = ui.configint('infinitepush', 'metadatafilelimit', 100)
    nodesmetadata = {}
    for node in nodes:
        index = repo.bundlestore.index
        if not bool(index.getbundle(node)):
            raise error.Abort(_('node %s is not found') % node)

        if node not in repo:
            newbundlefile = downloadbundle(repo, bin(node))
            bundlepath = "bundle:%s+%s" % (repo.root, newbundlefile)
            bundlerepo = hg.repository(ui, bundlepath)
            repo = bundlerepo

        p1 = repo[node].p1().node()
        diffopts = patch.diffallopts(ui, {})
        match = scmutil.matchall(repo)
        chunks = patch.diff(repo, p1, node, match, None, diffopts, relroot='')
        difflines = util.iterlines(chunks)

        states = 'modified added removed deleted unknown ignored clean'.split()
        status = repo.status(p1, node)
        status = zip(states, status)

        filestatus = {}
        for state, files in status:
            for f in files:
                filestatus[f] = state

        diffstat = patch.diffstatdata(difflines)
        changed_files = {}
        copies = copiesmod.pathcopies(repo[p1], repo[node])
        for filename, adds, removes, isbinary in diffstat[:filelimit]:
            # use special encoding that allows non-utf8 filenames
            filename = encoding.jsonescape(filename, paranoid=True)
            changed_files[filename] = {
                'adds': adds, 'removes': removes, 'isbinary': isbinary,
                'status': filestatus.get(filename, 'unknown')
            }
            if filename in copies:
                changed_files[filename]['copies'] = copies[filename]

        output = {}
        output['changed_files'] = changed_files
        if len(diffstat) > filelimit:
            output['changed_files_truncated'] = True
        nodesmetadata[node] = output

    with index:
        for node, metadata in nodesmetadata.iteritems():
            dumped = json.dumps(metadata, sort_keys=True)
            index.saveoptionaljsonmetadata(node, dumped)