##// END OF EJS Templates
infinitepush: remove wrapping around bundle2._addpartsfromopts()...
infinitepush: remove wrapping around bundle2._addpartsfromopts() This wrapping around bundle2._addpartsfromopts() was added by me while hacking on an alternate way to mark a push as infinitepush or not. However the wrapping is wrong as the push command does not go through the code path which was wrapped on the client side. Differential Revision: https://phab.mercurial-scm.org/D2101

File last commit:

r37205:de4c2f3a default
r37209:e702ca15 default
Show More
infinitepushcommands.py
101 lines | 3.0 KiB | text/x-python | PythonLexer
# 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)