Mercurial > hg-stable
view mercurial/diffutil.py @ 39646:9c2c77c73f23
wireprotov2: define and implement "changesetdata" command
This commit introduces the "changesetdata" wire protocol command.
The role of the command is to expose data associated with changelog
revisions, including the raw revision data itself.
This command is the first piece of a new clone/pull strategy that
is built on top of domain-specific commands for data retrieval.
Instead of a monolithic "getbundle" command that transfers all of the
things, we'll be introducing commands for fetching specific pieces
of data.
Since the changeset is the fundamental unit from which we derive
pointers to other data (manifests, file nodes, etc), it makes sense
to start reimplementing pull with this data.
The command accepts as arguments a set of root and head revisions
defining the changesets that should be fetched as well as an explicit
list of nodes. By default, the command returns only the node values:
the client must explicitly request additional fields be added to the
response. Current supported fields are the list of parent nodes and
the revision fulltext.
My plan is to eventually add support for transferring other data
associated with changesets, including phases, bookmarks, obsolescence
markers, etc. Since the response format is CBOR, we'll be able to add
this data into the response object relatively easily (it should be
as simple as adding a key in a map).
The documentation captures a number of TODO items. Some of these may
require BC breaking changes. That's fine: wire protocol v2 is still
highly experimental.
Differential Revision: https://phab.mercurial-scm.org/D4481
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Wed, 12 Sep 2018 10:01:16 -0700 |
parents | be441eb65f09 |
children | 78b270a55dc6 |
line wrap: on
line source
# diffutil.py - utility functions related to diff and patch # # Copyright 2006 Brendan Cully <brendan@kublai.com> # Copyright 2007 Chris Mason <chris.mason@oracle.com> # Copyright 2018 Octobus <octobus@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. from __future__ import absolute_import from .i18n import _ from . import ( mdiff, pycompat, ) def diffallopts(ui, opts=None, untrusted=False, section='diff'): '''return diffopts with all features supported and parsed''' return difffeatureopts(ui, opts=opts, untrusted=untrusted, section=section, git=True, whitespace=True, formatchanging=True) def difffeatureopts(ui, opts=None, untrusted=False, section='diff', git=False, whitespace=False, formatchanging=False): '''return diffopts with only opted-in features parsed Features: - git: git-style diffs - whitespace: whitespace options like ignoreblanklines and ignorews - formatchanging: options that will likely break or cause correctness issues with most diff parsers ''' def get(key, name=None, getter=ui.configbool, forceplain=None): if opts: v = opts.get(key) # diffopts flags are either None-default (which is passed # through unchanged, so we can identify unset values), or # some other falsey default (eg --unified, which defaults # to an empty string). We only want to override the config # entries from hgrc with command line values if they # appear to have been set, which is any truthy value, # True, or False. if v or isinstance(v, bool): return v if forceplain is not None and ui.plain(): return forceplain return getter(section, name or key, untrusted=untrusted) # core options, expected to be understood by every diff parser buildopts = { 'nodates': get('nodates'), 'showfunc': get('show_function', 'showfunc'), 'context': get('unified', getter=ui.config), } buildopts['xdiff'] = ui.configbool('experimental', 'xdiff') if git: buildopts['git'] = get('git') # since this is in the experimental section, we need to call # ui.configbool directory buildopts['showsimilarity'] = ui.configbool('experimental', 'extendedheader.similarity') # need to inspect the ui object instead of using get() since we want to # test for an int hconf = ui.config('experimental', 'extendedheader.index') if hconf is not None: hlen = None try: # the hash config could be an integer (for length of hash) or a # word (e.g. short, full, none) hlen = int(hconf) if hlen < 0 or hlen > 40: msg = _("invalid length for extendedheader.index: '%d'\n") ui.warn(msg % hlen) except ValueError: # default value if hconf == 'short' or hconf == '': hlen = 12 elif hconf == 'full': hlen = 40 elif hconf != 'none': msg = _("invalid value for extendedheader.index: '%s'\n") ui.warn(msg % hconf) finally: buildopts['index'] = hlen if whitespace: buildopts['ignorews'] = get('ignore_all_space', 'ignorews') buildopts['ignorewsamount'] = get('ignore_space_change', 'ignorewsamount') buildopts['ignoreblanklines'] = get('ignore_blank_lines', 'ignoreblanklines') buildopts['ignorewseol'] = get('ignore_space_at_eol', 'ignorewseol') if formatchanging: buildopts['text'] = opts and opts.get('text') binary = None if opts is None else opts.get('binary') buildopts['nobinary'] = (not binary if binary is not None else get('nobinary', forceplain=False)) buildopts['noprefix'] = get('noprefix', forceplain=False) buildopts['worddiff'] = get('word_diff', 'word-diff', forceplain=False) return mdiff.diffopts(**pycompat.strkwargs(buildopts))