mercurial/cmdutil.py
author Brendan Cully <brendan@kublai.com>
Tue, 24 Oct 2006 13:17:41 -0700
changeset 3498 776c317566b6
parent 3090 eeaf9bcdfa25
child 3524 a33a9af1ec03
permissions -rw-r--r--
zsh: cache hg help output
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2957
6e062d9b188f fix comment.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2885
diff changeset
     1
# cmdutil.py - help for command processing in mercurial
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     2
#
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     3
# Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     4
#
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     6
# of the GNU General Public License, incorporated herein by reference.
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     7
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     8
from demandload import demandload
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     9
from node import *
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    10
from i18n import gettext as _
2958
ff3ea21a981a addremove: add -s/--similarity option
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2957
diff changeset
    11
demandload(globals(), 'mdiff util')
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    12
demandload(globals(), 'os sys')
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    13
3090
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    14
revrangesep = ':'
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    15
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    16
def revfix(repo, val, defval):
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    17
    '''turn user-level id of changeset into rev number.
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    18
    user-level id can be tag, changeset, rev number, or negative rev
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    19
    number relative to number of revs (-1 is tip, etc).'''
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    20
    if not val:
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    21
        return defval
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    22
    try:
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    23
        num = int(val)
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    24
        if str(num) != val:
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    25
            raise ValueError
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    26
        if num < 0:
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    27
            num += repo.changelog.count()
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    28
        if num < 0:
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    29
            num = 0
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    30
        elif num >= repo.changelog.count():
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    31
            raise ValueError
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    32
    except ValueError:
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    33
        try:
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    34
            num = repo.changelog.rev(repo.lookup(val))
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    35
        except KeyError:
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    36
            raise util.Abort(_('invalid revision identifier %s') % val)
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    37
    return num
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    38
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    39
def revpair(ui, repo, revs):
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    40
    '''return pair of nodes, given list of revisions. second item can
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    41
    be None, meaning use working dir.'''
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    42
    if not revs:
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    43
        return repo.dirstate.parents()[0], None
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    44
    end = None
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    45
    if len(revs) == 1:
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    46
        start = revs[0]
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    47
        if revrangesep in start:
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    48
            start, end = start.split(revrangesep, 1)
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    49
            start = revfix(repo, start, 0)
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    50
            end = revfix(repo, end, repo.changelog.count() - 1)
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    51
        else:
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    52
            start = revfix(repo, start, None)
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    53
    elif len(revs) == 2:
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    54
        if revrangesep in revs[0] or revrangesep in revs[1]:
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    55
            raise util.Abort(_('too many revisions specified'))
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    56
        start = revfix(repo, revs[0], None)
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    57
        end = revfix(repo, revs[1], None)
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    58
    else:
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    59
        raise util.Abort(_('too many revisions specified'))
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    60
    if end is not None: end = repo.lookup(str(end))
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    61
    return repo.lookup(str(start)), end
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    62
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    63
def revrange(ui, repo, revs):
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    64
    """Yield revision as strings from a list of revision specifications."""
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    65
    seen = {}
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    66
    for spec in revs:
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    67
        if revrangesep in spec:
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    68
            start, end = spec.split(revrangesep, 1)
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    69
            start = revfix(repo, start, 0)
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    70
            end = revfix(repo, end, repo.changelog.count() - 1)
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    71
            step = start > end and -1 or 1
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    72
            for rev in xrange(start, end+step, step):
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    73
                if rev in seen:
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    74
                    continue
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    75
                seen[rev] = 1
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    76
                yield str(rev)
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    77
        else:
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    78
            rev = revfix(repo, spec, None)
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    79
            if rev in seen:
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    80
                continue
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    81
            seen[rev] = 1
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    82
            yield str(rev)
