##// END OF EJS Templates
changegroup: move message about added changes to transaction summary...
changegroup: move message about added changes to transaction summary Before that, applying multiple changegroups in the same transaction issued the message multiple time. This result in a confusing output: adding changesets adding manifests adding file changes added 32768 changesets with 60829 changes to 2668 files adding changesets adding manifests adding file changes added 8192 changesets with 16885 changes to 1553 files adding changesets adding manifests adding file changes added 1020 changesets with 1799 changes to 536 files adding changesets adding manifests ... Instead, we now only issue the message once at the end of the transaction, summing up all added changesets, changes and files. The line is identical, but happens sightly later in the output. There are other suboptimal behavior around issue multiple changegroup (eg: progress bar). We'll cover them later. This impact of lot of test as one would expect, but a two pass check show they are just the order change we expected. To deal with "under the hood" bundle application by internal code, we had to take a slightly hacky move. We could clean that up with a more official way to enter "under the hood" section, however I want to keep this series simple to get it landed. This kind of change have a very high bit rot rate since it impact a lot of test output.

File last commit:

r41965:5f198b69 merge default
r43167:d7304434 default
Show More
generate-churning-bundle.py
138 lines | 4.4 KiB | text/x-python | PythonLexer
/ tests / artifacts / scripts / generate-churning-bundle.py
#!/usr/bin/env python
#
# generate-branchy-bundle - generate a branch for a "large" branchy repository
#
# Copyright 2018 Octobus, contact@octobus.net
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
#
# This script generates a repository suitable for testing delta computation
# strategies.
#
# The repository update a single "large" file with many updates. One fixed part
# of the files always get updated while the rest of the lines get updated over
# time. This update happens over many topological branches, some getting merged
# back.
#
# Running with `chg` in your path and `CHGHG` set is recommended for speed.
from __future__ import absolute_import, print_function
import hashlib
import os
import shutil
import subprocess
import sys
import tempfile
BUNDLE_NAME = 'big-file-churn.hg'
# constants for generating the repository
NB_CHANGESET = 5000
PERIOD_MERGING = 8
PERIOD_BRANCHING = 7
MOVE_BACK_MIN = 3
MOVE_BACK_RANGE = 5
# constants for generating the large file we keep updating
#
# At each revision, the beginning on the file change,
# and set of other lines changes too.
FILENAME='SPARSE-REVLOG-TEST-FILE'
NB_LINES = 10500
ALWAYS_CHANGE_LINES = 500
OTHER_CHANGES = 300
def nextcontent(previous_content):
"""utility to produce a new file content from the previous one"""
return hashlib.md5(previous_content).hexdigest()
def filecontent(iteridx, oldcontent):
"""generate a new file content
The content is generated according the iteration index and previous
content"""
# initial call
if iteridx is None:
current = ''
else:
current = str(iteridx)
for idx in xrange(NB_LINES):
do_change_line = True
if oldcontent is not None and ALWAYS_CHANGE_LINES < idx:
do_change_line = not ((idx - iteridx) % OTHER_CHANGES)
if do_change_line:
to_write = current + '\n'
current = nextcontent(current)
else:
to_write = oldcontent[idx]
yield to_write
def updatefile(filename, idx):
"""update <filename> to be at appropriate content for iteration <idx>"""
existing = None
if idx is not None:
with open(filename, 'rb') as old:
existing = old.readlines()
with open(filename, 'wb') as target:
for line in filecontent(idx, existing):
target.write(line)
def hg(command, *args):
"""call a mercurial command with appropriate config and argument"""
env = os.environ.copy()
if 'CHGHG' in env:
full_cmd = ['chg']
else:
full_cmd = ['hg']
full_cmd.append('--quiet')
full_cmd.append(command)
if command == 'commit':
# reproducible commit metadata
full_cmd.extend(['--date', '0 0', '--user', 'test'])
elif command == 'merge':
# avoid conflicts by picking the local variant
full_cmd.extend(['--tool', ':merge-local'])
full_cmd.extend(args)
env['HGRCPATH'] = ''
return subprocess.check_call(full_cmd, env=env)
def run(target):
tmpdir = tempfile.mkdtemp(prefix='tmp-hg-test-big-file-bundle-')
try:
os.chdir(tmpdir)
hg('init')
updatefile(FILENAME, None)
hg('commit', '--addremove', '--message', 'initial commit')
for idx in xrange(1, NB_CHANGESET + 1):
if sys.stdout.isatty():
print("generating commit #%d/%d" % (idx, NB_CHANGESET))
if (idx % PERIOD_BRANCHING) == 0:
move_back = MOVE_BACK_MIN + (idx % MOVE_BACK_RANGE)
hg('update', ".~%d" % move_back)
if (idx % PERIOD_MERGING) == 0:
hg('merge', 'min(head())')
updatefile(FILENAME, idx)
hg('commit', '--message', 'commit #%d' % idx)
hg('bundle', '--all', target, '--config', 'devel.bundle.delta=p1')
with open(target, 'rb') as bundle:
data = bundle.read()
digest = hashlib.md5(data).hexdigest()
with open(target + '.md5', 'wb') as md5file:
md5file.write(digest + '\n')
if sys.stdout.isatty():
print('bundle generated at "%s" md5: %s' % (target, digest))
finally:
shutil.rmtree(tmpdir)
return 0
if __name__ == '__main__':
orig = os.path.realpath(os.path.dirname(sys.argv[0]))
target = os.path.join(orig, os.pardir, 'cache', BUNDLE_NAME)
sys.exit(run(target))