eeaf9bcdfa25 Move revision parsing into cmdutil.
Brendan Cully <brendan@kublai.com>
parents: 3072
diff changeset
    83
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    84
def make_filename(repo, pat, node,
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    85
                  total=None, seqno=None, revwidth=None, pathname=None):
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    86
    node_expander = {
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    87
        'H': lambda: hex(node),
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    88
        'R': lambda: str(repo.changelog.rev(node)),
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    89
        'h': lambda: short(node),
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    90
        }
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    91
    expander = {
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    92
        '%': lambda: '%',
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    93
        'b': lambda: os.path.basename(repo.root),
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    94
        }
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    95
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    96
    try:
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    97
        if node:
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    98
            expander.update(node_expander)
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    99
        if node and revwidth is not None:
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   100
            expander['r'] = (lambda:
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   101
                    str(repo.changelog.rev(node)).zfill(revwidth))
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   102
        if total is not None:
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   103
            expander['N'] = lambda: str(total)
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   104
        if seqno is not None:
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   105
            expander['n'] = lambda: str(seqno)
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   106
        if total is not None and seqno is not None:
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   107
            expander['n'] = lambda:str(seqno).zfill(len(str(total)))
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   108
        if pathname is not None:
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   109
            expander['s'] = lambda: os.path.basename(pathname)
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   110
            expander['d'] = lambda: os.path.dirname(pathname) or '.'
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   111
            expander['p'] = lambda: pathname
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   112
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   113
        newname = []
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   114
        patlen = len(pat)
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   115
        i = 0
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   116
        while i < patlen:
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   117
            c = pat[i]
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   118
            if c == '%':
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   119
                i += 1
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   120
                c = pat[i]
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   121
                c = expander[c]()
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   122
            newname.append(c)
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   123
            i += 1
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   124
        return ''.join(newname)
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   125
    except KeyError, inst:
3072
bc3fe3b5b785 Never apply string formatting to generated errors with util.Abort.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2958
diff changeset
   126
        raise util.Abort(_("invalid format spec '%%%s' in output file name") %
bc3fe3b5b785 Never apply string formatting to generated errors with util.Abort.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2958
diff changeset
   127
                         inst.args[0])
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   128
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   129
def make_file(repo, pat, node=None,
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   130
              total=None, seqno=None, revwidth=None, mode='wb', pathname=None):
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   131
    if not pat or pat == '-':
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   132
        return 'w' in mode and sys.stdout or sys.stdin
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   133
    if hasattr(pat, 'write') and 'w' in mode:
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   134
        return pat
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   135
    if hasattr(pat, 'read') and 'r' in mode:
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   136
        return pat
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   137
    return open(make_filename(repo, pat, node, total, seqno, revwidth,
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   138
                              pathname),
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   139
                mode)
2882
cf98cd70d2c4 move walk and matchpats from commands to cmdutil.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2874
diff changeset
   140
cf98cd70d2c4 move walk and matchpats from commands to cmdutil.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2874
diff changeset
   141
def matchpats(repo, pats=[], opts={}, head=''):
cf98cd70d2c4 move walk and matchpats from commands to cmdutil.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2874
diff changeset
   142
    cwd = repo.getcwd()
cf98cd70d2c4 move walk and matchpats from commands to cmdutil.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2874
diff changeset
   143
    if not pats and cwd:
2885
bd29a3067b97 cmdutil.matchpats: allow include/exclude to be optional.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2884
diff changeset
   144
        opts['include'] = [os.path.join(cwd, i)
bd29a3067b97 cmdutil.matchpats: allow include/exclude to be optional.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2884
diff changeset
   145
                           for i in opts.get('include', [])]
bd29a3067b97 cmdutil.matchpats: allow include/exclude to be optional.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2884
diff changeset
   146
        opts['exclude'] = [os.path.join(cwd, x)
bd29a3067b97 cmdutil.matchpats: allow include/exclude to be optional.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2884
diff changeset
   147
                           for x in opts.get('exclude', [])]
2882
cf98cd70d2c4 move walk and matchpats from commands to cmdutil.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2874
diff changeset
   148
        cwd = ''
cf98cd70d2c4 move walk and matchpats from commands to cmdutil.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2874
diff changeset
   149
    return util.cmdmatcher(repo.root, cwd, pats or ['.'], opts.get('include'),
cf98cd70d2c4 move walk and matchpats from commands to cmdutil.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2874
diff changeset
   150
                           opts.get('exclude'), head)
cf98cd70d2c4 move walk and matchpats from commands to cmdutil.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2874
diff changeset
   151
2884
fcdcf0c19998 add default values to arguments of walk etc.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2883
diff changeset
   152
def makewalk(repo, pats=[], opts={}, node=None, head='', badmatch=None):
2882
cf98cd70d2c4 move walk and matchpats from commands to cmdutil.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2874
diff changeset
   153
    files, matchfn, anypats = matchpats(repo, pats, opts, head)
cf98cd70d2c4 move walk and matchpats from commands to cmdutil.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2874
diff changeset
   154
    exact = dict(zip(files, files))
cf98cd70d2c4 move walk and matchpats from commands to cmdutil.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2874
diff changeset
   155
    def walk():
cf98cd70d2c4 move walk and matchpats from commands to cmdutil.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2874
diff changeset
   156
        for src, fn in repo.walk(node=node, files=files, match=matchfn,
cf98cd70d2c4 move walk and matchpats from commands to cmdutil.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2874
diff changeset
   157
                                 badmatch=badmatch):
cf98cd70d2c4 move walk and matchpats from commands to cmdutil.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2874
diff changeset
   158
            yield src, fn, util.pathto(repo.getcwd(), fn), fn in exact
cf98cd70d2c4 move walk and matchpats from commands to cmdutil.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2874
diff changeset
   159
    return files, matchfn, walk()
cf98cd70d2c4 move walk and matchpats from commands to cmdutil.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2874
diff changeset
   160
2884
fcdcf0c19998 add default values to arguments of walk etc.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2883
diff changeset
   161
def walk(repo, pats=[], opts={}, node=None, head='', badmatch=None):
2882
cf98cd70d2c4 move walk and matchpats from commands to cmdutil.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2874
diff changeset
   162
    files, matchfn, results = makewalk(repo, pats, opts, node, head, badmatch)
cf98cd70d2c4 move walk and matchpats from commands to cmdutil.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2874
diff changeset
   163
    for r in results:
cf98cd70d2c4 move walk and matchpats from commands to cmdutil.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2874
diff changeset
   164
        yield r
2883
c2932ad5476a move commands.addremove_lock to cmdutil.addremove
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2882
diff changeset
   165
2958
ff3ea21a981a addremove: add -s/--similarity option
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2957
diff changeset
   166
def findrenames(repo, added=None, removed=None, threshold=0.5):
ff3ea21a981a addremove: add -s/--similarity option
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2957
diff changeset
   167
    if added is None or removed is None:
ff3ea21a981a addremove: add -s/--similarity option
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2957
diff changeset
   168
        added, removed = repo.status()[1:3]
ff3ea21a981a addremove: add -s/--similarity option
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2957
diff changeset
   169
    changes = repo.changelog.read(repo.dirstate.parents()[0])
ff3ea21a981a addremove: add -s/--similarity option
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2957
diff changeset
   170
    mf = repo.manifest.read(changes[0])
ff3ea21a981a addremove: add -s/--similarity option
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2957
diff changeset
   171
    for a in added:
ff3ea21a981a addremove: add -s/--similarity option
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2957
diff changeset
   172
        aa = repo.wread(a)
ff3ea21a981a addremove: add -s/--similarity option
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2957
diff changeset
   173
        bestscore, bestname = None, None
ff3ea21a981a addremove: add -s/--similarity option
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2957
diff changeset
   174
        for r in removed:
ff3ea21a981a addremove: add -s/--similarity option
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2957
diff changeset
   175
            rr = repo.file(r).read(mf[r])
ff3ea21a981a addremove: add -s/--similarity option
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2957
diff changeset
   176
            delta = mdiff.textdiff(aa, rr)
ff3ea21a981a addremove: add -s/--similarity option
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2957
diff changeset
   177
            if len(delta) < len(aa):
ff3ea21a981a addremove: add -s/--similarity option
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2957
diff changeset
   178
                myscore = 1.0 - (float(len(delta)) / len(aa))
ff3ea21a981a addremove: add -s/--similarity option
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2957
diff changeset
   179
                if bestscore is None or myscore > bestscore:
ff3ea21a981a addremove: add -s/--similarity option
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2957
diff changeset
   180
                    bestscore, bestname = myscore, r
ff3ea21a981a addremove: add -s/--similarity option
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2957
diff changeset
   181
        if bestname and bestscore >= threshold:
ff3ea21a981a addremove: add -s/--similarity option
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2957
diff changeset
   182
            yield bestname, a, bestscore
ff3ea21a981a addremove: add -s/--similarity option
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2957
diff changeset
   183
ff3ea21a981a addremove: add -s/--similarity option
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2957
diff changeset
   184
def addremove(repo, pats=[], opts={}, wlock=None, dry_run=None,
ff3ea21a981a addremove: add -s/--similarity option
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2957
diff changeset
   185
              similarity=None):
2883
c2932ad5476a move commands.addremove_lock to cmdutil.addremove
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2882
diff changeset
   186
    if dry_run is None:
c2932ad5476a move commands.addremove_lock to cmdutil.addremove
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2882
diff changeset
   187
        dry_run = opts.get('dry_run')
2958
ff3ea21a981a addremove: add -s/--similarity option
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2957
diff changeset
   188
    if similarity is None:
ff3ea21a981a addremove: add -s/--similarity option
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2957
diff changeset
   189
        similarity = float(opts.get('similarity') or 0)
2883
c2932ad5476a move commands.addremove_lock to cmdutil.addremove
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2882
diff changeset
   190
    add, remove = [], []
2958
ff3ea21a981a addremove: add -s/--similarity option
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2957
diff changeset
   191
    mapping = {}
2883
c2932ad5476a move commands.addremove_lock to cmdutil.addremove
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2882
diff changeset
   192
    for src, abs, rel, exact in walk(repo, pats, opts):
c2932ad5476a move commands.addremove_lock to cmdutil.addremove
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2882
diff changeset
   193
        if src == 'f' and repo.dirstate.state(abs) == '?':
c2932ad5476a move commands.addremove_lock to cmdutil.addremove
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2882
diff changeset
   194
            add.append(abs)
2958
ff3ea21a981a addremove: add -s/--similarity option
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2957
diff changeset
   195
            mapping[abs] = rel, exact
2883
c2932ad5476a move commands.addremove_lock to cmdutil.addremove
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2882
diff changeset
   196
            if repo.ui.verbose or not exact:
c2932ad5476a move commands.addremove_lock to cmdutil.addremove
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2882
diff changeset
   197
                repo.ui.status(_('adding %s\n') % ((pats and rel) or abs))
c2932ad5476a move commands.addremove_lock to cmdutil.addremove
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2882
diff changeset
   198
        if repo.dirstate.state(abs) != 'r' and not os.path.exists(rel):
c2932ad5476a move commands.addremove_lock to cmdutil.addremove
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2882
diff changeset
   199
            remove.append(abs)
2958
ff3ea21a981a addremove: add -s/--similarity option
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2957
diff changeset
   200
            mapping[abs] = rel, exact
2883
c2932ad5476a move commands.addremove_lock to cmdutil.addremove
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2882
diff changeset
   201
            if repo.ui.verbose or not exact:
c2932ad5476a move commands.addremove_lock to cmdutil.addremove
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2882
diff changeset
   202
                repo.ui.status(_('removing %s\n') % ((pats and rel) or abs))
c2932ad5476a move commands.addremove_lock to cmdutil.addremove
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2882
diff changeset
   203
    if not dry_run:
c2932ad5476a move commands.addremove_lock to cmdutil.addremove
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2882
diff changeset
   204
        repo.add(add, wlock=wlock)
c2932ad5476a move commands.addremove_lock to cmdutil.addremove
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2882
diff changeset
   205
        repo.remove(remove, wlock=wlock)
2958
ff3ea21a981a addremove: add -s/--similarity option
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2957
diff changeset
   206
    if similarity > 0:
ff3ea21a981a addremove: add -s/--similarity option
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2957
diff changeset
   207
        for old, new, score in findrenames(repo, add, remove, similarity):
ff3ea21a981a addremove: add -s/--similarity option
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2957
diff changeset
   208
            oldrel, oldexact = mapping[old]
ff3ea21a981a addremove: add -s/--similarity option
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2957
diff changeset
   209
            newrel, newexact = mapping[new]
ff3ea21a981a addremove: add -s/--similarity option
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2957
diff changeset
   210
            if repo.ui.verbose or not oldexact or not newexact:
ff3ea21a981a addremove: add -s/--similarity option
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2957
diff changeset
   211
                repo.ui.status(_('recording removal of %s as rename to %s '
ff3ea21a981a addremove: add -s/--similarity option
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2957
diff changeset
   212
                                 '(%d%% similar)\n') %
ff3ea21a981a addremove: add -s/--similarity option
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2957
diff changeset
   213
                               (oldrel, newrel, score * 100))
ff3ea21a981a addremove: add -s/--similarity option
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2957
diff changeset
   214
            if not dry_run:
ff3ea21a981a addremove: add -s/--similarity option
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2957
diff changeset
   215
                repo.copy(old, new, wlock=wlock)