mercurial/patch.py
author Gregory Szorc <gregory.szorc@gmail.com>
Sun, 06 Oct 2019 17:59:15 -0400
changeset 43104 74802979dd9d
parent 43097 27c4f93d07a9
child 43106 d783f945a701
permissions -rw-r--r--
py3: define and use pycompat.itervalues() .itervalues() only exists on Python 2. Python 3's equivalent is .values(). But we don't want to blindly use .values() everywhere because on Python 2, it will create a list, which will have performance implications. This commit introduces pycompat.itervalues() which will call the appropriate method on the passed object. We update all callers of obj.itervalues() to pycompat.itervalues(obj) instead. With this commit, the only source tranforming remaining is for iteritems(). Victory is near... Differential Revision: https://phab.mercurial-scm.org/D7013
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2861
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
     1
# patch.py - patch file parsing routines
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
     2
#
2865
71e78f2ca5ae merge git patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2863
diff changeset
     3
# Copyright 2006 Brendan Cully <brendan@kublai.com>
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
     4
# Copyright 2007 Chris Mason <chris.mason@oracle.com>
2865
71e78f2ca5ae merge git patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2863
diff changeset
     5
#
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 8209
diff changeset
     6
# This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 10203
diff changeset
     7
# GNU General Public License version 2 or any later version.
2861
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
     8
34152
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34146
diff changeset
     9
from __future__ import absolute_import, print_function
27485
60183975b5bc patch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27412
diff changeset
    10
25113
0ca8410ea345 util: drop alias for collections.deque
Martin von Zweigbergk <martinvonz@google.com>
parents: 24845
diff changeset
    11
import collections
37621
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
    12
import contextlib
27485
60183975b5bc patch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27412
diff changeset
    13
import copy
60183975b5bc patch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27412
diff changeset
    14
import email
60183975b5bc patch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27412
diff changeset
    15
import errno
29341
0d83ad967bf8 cleanup: replace uses of util.(md5|sha1|sha256|sha512) with hashlib.\1
Augie Fackler <raf@durin42.com>
parents: 29326
diff changeset
    16
import hashlib
27485
60183975b5bc patch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27412
diff changeset
    17
import os
60183975b5bc patch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27412
diff changeset
    18
import re
60183975b5bc patch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27412
diff changeset
    19
import shutil
60183975b5bc patch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27412
diff changeset
    20
import zlib
10965
7faef79a89c7 patch: move mercurial-specific imports after stdlib imports
Augie Fackler <durin42@gmail.com>
parents: 10905
diff changeset
    21
27485
60183975b5bc patch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27412
diff changeset
    22
from .i18n import _
60183975b5bc patch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27412
diff changeset
    23
from .node import (
60183975b5bc patch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27412
diff changeset
    24
    hex,
60183975b5bc patch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27412
diff changeset
    25
    short,
60183975b5bc patch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27412
diff changeset
    26
)
43085
eef9a2d67051 py3: manually import pycompat.open into files that need it
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43077
diff changeset
    27
from .pycompat import open
27485
60183975b5bc patch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27412
diff changeset
    28
from . import (
60183975b5bc patch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27412
diff changeset
    29
    copies,
37803
72f6498c040b diffhelper: rename module to avoid conflicts with ancient C module (issue5846)
Yuya Nishihara <yuya@tcha.org>
parents: 37764
diff changeset
    30
    diffhelper,
38589
1c93e0237a24 diffutil: move the module out of utils package
Yuya Nishihara <yuya@tcha.org>
parents: 38588
diff changeset
    31
    diffutil,
27485
60183975b5bc patch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27412
diff changeset
    32
    encoding,
60183975b5bc patch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27412
diff changeset
    33
    error,
28341
8286f551b7ee patch: when importing from email, RFC2047-decode From/Subject headers
Julien Cristau <julien.cristau@logilab.fr>
parents: 27902
diff changeset
    34
    mail,
27485
60183975b5bc patch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27412
diff changeset
    35
    mdiff,
60183975b5bc patch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27412
diff changeset
    36
    pathutil,
30944
48dea083f66d py3: convert the mode argument of os.fdopen to unicodes (1 of 2)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30819
diff changeset
    37
    pycompat,
27485
60183975b5bc patch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27412
diff changeset
    38
    scmutil,
30807
6381a6dbc325 patch: use opt.showsimilarity to calculate and show the similarity
Sean Farley <sean@farley.io>
parents: 30806
diff changeset
    39
    similar,
27485
60183975b5bc patch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27412
diff changeset
    40
    util,
31243
067f2a95e32c vfs: use 'vfs' module directly in 'mercurial.patch'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31226
diff changeset
    41
    vfs as vfsmod,
27485
60183975b5bc patch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27412
diff changeset
    42
)
37087
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36846
diff changeset
    43
from .utils import (
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36846
diff changeset
    44
    dateutil,
37123
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37087
diff changeset
    45
    procutil,
37087
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36846
diff changeset
    46
    stringutil,
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36846
diff changeset
    47
)
32409
017ad85e5ac8 diffhelpers: switch to policy importer
Yuya Nishihara <yuya@tcha.org>
parents: 32360
diff changeset
    48
28861
86db5cb55d46 pycompat: switch to util.stringio for py3 compat
timeless <timeless@mozdev.org>
parents: 28341
diff changeset
    49
stringio = util.stringio
2866
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
    50
31635
451c980a8b57 patch: make regular expressions bytes by adding b''
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31284
diff changeset
    51
gitre = re.compile(br'diff --git a/(.*) b/(.*)')
451c980a8b57 patch: make regular expressions bytes by adding b''
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31284
diff changeset
    52
tabsplitter = re.compile(br'(\t+|[^\t]+)')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
    53
wordsplitter = re.compile(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
    54
    br'(\t+| +|[a-zA-Z0-9_\x80-\xff]+|' b'[^ \ta-zA-Z0-9_\x80-\xff])'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
    55
)
7199
dd891d0d97a3 patch: consolidate two different regexes for parsing of git diffs
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7198
diff changeset
    56
34258
61714510220d error: move patch.PatchError so it can easily implement __bytes__ (API)
Yuya Nishihara <yuya@tcha.org>
parents: 34152
diff changeset
    57
PatchError = error.PatchError
2933
439fd013360d Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents: 2922
diff changeset
    58
439fd013360d Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents: 2922
diff changeset
    59
# public functions
439fd013360d Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents: 2922
diff changeset
    60
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
    61
10384
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
    62
def split(stream):
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
    63
    '''return an iterator of individual patches from a stream'''
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
    64
10384
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
    65
    def isheader(line, inheader):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    66
        if inheader and line.startswith((b' ', b'\t')):
10384
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
    67
            # continuation
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
    68
            return True
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    69
        if line.startswith((b' ', b'-', b'+')):
10883
196908117c27 patch: don't look for headers in diff lines
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 10748
diff changeset
    70
            # diff line - don't check for header pattern in there
196908117c27 patch: don't look for headers in diff lines
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 10748
diff changeset
    71
            return False
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    72
        l = line.split(b': ', 1)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    73
        return len(l) == 2 and b' ' not in l[0]
10384
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
    74
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
    75
    def chunk(lines):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    76
        return stringio(b''.join(lines))
10384
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
    77
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
    78
    def hgsplit(stream, cur):
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
    79
        inheader = True
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
    80
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
    81
        for line in stream:
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
    82
            if not line.strip():
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
    83
                inheader = False
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    84
            if not inheader and line.startswith(b'# HG changeset patch'):
10384
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
    85
                yield chunk(cur)
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
    86
                cur = []
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
    87
                inheader = True
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
    88
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
    89
            cur.append(line)
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
    90
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
    91
        if cur:
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
    92
            yield chunk(cur)
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
    93
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
    94
    def mboxsplit(stream, cur):
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
    95
        for line in stream:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    96
            if line.startswith(b'From '):
10384
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
    97
                for c in split(chunk(cur[1:])):
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
    98
                    yield c
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
    99
                cur = []
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   100
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   101
            cur.append(line)
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   102
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   103
        if cur:
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   104
            for c in split(chunk(cur[1:])):
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   105
                yield c
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   106
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   107
    def mimesplit(stream, cur):
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   108
        def msgfp(m):
28861
86db5cb55d46 pycompat: switch to util.stringio for py3 compat
timeless <timeless@mozdev.org>
parents: 28341
diff changeset
   109
            fp = stringio()
10384
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   110
            g = email.Generator.Generator(fp, mangle_from_=False)
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   111
            g.flatten(m)
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   112
            fp.seek(0)
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   113
            return fp
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   114
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   115
        for line in stream:
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   116
            cur.append(line)
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   117
        c = chunk(cur)
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   118
38341
7b12a2d2eedc py3: ditch email.parser.BytesParser which appears to be plain crap
Yuya Nishihara <yuya@tcha.org>
parents: 38338
diff changeset
   119
        m = mail.parse(c)
10384
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   120
        if not m.is_multipart():
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   121
            yield msgfp(m)
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   122
        else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   123
            ok_types = (b'text/plain', b'text/x-diff', b'text/x-patch')
10384
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   124
            for part in m.walk():
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   125
                ct = part.get_content_type()
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   126
                if ct not in ok_types:
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   127
                    continue
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   128
                yield msgfp(part)
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   129
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   130
    def headersplit(stream, cur):
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   131
        inheader = False
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   132
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   133
        for line in stream:
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   134
            if not inheader and isheader(line, inheader):
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   135
                yield chunk(cur)
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   136
                cur = []
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   137
                inheader = True
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   138
            if inheader and not isheader(line, inheader):
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   139
                inheader = False
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   140
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   141
            cur.append(line)
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   142
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   143
        if cur:
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   144
            yield chunk(cur)
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   145
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   146
    def remainder(cur):
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   147
        yield chunk(cur)
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   148
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   149
    class fiter(object):
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   150
        def __init__(self, fp):
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   151
            self.fp = fp
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   152
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   153
        def __iter__(self):
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   154
            return self
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   155
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   156
        def next(self):
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   157
            l = self.fp.readline()
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   158
            if not l:
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   159
                raise StopIteration
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   160
            return l
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   161
35202
a1d2fc32bb99 py3: define __next__ in patch.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35085
diff changeset
   162
        __next__ = next
a1d2fc32bb99 py3: define __next__ in patch.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35085
diff changeset
   163
10384
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   164
    inheader = False
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   165
    cur = []
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   166
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   167
    mimeheaders = [b'content-type']
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   168
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   169
    if not util.safehasattr(stream, b'next'):
10384
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   170
        # http responses, for example, have readline but not next
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   171
        stream = fiter(stream)
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   172
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   173
    for line in stream:
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   174
        cur.append(line)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   175
        if line.startswith(b'# HG changeset patch'):
10384
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   176
            return hgsplit(stream, cur)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   177
        elif line.startswith(b'From '):
10384
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   178
            return mboxsplit(stream, cur)
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   179
        elif isheader(line, inheader):
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   180
            inheader = True
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   181
            if line.split(b':', 1)[0].lower() in mimeheaders:
10384
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   182
                # let email parser handle this
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   183
                return mimesplit(stream, cur)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   184
        elif line.startswith(b'--- ') and inheader:
10501
a27af7229850 import: if in doubt, consume stream until start of diff
Brendan Cully <brendan@kublai.com>
parents: 10467
diff changeset
   185
            # No evil headers seen by diff start, split by hand
10384
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   186
            return headersplit(stream, cur)
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   187
        # Not enough info, keep reading
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   188
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   189
    # if we are here, we have a very plain patch
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   190
    return remainder(cur)
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
   191
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   192
26557
23f3f1cbd53b extract: add some facility for extensible header parsing
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26556
diff changeset
   193
## Some facility for extensible patch parsing:
23f3f1cbd53b extract: add some facility for extensible header parsing
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26556
diff changeset
   194
# list of pairs ("header to match", "data key")
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   195
patchheadermap = [
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   196
    (b'Date', b'date'),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   197
    (b'Branch', b'branch'),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   198
    (b'Node ID', b'nodeid'),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   199
]
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   200
26557
23f3f1cbd53b extract: add some facility for extensible header parsing
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26556
diff changeset
   201
37621
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   202
@contextlib.contextmanager
2866
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
   203
def extract(ui, fileobj):
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
   204
    '''extract patch from data read from fileobj.
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
   205
4263
47ba52121433 Add import --exact.
Brendan Cully <brendan@kublai.com>
parents: 4232
diff changeset
   206
    patch can be a normal patch or contained in an email message.
2866
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
   207
26781
1aee2ab0f902 spelling: trivial spell checking
Mads Kiilerich <madski@unity3d.com>
parents: 26587
diff changeset
   208
    return a dictionary. Standard keys are:
26547
b9be8ab6e628 patch: move 'extract' return to a dictionnary
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26421
diff changeset
   209
      - filename,
b9be8ab6e628 patch: move 'extract' return to a dictionnary
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26421
diff changeset
   210
      - message,
b9be8ab6e628 patch: move 'extract' return to a dictionnary
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26421
diff changeset
   211
      - user,
b9be8ab6e628 patch: move 'extract' return to a dictionnary
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26421
diff changeset
   212
      - date,
b9be8ab6e628 patch: move 'extract' return to a dictionnary
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26421
diff changeset
   213
      - branch,
b9be8ab6e628 patch: move 'extract' return to a dictionnary
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26421
diff changeset
   214
      - node,
b9be8ab6e628 patch: move 'extract' return to a dictionnary
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26421
diff changeset
   215
      - p1,
b9be8ab6e628 patch: move 'extract' return to a dictionnary
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26421
diff changeset
   216
      - p2.
26781
1aee2ab0f902 spelling: trivial spell checking
Mads Kiilerich <madski@unity3d.com>
parents: 26587
diff changeset
   217
    Any item can be missing from the dictionary. If filename is missing,
4263
47ba52121433 Add import --exact.
Brendan Cully <brendan@kublai.com>
parents: 4232
diff changeset
   218
    fileobj did not contain a patch. Caller must unlink filename when done.'''
2866
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
   219
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   220
    fd, tmpname = pycompat.mkstemp(prefix=b'hg-patch-')
37621
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   221
    tmpfp = os.fdopen(fd, r'wb')
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   222
    try:
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   223
        yield _extract(ui, fileobj, tmpname, tmpfp)
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   224
    finally:
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   225
        tmpfp.close()
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   226
        os.unlink(tmpname)
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   227
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   228
37621
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   229
def _extract(ui, fileobj, tmpname, tmpfp):
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   230
2866
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
   231
    # attempt to detect the start of a patch
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
   232
    # (this heuristic is borrowed from quilt)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   233
    diffre = re.compile(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   234
        br'^(?:Index:[ \t]|diff[ \t]-|RCS file: |'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   235
        br'retrieving revision [0-9]+(\.[0-9]+)*$|'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   236
        br'---[ \t].*?^\+\+\+[ \t]|'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   237
        br'\*\*\*[ \t].*?^---[ \t])',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   238
        re.MULTILINE | re.DOTALL,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   239
    )
2866
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
   240
26547
b9be8ab6e628 patch: move 'extract' return to a dictionnary
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26421
diff changeset
   241
    data = {}
37621
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   242
38341
7b12a2d2eedc py3: ditch email.parser.BytesParser which appears to be plain crap
Yuya Nishihara <yuya@tcha.org>
parents: 38338
diff changeset
   243
    msg = mail.parse(fileobj)
2866
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
   244
37621
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   245
    subject = msg[r'Subject'] and mail.headdecode(msg[r'Subject'])
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   246
    data[b'user'] = msg[r'From'] and mail.headdecode(msg[r'From'])
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   247
    if not subject and not data[b'user']:
37621
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   248
        # Not an email, restore parsed headers if any
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   249
        subject = (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   250
            b'\n'.join(
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   251
                b': '.join(map(encoding.strtolocal, h)) for h in msg.items()
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   252
            )
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   253
            + b'\n'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   254
        )
9573
b8352a3617f3 patch: do not swallow header-like patch first line (issue1859)
Patrick Mezard <pmezard@gmail.com>
parents: 9243
diff changeset
   255
37621
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   256
    # should try to parse msg['Date']
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   257
    parents = []
2866
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
   258
43097
27c4f93d07a9 import: read X-Mercurial-Node email header to determine nodeid
Denis Laxalde <denis@laxalde.org>
parents: 43085
diff changeset
   259
    nodeid = msg[r'X-Mercurial-Node']
27c4f93d07a9 import: read X-Mercurial-Node email header to determine nodeid
Denis Laxalde <denis@laxalde.org>
parents: 43085
diff changeset
   260
    if nodeid:
27c4f93d07a9 import: read X-Mercurial-Node email header to determine nodeid
Denis Laxalde <denis@laxalde.org>
parents: 43085
diff changeset
   261
        data[b'nodeid'] = nodeid = mail.headdecode(nodeid)
27c4f93d07a9 import: read X-Mercurial-Node email header to determine nodeid
Denis Laxalde <denis@laxalde.org>
parents: 43085
diff changeset
   262
        ui.debug(b'Node ID: %s\n' % nodeid)
27c4f93d07a9 import: read X-Mercurial-Node email header to determine nodeid
Denis Laxalde <denis@laxalde.org>
parents: 43085
diff changeset
   263
37621
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   264
    if subject:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   265
        if subject.startswith(b'[PATCH'):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   266
            pend = subject.find(b']')
37621
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   267
            if pend >= 0:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   268
                subject = subject[pend + 1 :].lstrip()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   269
        subject = re.sub(br'\n[ \t]+', b' ', subject)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   270
        ui.debug(b'Subject: %s\n' % subject)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   271
    if data[b'user']:
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   272
        ui.debug(b'From: %s\n' % data[b'user'])
37621
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   273
    diffs_seen = 0
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   274
    ok_types = (b'text/plain', b'text/x-diff', b'text/x-patch')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   275
    message = b''
37621
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   276
    for part in msg.walk():
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   277
        content_type = pycompat.bytestr(part.get_content_type())
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   278
        ui.debug(b'Content-Type: %s\n' % content_type)
37621
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   279
        if content_type not in ok_types:
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   280
            continue
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   281
        payload = part.get_payload(decode=True)
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   282
        m = diffre.search(payload)
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   283
        if m:
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   284
            hgpatch = False
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   285
            hgpatchheader = False
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   286
            ignoretext = False
4220
1253703853a8 git-send-email compatibility: stop reading changelog after ^---$
Brendan Cully <brendan@kublai.com>
parents: 4208
diff changeset
   287
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   288
            ui.debug(b'found patch at byte %d\n' % m.start(0))
37621
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   289
            diffs_seen += 1
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   290
            cfp = stringio()
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   291
            for line in payload[: m.start(0)].splitlines():
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   292
                if line.startswith(b'# HG changeset patch') and not hgpatch:
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   293
                    ui.debug(b'patch generated by hg export\n')
37621
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   294
                    hgpatch = True
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   295
                    hgpatchheader = True
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   296
                    # drop earlier commit message content
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   297
                    cfp.seek(0)
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   298
                    cfp.truncate()
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   299
                    subject = None
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   300
                elif hgpatchheader:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   301
                    if line.startswith(b'# User '):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   302
                        data[b'user'] = line[7:]
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   303
                        ui.debug(b'From: %s\n' % data[b'user'])
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   304
                    elif line.startswith(b"# Parent "):
37621
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   305
                        parents.append(line[9:].lstrip())
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   306
                    elif line.startswith(b"# "):
37621
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   307
                        for header, key in patchheadermap:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   308
                            prefix = b'# %s ' % header
37621
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   309
                            if line.startswith(prefix):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   310
                                data[key] = line[len(prefix) :]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   311
                                ui.debug(b'%s: %s\n' % (header, data[key]))
37621
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   312
                    else:
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   313
                        hgpatchheader = False
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   314
                elif line == b'---':
37621
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   315
                    ignoretext = True
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   316
                if not hgpatchheader and not ignoretext:
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   317
                    cfp.write(line)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   318
                    cfp.write(b'\n')
37621
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   319
            message = cfp.getvalue()
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   320
            if tmpfp:
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   321
                tmpfp.write(payload)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   322
                if not payload.endswith(b'\n'):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   323
                    tmpfp.write(b'\n')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   324
        elif not diffs_seen and message and content_type == b'text/plain':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   325
            message += b'\n' + payload
2866
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
   326
4777
5ee5cbfceff3 patch.extract: do not prepend subject if the description already starts with it
Brendan Cully <brendan@kublai.com>
parents: 4659
diff changeset
   327
    if subject and not message.startswith(subject):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   328
        message = b'%s\n%s' % (subject, message)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   329
    data[b'message'] = message
2866
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
   330
    tmpfp.close()
24306
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24269
diff changeset
   331
    if parents:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   332
        data[b'p1'] = parents.pop(0)
26548
25a58881efdd extract: simplify parents assignement
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26547
diff changeset
   333
        if parents:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   334
            data[b'p2'] = parents.pop(0)
24306
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24269
diff changeset
   335
26555
1e33384ff2ed extract: use a single return
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26554
diff changeset
   336
    if diffs_seen:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   337
        data[b'filename'] = tmpname
37621
5537d8f5e989 patch: make extract() a context manager (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37574
diff changeset
   338
26547
b9be8ab6e628 patch: move 'extract' return to a dictionnary
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26421
diff changeset
   339
    return data
2861
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   340
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   341
8778
c5f36402daad use new style classes
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8761
diff changeset
   342
class patchmeta(object):
7148
7d84e5b00e29 patch: extract and rename gitpatch into patchmeta, document
Patrick Mezard <pmezard@gmail.com>
parents: 7147
diff changeset
   343
    """Patched file metadata
7d84e5b00e29 patch: extract and rename gitpatch into patchmeta, document
Patrick Mezard <pmezard@gmail.com>
parents: 7147
diff changeset
   344
7d84e5b00e29 patch: extract and rename gitpatch into patchmeta, document
Patrick Mezard <pmezard@gmail.com>
parents: 7147
diff changeset
   345
    'op' is the performed operation within ADD, DELETE, RENAME, MODIFY
7d84e5b00e29 patch: extract and rename gitpatch into patchmeta, document
Patrick Mezard <pmezard@gmail.com>
parents: 7147
diff changeset
   346
    or COPY.  'path' is patched file path. 'oldpath' is set to the
7149
01a056c54385 patch: patchmeta gives (islink, isexec) tuple instead of int mode
Patrick Mezard <pmezard@gmail.com>
parents: 7148
diff changeset
   347
    origin file when 'op' is either COPY or RENAME, None otherwise. If
01a056c54385 patch: patchmeta gives (islink, isexec) tuple instead of int mode
Patrick Mezard <pmezard@gmail.com>
parents: 7148
diff changeset
   348
    file mode is changed, 'mode' is a tuple (islink, isexec) where
01a056c54385 patch: patchmeta gives (islink, isexec) tuple instead of int mode
Patrick Mezard <pmezard@gmail.com>
parents: 7148
diff changeset
   349
    'islink' is True if the file is a symlink and 'isexec' is True if
01a056c54385 patch: patchmeta gives (islink, isexec) tuple instead of int mode
Patrick Mezard <pmezard@gmail.com>
parents: 7148
diff changeset
   350
    the file is executable. Otherwise, 'mode' is None.
7148
7d84e5b00e29 patch: extract and rename gitpatch into patchmeta, document
Patrick Mezard <pmezard@gmail.com>
parents: 7147
diff changeset
   351
    """
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   352
7148
7d84e5b00e29 patch: extract and rename gitpatch into patchmeta, document
Patrick Mezard <pmezard@gmail.com>
parents: 7147
diff changeset
   353
    def __init__(self, path):
7d84e5b00e29 patch: extract and rename gitpatch into patchmeta, document
Patrick Mezard <pmezard@gmail.com>
parents: 7147
diff changeset
   354
        self.path = path
7d84e5b00e29 patch: extract and rename gitpatch into patchmeta, document
Patrick Mezard <pmezard@gmail.com>
parents: 7147
diff changeset
   355
        self.oldpath = None
7d84e5b00e29 patch: extract and rename gitpatch into patchmeta, document
Patrick Mezard <pmezard@gmail.com>
parents: 7147
diff changeset
   356
        self.mode = None
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   357
        self.op = b'MODIFY'
7148
7d84e5b00e29 patch: extract and rename gitpatch into patchmeta, document
Patrick Mezard <pmezard@gmail.com>
parents: 7147
diff changeset
   358
        self.binary = False
7d84e5b00e29 patch: extract and rename gitpatch into patchmeta, document
Patrick Mezard <pmezard@gmail.com>
parents: 7147
diff changeset
   359
7149
01a056c54385 patch: patchmeta gives (islink, isexec) tuple instead of int mode
Patrick Mezard <pmezard@gmail.com>
parents: 7148
diff changeset
   360
    def setmode(self, mode):
25658
e93036747902 global: mass rewrite to use modern octal syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25644
diff changeset
   361
        islink = mode & 0o20000
e93036747902 global: mass rewrite to use modern octal syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25644
diff changeset
   362
        isexec = mode & 0o100
7149
01a056c54385 patch: patchmeta gives (islink, isexec) tuple instead of int mode
Patrick Mezard <pmezard@gmail.com>
parents: 7148
diff changeset
   363
        self.mode = (islink, isexec)
01a056c54385 patch: patchmeta gives (islink, isexec) tuple instead of int mode
Patrick Mezard <pmezard@gmail.com>
parents: 7148
diff changeset
   364
14566
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
   365
    def copy(self):
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
   366
        other = patchmeta(self.path)
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
   367
        other.oldpath = self.oldpath
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
   368
        other.mode = self.mode
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
   369
        other.op = self.op
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
   370
        other.binary = self.binary
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
   371
        return other
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
   372
16506
fc4e0fecf403 patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents: 16475
diff changeset
   373
    def _ispatchinga(self, afile):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   374
        if afile == b'/dev/null':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   375
            return self.op == b'ADD'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   376
        return afile == b'a/' + (self.oldpath or self.path)
16506
fc4e0fecf403 patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents: 16475
diff changeset
   377
fc4e0fecf403 patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents: 16475
diff changeset
   378
    def _ispatchingb(self, bfile):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   379
        if bfile == b'/dev/null':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   380
            return self.op == b'DELETE'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   381
        return bfile == b'b/' + self.path
16506
fc4e0fecf403 patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents: 16475
diff changeset
   382
fc4e0fecf403 patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents: 16475
diff changeset
   383
    def ispatching(self, afile, bfile):
fc4e0fecf403 patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents: 16475
diff changeset
   384
        return self._ispatchinga(afile) and self._ispatchingb(bfile)
fc4e0fecf403 patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents: 16475
diff changeset
   385
11018
17cf756ba25d patch: descriptive patchmeta.__repr__ to help debugging
Mads Kiilerich <mads@kiilerich.com>
parents: 10966
diff changeset
   386
    def __repr__(self):
41635
3751595ec45e py3: make sure __repr__ returns str
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41631
diff changeset
   387
        return r"<patchmeta %s %r>" % (self.op, self.path)
11018
17cf756ba25d patch: descriptive patchmeta.__repr__ to help debugging
Mads Kiilerich <mads@kiilerich.com>
parents: 10966
diff changeset
   388
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   389
7152
f0055cec8446 patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 7151
diff changeset
   390
def readgitpatch(lr):
2861
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   391
    """extract git-style metadata about patches from <patchname>"""
3223
53e843840349 Whitespace/Tab cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3199
diff changeset
   392
2861
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   393
    # Filter patch for git information
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   394
    gp = None
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   395
    gitpatches = []
7152
f0055cec8446 patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 7151
diff changeset
   396
    for line in lr:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   397
        line = line.rstrip(b' \r\n')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   398
        if line.startswith(b'diff --git a/'):
2861
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   399
            m = gitre.match(line)
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   400
            if m:
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   401
                if gp:
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   402
                    gitpatches.append(gp)
9392
039bce1b505f patch: readgitpatch: remove unused variable 'src'
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9331
diff changeset
   403
                dst = m.group(2)
7148
7d84e5b00e29 patch: extract and rename gitpatch into patchmeta, document
Patrick Mezard <pmezard@gmail.com>
parents: 7147
diff changeset
   404
                gp = patchmeta(dst)
2861
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   405
        elif gp:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   406
            if line.startswith(b'--- '):
2861
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   407
                gitpatches.append(gp)
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   408
                gp = None
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   409
                continue
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   410
            if line.startswith(b'rename from '):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   411
                gp.op = b'RENAME'
9243
df21a009c9c4 fix issue 1763: strip chars from end of line when parsing gitpatch lines
Bill Barry <after.fallout@gmail.com>
parents: 9123
diff changeset
   412
                gp.oldpath = line[12:]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   413
            elif line.startswith(b'rename to '):
9243
df21a009c9c4 fix issue 1763: strip chars from end of line when parsing gitpatch lines
Bill Barry <after.fallout@gmail.com>
parents: 9123
diff changeset
   414
                gp.path = line[10:]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   415
            elif line.startswith(b'copy from '):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   416
                gp.op = b'COPY'
9243
df21a009c9c4 fix issue 1763: strip chars from end of line when parsing gitpatch lines
Bill Barry <after.fallout@gmail.com>
parents: 9123
diff changeset
   417
                gp.oldpath = line[10:]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   418
            elif line.startswith(b'copy to '):
9243
df21a009c9c4 fix issue 1763: strip chars from end of line when parsing gitpatch lines
Bill Barry <after.fallout@gmail.com>
parents: 9123
diff changeset
   419
                gp.path = line[8:]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   420
            elif line.startswith(b'deleted file'):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   421
                gp.op = b'DELETE'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   422
            elif line.startswith(b'new file mode '):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   423
                gp.op = b'ADD'
9243
df21a009c9c4 fix issue 1763: strip chars from end of line when parsing gitpatch lines
Bill Barry <after.fallout@gmail.com>
parents: 9123
diff changeset
   424
                gp.setmode(int(line[-6:], 8))
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   425
            elif line.startswith(b'new mode '):
9243
df21a009c9c4 fix issue 1763: strip chars from end of line when parsing gitpatch lines
Bill Barry <after.fallout@gmail.com>
parents: 9123
diff changeset
   426
                gp.setmode(int(line[-6:], 8))
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   427
            elif line.startswith(b'GIT binary patch'):
3367
7f486971d263 Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents: 3329
diff changeset
   428
                gp.binary = True
2861
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   429
    if gp:
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   430
        gitpatches.append(gp)
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   431
12669
b0fa39c68370 patch: remove unused flags from readgitpatch()
Patrick Mezard <pmezard@gmail.com>
parents: 12645
diff changeset
   432
    return gitpatches
2861
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   433
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   434
8891
5fe8dc75aa4a patch: use new style class in linereader
Simon Heimberg <simohe@besonet.ch>
parents: 8843
diff changeset
   435
class linereader(object):
8810
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
   436
    # simple class to allow pushing lines back into the input stream
14418
0174d1f79280 patch: remove EOL support from linereader class
Patrick Mezard <pmezard@gmail.com>
parents: 14402
diff changeset
   437
    def __init__(self, fp):
8810
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
   438
        self.fp = fp
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
   439
        self.buf = []
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
   440
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
   441
    def push(self, line):
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
   442
        if line is not None:
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
   443
            self.buf.append(line)
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
   444
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
   445
    def readline(self):
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
   446
        if self.buf:
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
   447
            l = self.buf[0]
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
   448
            del self.buf[0]
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
   449
            return l
14418
0174d1f79280 patch: remove EOL support from linereader class
Patrick Mezard <pmezard@gmail.com>
parents: 14402
diff changeset
   450
        return self.fp.readline()
8810
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
   451
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
   452
    def __iter__(self):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   453
        return iter(self.readline, b'')
8810
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
   454
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   455
14348
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   456
class abstractbackend(object):
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   457
    def __init__(self, ui):
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   458
        self.ui = ui
14348
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   459
14391
1e64e1e12195 patch: unify backend file access interface
Patrick Mezard <pmezard@gmail.com>
parents: 14390
diff changeset
   460
    def getfile(self, fname):
1e64e1e12195 patch: unify backend file access interface
Patrick Mezard <pmezard@gmail.com>
parents: 14390
diff changeset
   461
        """Return target file data and flags as a (data, (islink,
22296
650b5b6e75ed convert: use None value for missing files instead of overloading IOError
Mads Kiilerich <madski@unity3d.com>
parents: 21833
diff changeset
   462
        isexec)) tuple. Data is None if file is missing/deleted.
14348
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   463
        """
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   464
        raise NotImplementedError
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   465
14452
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
   466
    def setfile(self, fname, data, mode, copysource):
14391
1e64e1e12195 patch: unify backend file access interface
Patrick Mezard <pmezard@gmail.com>
parents: 14390
diff changeset
   467
        """Write data to target file fname and set its mode. mode is a
1e64e1e12195 patch: unify backend file access interface
Patrick Mezard <pmezard@gmail.com>
parents: 14390
diff changeset
   468
        (islink, isexec) tuple. If data is None, the file content should
14452
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
   469
        be left unchanged. If the file is modified after being copied,
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
   470
        copysource is set to the original file name.
14367
468d7d1744b4 patch: set desired mode when patching, not in updatedir()
Patrick Mezard <pmezard@gmail.com>
parents: 14366
diff changeset
   471
        """
14348
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   472
        raise NotImplementedError
5652
e90e72c6b4c7 patch: write rej files for missing targets (issue 853)
Patrick Mezard <pmezard@gmail.com>
parents: 5651
diff changeset
   473
14348
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   474
    def unlink(self, fname):
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   475
        """Unlink target file."""
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   476
        raise NotImplementedError
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   477
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   478
    def writerej(self, fname, failed, total, lines):
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   479
        """Write rejected lines for fname. total is the number of hunks
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   480
        which failed to apply and total the total number of hunks for this
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   481
        files.
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   482
        """
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   483
14351
d54f9bbcc640 patch: add lexists() to backends, use it in selectfile()
Patrick Mezard <pmezard@gmail.com>
parents: 14350
diff changeset
   484
    def exists(self, fname):
d54f9bbcc640 patch: add lexists() to backends, use it in selectfile()
Patrick Mezard <pmezard@gmail.com>
parents: 14350
diff changeset
   485
        raise NotImplementedError
d54f9bbcc640 patch: add lexists() to backends, use it in selectfile()
Patrick Mezard <pmezard@gmail.com>
parents: 14350
diff changeset
   486
33161
b8ae289a7707 patch: add close() to abstractbackend
Martin von Zweigbergk <martinvonz@google.com>
parents: 33116
diff changeset
   487
    def close(self):
b8ae289a7707 patch: add close() to abstractbackend
Martin von Zweigbergk <martinvonz@google.com>
parents: 33116
diff changeset
   488
        raise NotImplementedError
b8ae289a7707 patch: add close() to abstractbackend
Martin von Zweigbergk <martinvonz@google.com>
parents: 33116
diff changeset
   489
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   490
14348
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   491
class fsbackend(abstractbackend):
14350
00da6624e167 patch: move copyfile() into backends, abstract basedir
Patrick Mezard <pmezard@gmail.com>
parents: 14349
diff changeset
   492
    def __init__(self, ui, basedir):
14348
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   493
        super(fsbackend, self).__init__(ui)
31243
067f2a95e32c vfs: use 'vfs' module directly in 'mercurial.patch'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31226
diff changeset
   494
        self.opener = vfsmod.vfs(basedir)
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   495
14391
1e64e1e12195 patch: unify backend file access interface
Patrick Mezard <pmezard@gmail.com>
parents: 14390
diff changeset
   496
    def getfile(self, fname):
21717
2a095d3442e0 patch: replace functions in fsbackend to use vfs
Chinmay Joshi <c@chinmayjoshi.com>
parents: 21553
diff changeset
   497
        if self.opener.islink(fname):
2a095d3442e0 patch: replace functions in fsbackend to use vfs
Chinmay Joshi <c@chinmayjoshi.com>
parents: 21553
diff changeset
   498
            return (self.opener.readlink(fname), (True, False))
2a095d3442e0 patch: replace functions in fsbackend to use vfs
Chinmay Joshi <c@chinmayjoshi.com>
parents: 21553
diff changeset
   499
14531
b88368a3ade4 patch: remove redundant islink() call
Patrick Mezard <pmezard@gmail.com>
parents: 14494
diff changeset
   500
        isexec = False
7392
564326a6ef9c patch: isolate patchfile filesystem calls into methods
Patrick Mezard <pmezard@gmail.com>
parents: 7391
diff changeset
   501
        try:
25658
e93036747902 global: mass rewrite to use modern octal syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25644
diff changeset
   502
            isexec = self.opener.lstat(fname).st_mode & 0o100 != 0
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25658
diff changeset
   503
        except OSError as e:
14391
1e64e1e12195 patch: unify backend file access interface
Patrick Mezard <pmezard@gmail.com>
parents: 14390
diff changeset
   504
            if e.errno != errno.ENOENT:
1e64e1e12195 patch: unify backend file access interface
Patrick Mezard <pmezard@gmail.com>
parents: 14390
diff changeset
   505
                raise
22296
650b5b6e75ed convert: use None value for missing files instead of overloading IOError
Mads Kiilerich <madski@unity3d.com>
parents: 21833
diff changeset
   506
        try:
650b5b6e75ed convert: use None value for missing files instead of overloading IOError
Mads Kiilerich <madski@unity3d.com>
parents: 21833
diff changeset
   507
            return (self.opener.read(fname), (False, isexec))
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25658
diff changeset
   508
        except IOError as e:
22296
650b5b6e75ed convert: use None value for missing files instead of overloading IOError
Mads Kiilerich <madski@unity3d.com>
parents: 21833
diff changeset
   509
            if e.errno != errno.ENOENT:
650b5b6e75ed convert: use None value for missing files instead of overloading IOError
Mads Kiilerich <madski@unity3d.com>
parents: 21833
diff changeset
   510
                raise
650b5b6e75ed convert: use None value for missing files instead of overloading IOError
Mads Kiilerich <madski@unity3d.com>
parents: 21833
diff changeset
   511
            return None, None
7392
564326a6ef9c patch: isolate patchfile filesystem calls into methods
Patrick Mezard <pmezard@gmail.com>
parents: 7391
diff changeset
   512
14452
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
   513
    def setfile(self, fname, data, mode, copysource):
14391
1e64e1e12195 patch: unify backend file access interface
Patrick Mezard <pmezard@gmail.com>
parents: 14390
diff changeset
   514
        islink, isexec = mode
1e64e1e12195 patch: unify backend file access interface
Patrick Mezard <pmezard@gmail.com>
parents: 14390
diff changeset
   515
        if data is None:
21717
2a095d3442e0 patch: replace functions in fsbackend to use vfs
Chinmay Joshi <c@chinmayjoshi.com>
parents: 21553
diff changeset
   516
            self.opener.setflags(fname, islink, isexec)
14390
ce77c275bec3 patch: merge backend setmode() into writelines()
Patrick Mezard <pmezard@gmail.com>
parents: 14389
diff changeset
   517
            return
14391
1e64e1e12195 patch: unify backend file access interface
Patrick Mezard <pmezard@gmail.com>
parents: 14390
diff changeset
   518
        if islink:
1e64e1e12195 patch: unify backend file access interface
Patrick Mezard <pmezard@gmail.com>
parents: 14390
diff changeset
   519
            self.opener.symlink(data, fname)
14367
468d7d1744b4 patch: set desired mode when patching, not in updatedir()
Patrick Mezard <pmezard@gmail.com>
parents: 14366
diff changeset
   520
        else:
14391
1e64e1e12195 patch: unify backend file access interface
Patrick Mezard <pmezard@gmail.com>
parents: 14390
diff changeset
   521
            self.opener.write(fname, data)
14367
468d7d1744b4 patch: set desired mode when patching, not in updatedir()
Patrick Mezard <pmezard@gmail.com>
parents: 14366
diff changeset
   522
            if isexec:
21717
2a095d3442e0 patch: replace functions in fsbackend to use vfs
Chinmay Joshi <c@chinmayjoshi.com>
parents: 21553
diff changeset
   523
                self.opener.setflags(fname, False, True)
7392
564326a6ef9c patch: isolate patchfile filesystem calls into methods
Patrick Mezard <pmezard@gmail.com>
parents: 7391
diff changeset
   524
564326a6ef9c patch: isolate patchfile filesystem calls into methods
Patrick Mezard <pmezard@gmail.com>
parents: 7391
diff changeset
   525
    def unlink(self, fname):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   526
        rmdir = self.ui.configbool(b'experimental', b'removeemptydirs')
38497
da2a7d8354b2 unlinkpath: make empty directory removal optional (issue5901) (issue5826)
Kyle Lippincott <spectral@google.com>
parents: 38341
diff changeset
   527
        self.opener.unlinkpath(fname, ignoremissing=True, rmdir=rmdir)
7392
564326a6ef9c patch: isolate patchfile filesystem calls into methods
Patrick Mezard <pmezard@gmail.com>
parents: 7391
diff changeset
   528
14348
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   529
    def writerej(self, fname, failed, total, lines):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   530
        fname = fname + b".rej"
14348
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   531
        self.ui.warn(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   532
            _(b"%d out of %d hunks FAILED -- saving rejects to file %s\n")
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   533
            % (failed, total, fname)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   534
        )
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   535
        fp = self.opener(fname, b'w')
14348
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   536
        fp.writelines(lines)
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   537
        fp.close()
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   538
14351
d54f9bbcc640 patch: add lexists() to backends, use it in selectfile()
Patrick Mezard <pmezard@gmail.com>
parents: 14350
diff changeset
   539
    def exists(self, fname):
21717
2a095d3442e0 patch: replace functions in fsbackend to use vfs
Chinmay Joshi <c@chinmayjoshi.com>
parents: 21553
diff changeset
   540
        return self.opener.lexists(fname)
14351
d54f9bbcc640 patch: add lexists() to backends, use it in selectfile()
Patrick Mezard <pmezard@gmail.com>
parents: 14350
diff changeset
   541
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   542
14370
17cea10c343e patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14369
diff changeset
   543
class workingbackend(fsbackend):
17cea10c343e patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14369
diff changeset
   544
    def __init__(self, ui, repo, similarity):
17cea10c343e patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14369
diff changeset
   545
        super(workingbackend, self).__init__(ui, repo.root)
17cea10c343e patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14369
diff changeset
   546
        self.repo = repo
17cea10c343e patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14369
diff changeset
   547
        self.similarity = similarity
17cea10c343e patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14369
diff changeset
   548
        self.removed = set()
17cea10c343e patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14369
diff changeset
   549
        self.changed = set()
17cea10c343e patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14369
diff changeset
   550
        self.copied = []
17cea10c343e patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14369
diff changeset
   551
14453
ea3d548132cc patch: do not patch unknown files (issue752)
Patrick Mezard <pmezard@gmail.com>
parents: 14452
diff changeset
   552
    def _checkknown(self, fname):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   553
        if self.repo.dirstate[fname] == b'?' and self.exists(fname):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   554
            raise PatchError(_(b'cannot patch %s: file is not tracked') % fname)
14453
ea3d548132cc patch: do not patch unknown files (issue752)
Patrick Mezard <pmezard@gmail.com>
parents: 14452
diff changeset
   555
14452
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
   556
    def setfile(self, fname, data, mode, copysource):
14453
ea3d548132cc patch: do not patch unknown files (issue752)
Patrick Mezard <pmezard@gmail.com>
parents: 14452
diff changeset
   557
        self._checkknown(fname)
14452
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
   558
        super(workingbackend, self).setfile(fname, data, mode, copysource)
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
   559
        if copysource is not None:
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
   560
            self.copied.append((copysource, fname))
14370
17cea10c343e patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14369
diff changeset
   561
        self.changed.add(fname)
17cea10c343e patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14369
diff changeset
   562
17cea10c343e patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14369
diff changeset
   563
    def unlink(self, fname):
14453
ea3d548132cc patch: do not patch unknown files (issue752)
Patrick Mezard <pmezard@gmail.com>
parents: 14452
diff changeset
   564
        self._checkknown(fname)
14370
17cea10c343e patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14369
diff changeset
   565
        super(workingbackend, self).unlink(fname)
17cea10c343e patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14369
diff changeset
   566
        self.removed.add(fname)
17cea10c343e patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14369
diff changeset
   567
        self.changed.add(fname)
17cea10c343e patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14369
diff changeset
   568
17cea10c343e patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14369
diff changeset
   569
    def close(self):
17cea10c343e patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14369
diff changeset
   570
        wctx = self.repo[None]
19155
0b3689a08df5 patch: use scmutil.marktouched instead of scmutil.addremove
Siddharth Agarwal <sid0@fb.com>
parents: 18830
diff changeset
   571
        changed = set(self.changed)
14370
17cea10c343e patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14369
diff changeset
   572
        for src, dst in self.copied:
17cea10c343e patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14369
diff changeset
   573
            scmutil.dirstatecopy(self.ui, self.repo, wctx, src, dst)
16112
d7829b2ecf32 import: handle git renames and --similarity (issue3187)
Patrick Mezard <patrick@mezard.eu>
parents: 15971
diff changeset
   574
        if self.removed:
14435
5f6090e559fa context: make forget work like commands.forget
Matt Mackall <mpm@selenic.com>
parents: 14418
diff changeset
   575
            wctx.forget(sorted(self.removed))
16112
d7829b2ecf32 import: handle git renames and --similarity (issue3187)
Patrick Mezard <patrick@mezard.eu>
parents: 15971
diff changeset
   576
            for f in self.removed:
d7829b2ecf32 import: handle git renames and --similarity (issue3187)
Patrick Mezard <patrick@mezard.eu>
parents: 15971
diff changeset
   577
                if f not in self.repo.dirstate:
d7829b2ecf32 import: handle git renames and --similarity (issue3187)
Patrick Mezard <patrick@mezard.eu>
parents: 15971
diff changeset
   578
                    # File was deleted and no longer belongs to the
d7829b2ecf32 import: handle git renames and --similarity (issue3187)
Patrick Mezard <patrick@mezard.eu>
parents: 15971
diff changeset
   579
                    # dirstate, it was probably marked added then
d7829b2ecf32 import: handle git renames and --similarity (issue3187)
Patrick Mezard <patrick@mezard.eu>
parents: 15971
diff changeset
   580
                    # deleted, and should not be considered by
19155
0b3689a08df5 patch: use scmutil.marktouched instead of scmutil.addremove
Siddharth Agarwal <sid0@fb.com>
parents: 18830
diff changeset
   581
                    # marktouched().
0b3689a08df5 patch: use scmutil.marktouched instead of scmutil.addremove
Siddharth Agarwal <sid0@fb.com>
parents: 18830
diff changeset
   582
                    changed.discard(f)
0b3689a08df5 patch: use scmutil.marktouched instead of scmutil.addremove
Siddharth Agarwal <sid0@fb.com>
parents: 18830
diff changeset
   583
        if changed:
0b3689a08df5 patch: use scmutil.marktouched instead of scmutil.addremove
Siddharth Agarwal <sid0@fb.com>
parents: 18830
diff changeset
   584
            scmutil.marktouched(self.repo, changed, self.similarity)
14370
17cea10c343e patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14369
diff changeset
   585
        return sorted(self.changed)
17cea10c343e patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14369
diff changeset
   586
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   587
14452
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
   588
class filestore(object):
14658
7ddf9a607b75 patch: make filestore store data in memory and fallback to fs
Patrick Mezard <pmezard@gmail.com>
parents: 14611
diff changeset
   589
    def __init__(self, maxsize=None):
14452
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
   590
        self.opener = None
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
   591
        self.files = {}
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
   592
        self.created = 0
14658
7ddf9a607b75 patch: make filestore store data in memory and fallback to fs
Patrick Mezard <pmezard@gmail.com>
parents: 14611
diff changeset
   593
        self.maxsize = maxsize
7ddf9a607b75 patch: make filestore store data in memory and fallback to fs
Patrick Mezard <pmezard@gmail.com>
parents: 14611
diff changeset
   594
        if self.maxsize is None:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   595
            self.maxsize = 4 * (2 ** 20)
14658
7ddf9a607b75 patch: make filestore store data in memory and fallback to fs
Patrick Mezard <pmezard@gmail.com>
parents: 14611
diff changeset
   596
        self.size = 0
7ddf9a607b75 patch: make filestore store data in memory and fallback to fs
Patrick Mezard <pmezard@gmail.com>
parents: 14611
diff changeset
   597
        self.data = {}
14452
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
   598
14609
f53dc0787424 patch: extend filtestore to store an optional copy source
Patrick Mezard <pmezard@gmail.com>
parents: 14566
diff changeset
   599
    def setfile(self, fname, data, mode, copied=None):
14658
7ddf9a607b75 patch: make filestore store data in memory and fallback to fs
Patrick Mezard <pmezard@gmail.com>
parents: 14611
diff changeset
   600
        if self.maxsize < 0 or (len(data) + self.size) <= self.maxsize:
7ddf9a607b75 patch: make filestore store data in memory and fallback to fs
Patrick Mezard <pmezard@gmail.com>
parents: 14611
diff changeset
   601
            self.data[fname] = (data, mode, copied)
7ddf9a607b75 patch: make filestore store data in memory and fallback to fs
Patrick Mezard <pmezard@gmail.com>
parents: 14611
diff changeset
   602
            self.size += len(data)
7ddf9a607b75 patch: make filestore store data in memory and fallback to fs
Patrick Mezard <pmezard@gmail.com>
parents: 14611
diff changeset
   603
        else:
7ddf9a607b75 patch: make filestore store data in memory and fallback to fs
Patrick Mezard <pmezard@gmail.com>
parents: 14611
diff changeset
   604
            if self.opener is None:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   605
                root = pycompat.mkdtemp(prefix=b'hg-patch-')
31243
067f2a95e32c vfs: use 'vfs' module directly in 'mercurial.patch'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31226
diff changeset
   606
                self.opener = vfsmod.vfs(root)
14658
7ddf9a607b75 patch: make filestore store data in memory and fallback to fs
Patrick Mezard <pmezard@gmail.com>
parents: 14611
diff changeset
   607
            # Avoid filename issues with these simple names
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   608
            fn = b'%d' % self.created
14658
7ddf9a607b75 patch: make filestore store data in memory and fallback to fs
Patrick Mezard <pmezard@gmail.com>
parents: 14611
diff changeset
   609
            self.opener.write(fn, data)
7ddf9a607b75 patch: make filestore store data in memory and fallback to fs
Patrick Mezard <pmezard@gmail.com>
parents: 14611
diff changeset
   610
            self.created += 1
7ddf9a607b75 patch: make filestore store data in memory and fallback to fs
Patrick Mezard <pmezard@gmail.com>
parents: 14611
diff changeset
   611
            self.files[fname] = (fn, mode, copied)
14452
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
   612
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
   613
    def getfile(self, fname):
14658
7ddf9a607b75 patch: make filestore store data in memory and fallback to fs
Patrick Mezard <pmezard@gmail.com>
parents: 14611
diff changeset
   614
        if fname in self.data:
7ddf9a607b75 patch: make filestore store data in memory and fallback to fs
Patrick Mezard <pmezard@gmail.com>
parents: 14611
diff changeset
   615
            return self.data[fname]
7ddf9a607b75 patch: make filestore store data in memory and fallback to fs
Patrick Mezard <pmezard@gmail.com>
parents: 14611
diff changeset
   616
        if not self.opener or fname not in self.files:
22296
650b5b6e75ed convert: use None value for missing files instead of overloading IOError
Mads Kiilerich <madski@unity3d.com>
parents: 21833
diff changeset
   617
            return None, None, None
14609
f53dc0787424 patch: extend filtestore to store an optional copy source
Patrick Mezard <pmezard@gmail.com>
parents: 14566
diff changeset
   618
        fn, mode, copied = self.files[fname]
f53dc0787424 patch: extend filtestore to store an optional copy source
Patrick Mezard <pmezard@gmail.com>
parents: 14566
diff changeset
   619
        return self.opener.read(fn), mode, copied
14452
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
   620
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
   621
    def close(self):
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
   622
        if self.opener:
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
   623
            shutil.rmtree(self.opener.base)
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
   624
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   625
14611
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
   626
class repobackend(abstractbackend):
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
   627
    def __init__(self, ui, repo, ctx, store):
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
   628
        super(repobackend, self).__init__(ui)
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
   629
        self.repo = repo
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
   630
        self.ctx = ctx
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
   631
        self.store = store
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
   632
        self.changed = set()
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
   633
        self.removed = set()
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
   634
        self.copied = {}
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
   635
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
   636
    def _checkknown(self, fname):
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
   637
        if fname not in self.ctx:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   638
            raise PatchError(_(b'cannot patch %s: file is not tracked') % fname)
14611
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
   639
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
   640
    def getfile(self, fname):
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
   641
        try:
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
   642
            fctx = self.ctx[fname]
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
   643
        except error.LookupError:
22296
650b5b6e75ed convert: use None value for missing files instead of overloading IOError
Mads Kiilerich <madski@unity3d.com>
parents: 21833
diff changeset
   644
            return None, None
14611
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
   645
        flags = fctx.flags()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   646
        return fctx.data(), (b'l' in flags, b'x' in flags)
14611
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
   647
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
   648
    def setfile(self, fname, data, mode, copysource):
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
   649
        if copysource:
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
   650
            self._checkknown(copysource)
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
   651
        if data is None:
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
   652
            data = self.ctx[fname].data()
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
   653
        self.store.setfile(fname, data, mode, copysource)
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
   654
        self.changed.add(fname)
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
   655
        if copysource:
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
   656
            self.copied[fname] = copysource
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
   657
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
   658
    def unlink(self, fname):
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
   659
        self._checkknown(fname)
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
   660
        self.removed.add(fname)
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
   661
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
   662
    def exists(self, fname):
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
   663
        return fname in self.ctx
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
   664
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
   665
    def close(self):
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
   666
        return self.changed | self.removed
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
   667
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   668
14348
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   669
# @@ -start,len +start,len @@ or @@ -start +start @@ if len is 1
41546
bd3f03d8cc9f global: use raw strings for regular expressions with escapes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41513
diff changeset
   670
unidesc = re.compile(br'@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@')
bd3f03d8cc9f global: use raw strings for regular expressions with escapes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41513
diff changeset
   671
contextdesc = re.compile(br'(?:---|\*\*\*) (\d+)(?:,(\d+))? (?:---|\*\*\*)')
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   672
eolmodes = [b'strict', b'crlf', b'lf', b'auto']
14348
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   673
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   674
14348
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   675
class patchfile(object):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   676
    def __init__(self, ui, gp, backend, store, eolmode=b'strict'):
14566
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
   677
        self.fname = gp.path
14348
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   678
        self.eolmode = eolmode
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   679
        self.eol = None
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   680
        self.backend = backend
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   681
        self.ui = ui
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   682
        self.lines = []
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   683
        self.exists = False
14452
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
   684
        self.missing = True
14566
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
   685
        self.mode = gp.mode
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
   686
        self.copysource = gp.oldpath
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   687
        self.create = gp.op in (b'ADD', b'COPY', b'RENAME')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   688
        self.remove = gp.op == b'DELETE'
22296
650b5b6e75ed convert: use None value for missing files instead of overloading IOError
Mads Kiilerich <madski@unity3d.com>
parents: 21833
diff changeset
   689
        if self.copysource is None:
650b5b6e75ed convert: use None value for missing files instead of overloading IOError
Mads Kiilerich <madski@unity3d.com>
parents: 21833
diff changeset
   690
            data, mode = backend.getfile(self.fname)
650b5b6e75ed convert: use None value for missing files instead of overloading IOError
Mads Kiilerich <madski@unity3d.com>
parents: 21833
diff changeset
   691
        else:
650b5b6e75ed convert: use None value for missing files instead of overloading IOError
Mads Kiilerich <madski@unity3d.com>
parents: 21833
diff changeset
   692
            data, mode = store.getfile(self.copysource)[:2]
650b5b6e75ed convert: use None value for missing files instead of overloading IOError
Mads Kiilerich <madski@unity3d.com>
parents: 21833
diff changeset
   693
        if data is not None:
650b5b6e75ed convert: use None value for missing files instead of overloading IOError
Mads Kiilerich <madski@unity3d.com>
parents: 21833
diff changeset
   694
            self.exists = self.copysource is None or backend.exists(self.fname)
14452
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
   695
            self.missing = False
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
   696
            if data:
14832
d60e4f227d75 patch: fix parsing patch files containing CRs not followed by LFs
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14764
diff changeset
   697
                self.lines = mdiff.splitnewlines(data)
14452
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
   698
            if self.mode is None:
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
   699
                self.mode = mode
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
   700
            if self.lines:
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
   701
                # Normalize line endings
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   702
                if self.lines[0].endswith(b'\r\n'):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   703
                    self.eol = b'\r\n'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   704
                elif self.lines[0].endswith(b'\n'):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   705
                    self.eol = b'\n'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   706
                if eolmode != b'strict':
14452
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
   707
                    nlines = []
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
   708
                    for l in self.lines:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   709
                        if l.endswith(b'\r\n'):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   710
                            l = l[:-2] + b'\n'
14452
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
   711
                        nlines.append(l)
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
   712
                    self.lines = nlines
22296
650b5b6e75ed convert: use None value for missing files instead of overloading IOError
Mads Kiilerich <madski@unity3d.com>
parents: 21833
diff changeset
   713
        else:
14566
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
   714
            if self.create:
14452
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
   715
                self.missing = False
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
   716
            if self.mode is None:
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
   717
                self.mode = (False, False)
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
   718
        if self.missing:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   719
            self.ui.warn(_(b"unable to find '%s' for patching\n") % self.fname)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   720
            self.ui.warn(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   721
                _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   722
                    b"(use '--prefix' to apply patch relative to the "
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   723
                    b"current directory)\n"
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   724
                )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   725
            )
14348
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   726
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   727
        self.hash = {}
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   728
        self.dirty = 0
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   729
        self.offset = 0
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   730
        self.skew = 0
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   731
        self.rej = []
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   732
        self.fileprinted = False
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   733
        self.printfile(False)
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   734
        self.hunks = 0
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   735
14367
468d7d1744b4 patch: set desired mode when patching, not in updatedir()
Patrick Mezard <pmezard@gmail.com>
parents: 14366
diff changeset
   736
    def writelines(self, fname, lines, mode):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   737
        if self.eolmode == b'auto':
14348
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   738
            eol = self.eol
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   739
        elif self.eolmode == b'crlf':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   740
            eol = b'\r\n'
14348
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   741
        else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   742
            eol = b'\n'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   743
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   744
        if self.eolmode != b'strict' and eol and eol != b'\n':
14348
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   745
            rawlines = []
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   746
            for l in lines:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   747
                if l and l.endswith(b'\n'):
14348
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   748
                    l = l[:-1] + eol
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   749
                rawlines.append(l)
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   750
            lines = rawlines
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   751
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   752
        self.backend.setfile(fname, b''.join(lines), mode, self.copysource)
14348
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   753
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   754
    def printfile(self, warn):
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   755
        if self.fileprinted:
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   756
            return
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   757
        if warn or self.ui.verbose:
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   758
            self.fileprinted = True
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   759
        s = _(b"patching file %s\n") % self.fname
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   760
        if warn:
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   761
            self.ui.warn(s)
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   762
        else:
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   763
            self.ui.note(s)
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   764
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   765
    def findlines(self, l, linenum):
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   766
        # looks through the hash and finds candidate lines.  The
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   767
        # result is a list of line numbers sorted based on distance
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   768
        # from linenum
5143
d4fa6bafc43a Remove trailing spaces, fix indentation
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5116
diff changeset
   769
9681
ac3a68cb16eb patch: simplify logic
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9642
diff changeset
   770
        cand = self.hash.get(l, [])
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   771
        if len(cand) > 1:
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   772
            # resort our list of potentials forward then back.
9032
1fa80c5428b8 compat: use 'key' argument instead of 'cmp' when sorting a list
Alejandro Santos <alejolp@alejolp.com>
parents: 9031
diff changeset
   773
            cand.sort(key=lambda x: abs(x - linenum))
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   774
        return cand
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   775
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   776
    def write_rej(self):
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   777
        # our rejects are a little different from patch(1).  This always
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   778
        # creates rejects in the same form as the original patch.  A file
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   779
        # header is inserted so that you can run the reject through patch again
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   780
        # without having to type the filename.
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   781
        if not self.rej:
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   782
            return
14349
776ae95b8835 patch: merge makerejlines() into write_rej()
Patrick Mezard <pmezard@gmail.com>
parents: 14348
diff changeset
   783
        base = os.path.basename(self.fname)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   784
        lines = [b"--- %s\n+++ %s\n" % (base, base)]
14349
776ae95b8835 patch: merge makerejlines() into write_rej()
Patrick Mezard <pmezard@gmail.com>
parents: 14348
diff changeset
   785
        for x in self.rej:
776ae95b8835 patch: merge makerejlines() into write_rej()
Patrick Mezard <pmezard@gmail.com>
parents: 14348
diff changeset
   786
            for l in x.hunk:
776ae95b8835 patch: merge makerejlines() into write_rej()
Patrick Mezard <pmezard@gmail.com>
parents: 14348
diff changeset
   787
                lines.append(l)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   788
                if l[-1:] != b'\n':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   789
                    lines.append(b"\n\\ No newline at end of file\n")
14349
776ae95b8835 patch: merge makerejlines() into write_rej()
Patrick Mezard <pmezard@gmail.com>
parents: 14348
diff changeset
   790
        self.backend.writerej(self.fname, len(self.rej), self.hunks, lines)
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   791
9393
23c4e772c172 patch: remove the unused, broken reverse() function
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9392
diff changeset
   792
    def apply(self, h):
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   793
        if not h.complete():
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   794
            raise PatchError(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   795
                _(b"bad hunk #%d %s (%d %d %d %d)")
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   796
                % (h.number, h.desc, len(h.a), h.lena, len(h.b), h.lenb)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   797
            )
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   798
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   799
        self.hunks += 1
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   800
5652
e90e72c6b4c7 patch: write rej files for missing targets (issue 853)
Patrick Mezard <pmezard@gmail.com>
parents: 5651
diff changeset
   801
        if self.missing:
e90e72c6b4c7 patch: write rej files for missing targets (issue 853)
Patrick Mezard <pmezard@gmail.com>
parents: 5651
diff changeset
   802
            self.rej.append(h)
e90e72c6b4c7 patch: write rej files for missing targets (issue 853)
Patrick Mezard <pmezard@gmail.com>
parents: 5651
diff changeset
   803
            return -1
e90e72c6b4c7 patch: write rej files for missing targets (issue 853)
Patrick Mezard <pmezard@gmail.com>
parents: 5651
diff changeset
   804
14451
c78d41db6f88 patch: refactor file creation/removal detection
Patrick Mezard <pmezard@gmail.com>
parents: 14437
diff changeset
   805
        if self.exists and self.create:
14452
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
   806
            if self.copysource:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   807
                self.ui.warn(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   808
                    _(b"cannot create %s: destination already " b"exists\n")
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   809
                    % self.fname
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   810
                )
14452
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
   811
            else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   812
                self.ui.warn(_(b"file %s already exists\n") % self.fname)
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   813
            self.rej.append(h)
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   814
            return -1
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   815
9585
ea1935e2020a patch: handle symlinks without symlinkhunk
Patrick Mezard <pmezard@gmail.com>
parents: 9573
diff changeset
   816
        if isinstance(h, binhunk):
14451
c78d41db6f88 patch: refactor file creation/removal detection
Patrick Mezard <pmezard@gmail.com>
parents: 14437
diff changeset
   817
            if self.remove:
14348
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   818
                self.backend.unlink(self.fname)
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   819
            else:
20137
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
   820
                l = h.new(self.lines)
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
   821
                self.lines[:] = l
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
   822
                self.offset += len(l)
14217
71d5287351e9 patchfile: use real Booleans instead of 0/1
Martin Geisler <mg@aragost.com>
parents: 14017
diff changeset
   823
                self.dirty = True
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   824
            return 0
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   825
10127
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
   826
        horig = h
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   827
        if (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   828
            self.eolmode in (b'crlf', b'lf')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   829
            or self.eolmode == b'auto'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   830
            and self.eol
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   831
        ):
10128
ea7c392f2b08 patch: drop eol normalization fast-path for 'lf' and 'crlf'
Patrick Mezard <pmezard@gmail.com>
parents: 10127
diff changeset
   832
            # If new eols are going to be normalized, then normalize
ea7c392f2b08 patch: drop eol normalization fast-path for 'lf' and 'crlf'
Patrick Mezard <pmezard@gmail.com>
parents: 10127
diff changeset
   833
            # hunk data before patching. Otherwise, preserve input
ea7c392f2b08 patch: drop eol normalization fast-path for 'lf' and 'crlf'
Patrick Mezard <pmezard@gmail.com>
parents: 10127
diff changeset
   834
            # line-endings.
10127
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
   835
            h = h.getnormalized()
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
   836
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   837
        # fast case first, no offsets, no fuzz
16122
9ef3a4a2c6c0 patch: make hunk.fuzzit() compute the fuzzed start locations
Patrick Mezard <patrick@mezard.eu>
parents: 16121
diff changeset
   838
        old, oldstart, new, newstart = h.fuzzit(0, False)
9ef3a4a2c6c0 patch: make hunk.fuzzit() compute the fuzzed start locations
Patrick Mezard <patrick@mezard.eu>
parents: 16121
diff changeset
   839
        oldstart += self.offset
9ef3a4a2c6c0 patch: make hunk.fuzzit() compute the fuzzed start locations
Patrick Mezard <patrick@mezard.eu>
parents: 16121
diff changeset
   840
        orig_start = oldstart
10135
9a4034b630c4 patch: better handling of sequence of offset patch hunks (issue1941)
Greg Onufer <gonufer@jazzhaiku.com>
parents: 9725
diff changeset
   841
        # if there's skew we want to emit the "(offset %d lines)" even
9a4034b630c4 patch: better handling of sequence of offset patch hunks (issue1941)
Greg Onufer <gonufer@jazzhaiku.com>
parents: 9725
diff changeset
   842
        # when the hunk cleanly applies at start + skew, so skip the
9a4034b630c4 patch: better handling of sequence of offset patch hunks (issue1941)
Greg Onufer <gonufer@jazzhaiku.com>
parents: 9725
diff changeset
   843
        # fast case code
37803
72f6498c040b diffhelper: rename module to avoid conflicts with ancient C module (issue5846)
Yuya Nishihara <yuya@tcha.org>
parents: 37764
diff changeset
   844
        if self.skew == 0 and diffhelper.testhunk(old, self.lines, oldstart):
14451
c78d41db6f88 patch: refactor file creation/removal detection
Patrick Mezard <pmezard@gmail.com>
parents: 14437
diff changeset
   845
            if self.remove:
14348
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
   846
                self.backend.unlink(self.fname)
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   847
            else:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   848
                self.lines[oldstart : oldstart + len(old)] = new
16122
9ef3a4a2c6c0 patch: make hunk.fuzzit() compute the fuzzed start locations
Patrick Mezard <patrick@mezard.eu>
parents: 16121
diff changeset
   849
                self.offset += len(new) - len(old)
14217
71d5287351e9 patchfile: use real Booleans instead of 0/1
Martin Geisler <mg@aragost.com>
parents: 14017
diff changeset
   850
                self.dirty = True
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   851
            return 0
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   852
13700
63307feb59dd patch: inline patchfile.hashlines()
Patrick Mezard <pmezard@gmail.com>
parents: 13699
diff changeset
   853
        # ok, we couldn't match the hunk. Lets look for offsets and fuzz it
63307feb59dd patch: inline patchfile.hashlines()
Patrick Mezard <pmezard@gmail.com>
parents: 13699
diff changeset
   854
        self.hash = {}
63307feb59dd patch: inline patchfile.hashlines()
Patrick Mezard <pmezard@gmail.com>
parents: 13699
diff changeset
   855
        for x, s in enumerate(self.lines):
63307feb59dd patch: inline patchfile.hashlines()
Patrick Mezard <pmezard@gmail.com>
parents: 13699
diff changeset
   856
            self.hash.setdefault(s, []).append(x)
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   857
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   858
        for fuzzlen in pycompat.xrange(
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   859
            self.ui.configint(b"patch", b"fuzz") + 1
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   860
        ):
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
   861
            for toponly in [True, False]:
16122
9ef3a4a2c6c0 patch: make hunk.fuzzit() compute the fuzzed start locations
Patrick Mezard <patrick@mezard.eu>
parents: 16121
diff changeset
   862
                old, oldstart, new, newstart = h.fuzzit(fuzzlen, toponly)
16123
b0c7525f826d patch: fix fuzzing of hunks without previous lines (issue3264)
Patrick Mezard <patrick@mezard.eu>
parents: 16122
diff changeset
   863
                oldstart = oldstart + self.offset + self.skew
b0c7525f826d patch: fix fuzzing of hunks without previous lines (issue3264)
Patrick Mezard <patrick@mezard.eu>
parents: 16122
diff changeset
   864
                oldstart = min(oldstart, len(self.lines))
b0c7525f826d patch: fix fuzzing of hunks without previous lines (issue3264)
Patrick Mezard <patrick@mezard.eu>
parents: 16122
diff changeset
   865
                if old:
b0c7525f826d patch: fix fuzzing of hunks without previous lines (issue3264)
Patrick Mezard <patrick@mezard.eu>
parents: 16122
diff changeset
   866
                    cand = self.findlines(old[0][1:], oldstart)
b0c7525f826d patch: fix fuzzing of hunks without previous lines (issue3264)
Patrick Mezard <patrick@mezard.eu>
parents: 16122
diff changeset
   867
                else:
b0c7525f826d patch: fix fuzzing of hunks without previous lines (issue3264)
Patrick Mezard <patrick@mezard.eu>
parents: 16122
diff changeset
   868
                    # Only adding lines with no or fuzzed context, just
b0c7525f826d patch: fix fuzzing of hunks without previous lines (issue3264)
Patrick Mezard <patrick@mezard.eu>
parents: 16122
diff changeset
   869
                    # take the skew in account
b0c7525f826d patch: fix fuzzing of hunks without previous lines (issue3264)
Patrick Mezard <patrick@mezard.eu>
parents: 16122
diff changeset
   870
                    cand = [oldstart]
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   871
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   872
                for l in cand:
37803
72f6498c040b diffhelper: rename module to avoid conflicts with ancient C module (issue5846)
Yuya Nishihara <yuya@tcha.org>
parents: 37764
diff changeset
   873
                    if not old or diffhelper.testhunk(old, self.lines, l):
16121
ccba74472af2 patch: fuzz old and new lines at the same time
Patrick Mezard <patrick@mezard.eu>
parents: 16112
diff changeset
   874
                        self.lines[l : l + len(old)] = new
ccba74472af2 patch: fuzz old and new lines at the same time
Patrick Mezard <patrick@mezard.eu>
parents: 16112
diff changeset
   875
                        self.offset += len(new) - len(old)
10135
9a4034b630c4 patch: better handling of sequence of offset patch hunks (issue1941)
Greg Onufer <gonufer@jazzhaiku.com>
parents: 9725
diff changeset
   876
                        self.skew = l - orig_start
14217
71d5287351e9 patchfile: use real Booleans instead of 0/1
Martin Geisler <mg@aragost.com>
parents: 14017
diff changeset
   877
                        self.dirty = True
10518
5fe51d348daf patch, i18n: avoid parameterized messages
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 10501
diff changeset
   878
                        offset = l - orig_start - fuzzlen
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   879
                        if fuzzlen:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   880
                            msg = _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   881
                                b"Hunk #%d succeeded at %d "
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   882
                                b"with fuzz %d "
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   883
                                b"(offset %d lines).\n"
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   884
                            )
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   885
                            self.printfile(True)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   886
                            self.ui.warn(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   887
                                msg % (h.number, l + 1, fuzzlen, offset)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   888
                            )
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   889
                        else:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   890
                            msg = _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   891
                                b"Hunk #%d succeeded at %d "
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   892
                                b"(offset %d lines).\n"
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   893
                            )
10518
5fe51d348daf patch, i18n: avoid parameterized messages
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 10501
diff changeset
   894
                            self.ui.note(msg % (h.number, l + 1, offset))
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   895
                        return fuzzlen
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   896
        self.printfile(True)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   897
        self.ui.warn(_(b"Hunk #%d FAILED at %d\n") % (h.number, orig_start))
10127
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
   898
        self.rej.append(horig)
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   899
        return -1
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
   900
13701
bc38ff7cb919 patch: move closefile() into patchfile.close()
Patrick Mezard <pmezard@gmail.com>
parents: 13700
diff changeset
   901
    def close(self):
bc38ff7cb919 patch: move closefile() into patchfile.close()
Patrick Mezard <pmezard@gmail.com>
parents: 13700
diff changeset
   902
        if self.dirty:
14367
468d7d1744b4 patch: set desired mode when patching, not in updatedir()
Patrick Mezard <pmezard@gmail.com>
parents: 14366
diff changeset
   903
            self.writelines(self.fname, self.lines, self.mode)
13701
bc38ff7cb919 patch: move closefile() into patchfile.close()
Patrick Mezard <pmezard@gmail.com>
parents: 13700
diff changeset
   904
        self.write_rej()
bc38ff7cb919 patch: move closefile() into patchfile.close()
Patrick Mezard <pmezard@gmail.com>
parents: 13700
diff changeset
   905
        return len(self.rej)
bc38ff7cb919 patch: move closefile() into patchfile.close()
Patrick Mezard <pmezard@gmail.com>
parents: 13700
diff changeset
   906
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   907
24261
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
   908
class header(object):
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
   909
    """patch header
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
   910
    """
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   911
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   912
    diffgit_re = re.compile(b'diff --git a/(.*) b/(.*)$')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   913
    diff_re = re.compile(b'diff -r .* (.*)$')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   914
    allhunks_re = re.compile(b'(?:index|deleted file) ')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   915
    pretty_re = re.compile(b'(?:new file|deleted file) ')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   916
    special_re = re.compile(b'(?:index|deleted|copy|rename|new mode) ')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   917
    newfile_re = re.compile(b'(?:new file|copy to|rename to)')
24261
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
   918
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
   919
    def __init__(self, header):
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
   920
        self.header = header
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
   921
        self.hunks = []
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
   922
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
   923
    def binary(self):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   924
        return any(h.startswith(b'index ') for h in self.header)
24261
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
   925
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
   926
    def pretty(self, fp):
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
   927
        for h in self.header:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   928
            if h.startswith(b'index '):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   929
                fp.write(_(b'this modifies a binary file (all or nothing)\n'))
24261
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
   930
                break
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
   931
            if self.pretty_re.match(h):
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
   932
                fp.write(h)
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
   933
                if self.binary():
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   934
                    fp.write(_(b'this is a binary file\n'))
24261
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
   935
                break
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   936
            if h.startswith(b'---'):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   937
                fp.write(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   938
                    _(b'%d hunks, %d lines changed\n')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   939
                    % (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   940
                        len(self.hunks),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   941
                        sum([max(h.added, h.removed) for h in self.hunks]),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   942
                    )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   943
                )
24261
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
   944
                break
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
   945
            fp.write(h)
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
   946
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
   947
    def write(self, fp):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   948
        fp.write(b''.join(self.header))
24261
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
   949
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
   950
    def allhunks(self):
25149
3f0744eeaeaf cleanup: use __builtins__.any instead of util.any
Augie Fackler <augie@google.com>
parents: 25138
diff changeset
   951
        return any(self.allhunks_re.match(h) for h in self.header)
24261
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
   952
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
   953
    def files(self):
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
   954
        match = self.diffgit_re.match(self.header[0])
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
   955
        if match:
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
   956
            fromfile, tofile = match.groups()
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
   957
            if fromfile == tofile:
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
   958
                return [fromfile]
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
   959
            return [fromfile, tofile]
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
   960
        else:
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
   961
            return self.diff_re.match(self.header[0]).groups()
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
   962
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
   963
    def filename(self):
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
   964
        return self.files()[-1]
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
   965
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
   966
    def __repr__(self):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   967
        return b'<header %s>' % (b' '.join(map(repr, self.files())))
24261
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
   968
24845
8133494accf1 record: edit patch of newly added files (issue4304)
Laurent Charignon <lcharignon@fb.com>
parents: 24837
diff changeset
   969
    def isnewfile(self):
25149
3f0744eeaeaf cleanup: use __builtins__.any instead of util.any
Augie Fackler <augie@google.com>
parents: 25138
diff changeset
   970
        return any(self.newfile_re.match(h) for h in self.header)
24845
8133494accf1 record: edit patch of newly added files (issue4304)
Laurent Charignon <lcharignon@fb.com>
parents: 24837
diff changeset
   971
24261
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
   972
    def special(self):
24845
8133494accf1 record: edit patch of newly added files (issue4304)
Laurent Charignon <lcharignon@fb.com>
parents: 24837
diff changeset
   973
        # Special files are shown only at the header level and not at the hunk
8133494accf1 record: edit patch of newly added files (issue4304)
Laurent Charignon <lcharignon@fb.com>
parents: 24837
diff changeset
   974
        # level for example a file that has been deleted is a special file.
8133494accf1 record: edit patch of newly added files (issue4304)
Laurent Charignon <lcharignon@fb.com>
parents: 24837
diff changeset
   975
        # The user cannot change the content of the operation, in the case of
8133494accf1 record: edit patch of newly added files (issue4304)
Laurent Charignon <lcharignon@fb.com>
parents: 24837
diff changeset
   976
        # the deleted file he has to take the deletion or not take it, he
8133494accf1 record: edit patch of newly added files (issue4304)
Laurent Charignon <lcharignon@fb.com>
parents: 24837
diff changeset
   977
        # cannot take some of it.
8133494accf1 record: edit patch of newly added files (issue4304)
Laurent Charignon <lcharignon@fb.com>
parents: 24837
diff changeset
   978
        # Newly added files are special if they are empty, they are not special
8133494accf1 record: edit patch of newly added files (issue4304)
Laurent Charignon <lcharignon@fb.com>
parents: 24837
diff changeset
   979
        # if they have some content as we want to be able to change it
8133494accf1 record: edit patch of newly added files (issue4304)
Laurent Charignon <lcharignon@fb.com>
parents: 24837
diff changeset
   980
        nocontent = len(self.header) == 2
8133494accf1 record: edit patch of newly added files (issue4304)
Laurent Charignon <lcharignon@fb.com>
parents: 24837
diff changeset
   981
        emptynewfile = self.isnewfile() and nocontent
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   982
        return emptynewfile or any(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   983
            self.special_re.match(h) for h in self.header
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   984
        )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   985
24261
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
   986
24263
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
   987
class recordhunk(object):
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
   988
    """patch hunk
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
   989
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
   990
    XXX shouldn't we merge this with the other hunk class?
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
   991
    """
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
   992
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   993
    def __init__(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   994
        self,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   995
        header,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   996
        fromline,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   997
        toline,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   998
        proc,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
   999
        before,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1000
        hunk,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1001
        after,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1002
        maxcontext=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1003
    ):
33270
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1004
        def trimcontext(lines, reverse=False):
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1005
            if maxcontext is not None:
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1006
                delta = len(lines) - maxcontext
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1007
                if delta > 0:
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1008
                    if reverse:
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1009
                        return delta, lines[delta:]
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1010
                    else:
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1011
                        return delta, lines[:maxcontext]
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1012
            return 0, lines
24263
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
  1013
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
  1014
        self.header = header
33270
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1015
        trimedbefore, self.before = trimcontext(before, True)
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1016
        self.fromline = fromline + trimedbefore
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1017
        self.toline = toline + trimedbefore
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1018
        _trimedafter, self.after = trimcontext(after, False)
24263
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
  1019
        self.proc = proc
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
  1020
        self.hunk = hunk
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
  1021
        self.added, self.removed = self.countchanges(self.hunk)
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
  1022
24346
31edcea517c1 record: add comparison methods for recordhunk class
Laurent Charignon <lcharignon@fb.com>
parents: 24341
diff changeset
  1023
    def __eq__(self, v):
31edcea517c1 record: add comparison methods for recordhunk class
Laurent Charignon <lcharignon@fb.com>
parents: 24341
diff changeset
  1024
        if not isinstance(v, recordhunk):
31edcea517c1 record: add comparison methods for recordhunk class
Laurent Charignon <lcharignon@fb.com>
parents: 24341
diff changeset
  1025
            return False
31edcea517c1 record: add comparison methods for recordhunk class
Laurent Charignon <lcharignon@fb.com>
parents: 24341
diff changeset
  1026
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1027
        return (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1028
            (v.hunk == self.hunk)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1029
            and (v.proc == self.proc)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1030
            and (self.fromline == v.fromline)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1031
            and (self.header.files() == v.header.files())
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1032
        )
24346
31edcea517c1 record: add comparison methods for recordhunk class
Laurent Charignon <lcharignon@fb.com>
parents: 24341
diff changeset
  1033
31edcea517c1 record: add comparison methods for recordhunk class
Laurent Charignon <lcharignon@fb.com>
parents: 24341
diff changeset
  1034
    def __hash__(self):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1035
        return hash(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1036
            (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1037
                tuple(self.hunk),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1038
                tuple(self.header.files()),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1039
                self.fromline,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1040
                self.proc,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1041
            )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1042
        )
24346
31edcea517c1 record: add comparison methods for recordhunk class
Laurent Charignon <lcharignon@fb.com>
parents: 24341
diff changeset
  1043
24263
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
  1044
    def countchanges(self, hunk):
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
  1045
        """hunk -> (n+,n-)"""
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1046
        add = len([h for h in hunk if h.startswith(b'+')])
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1047
        rem = len([h for h in hunk if h.startswith(b'-')])
24263
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
  1048
        return add, rem
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
  1049
32997
66117dae87f9 patch: rewrite reversehunks (issue5337)
Jun Wu <quark@fb.com>
parents: 32409
diff changeset
  1050
    def reversehunk(self):
66117dae87f9 patch: rewrite reversehunks (issue5337)
Jun Wu <quark@fb.com>
parents: 32409
diff changeset
  1051
        """return another recordhunk which is the reverse of the hunk
66117dae87f9 patch: rewrite reversehunks (issue5337)
Jun Wu <quark@fb.com>
parents: 32409
diff changeset
  1052
66117dae87f9 patch: rewrite reversehunks (issue5337)
Jun Wu <quark@fb.com>
parents: 32409
diff changeset
  1053
        If this hunk is diff(A, B), the returned hunk is diff(B, A). To do
66117dae87f9 patch: rewrite reversehunks (issue5337)
Jun Wu <quark@fb.com>
parents: 32409
diff changeset
  1054
        that, swap fromline/toline and +/- signs while keep other things
66117dae87f9 patch: rewrite reversehunks (issue5337)
Jun Wu <quark@fb.com>
parents: 32409
diff changeset
  1055
        unchanged.
66117dae87f9 patch: rewrite reversehunks (issue5337)
Jun Wu <quark@fb.com>
parents: 32409
diff changeset
  1056
        """
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1057
        m = {b'+': b'-', b'-': b'+', b'\\': b'\\'}
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1058
        hunk = [b'%s%s' % (m[l[0:1]], l[1:]) for l in self.hunk]
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1059
        return recordhunk(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1060
            self.header,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1061
            self.toline,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1062
            self.fromline,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1063
            self.proc,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1064
            self.before,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1065
            hunk,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1066
            self.after,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1067
        )
32997
66117dae87f9 patch: rewrite reversehunks (issue5337)
Jun Wu <quark@fb.com>
parents: 32409
diff changeset
  1068
24263
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
  1069
    def write(self, fp):
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
  1070
        delta = len(self.before) + len(self.after)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1071
        if self.after and self.after[-1] == b'\\ No newline at end of file\n':
24263
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
  1072
            delta -= 1
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
  1073
        fromlen = delta + self.removed
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
  1074
        tolen = delta + self.added
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1075
        fp.write(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1076
            b'@@ -%d,%d +%d,%d @@%s\n'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1077
            % (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1078
                self.fromline,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1079
                fromlen,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1080
                self.toline,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1081
                tolen,
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1082
                self.proc and (b' ' + self.proc),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1083
            )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1084
        )
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1085
        fp.write(b''.join(self.before + self.hunk + self.after))
24263
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
  1086
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
  1087
    pretty = write
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
  1088
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
  1089
    def filename(self):
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
  1090
        return self.header.filename()
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
  1091
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
  1092
    def __repr__(self):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1093
        return b'<hunk %r@%d>' % (self.filename(), self.fromline)
24263
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
  1094
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1095
34566
60213a2eca81 patch: do not cache translated messages (API)
Jun Wu <quark@fb.com>
parents: 34561
diff changeset
  1096
def getmessages():
60213a2eca81 patch: do not cache translated messages (API)
Jun Wu <quark@fb.com>
parents: 34561
diff changeset
  1097
    return {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1098
        b'multiple': {
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1099
            b'apply': _(b"apply change %d/%d to '%s'?"),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1100
            b'discard': _(b"discard change %d/%d to '%s'?"),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1101
            b'keep': _(b"keep change %d/%d to '%s'?"),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1102
            b'record': _(b"record change %d/%d to '%s'?"),
34566
60213a2eca81 patch: do not cache translated messages (API)
Jun Wu <quark@fb.com>
parents: 34561
diff changeset
  1103
        },
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1104
        b'single': {
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1105
            b'apply': _(b"apply this change to '%s'?"),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1106
            b'discard': _(b"discard this change to '%s'?"),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1107
            b'keep': _(b"keep this change to '%s'?"),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1108
            b'record': _(b"record this change to '%s'?"),
34566
60213a2eca81 patch: do not cache translated messages (API)
Jun Wu <quark@fb.com>
parents: 34561
diff changeset
  1109
        },
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1110
        b'help': {
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1111
            b'apply': _(
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1112
                b'[Ynesfdaq?]'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1113
                b'$$ &Yes, apply this change'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1114
                b'$$ &No, skip this change'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1115
                b'$$ &Edit this change manually'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1116
                b'$$ &Skip remaining changes to this file'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1117
                b'$$ Apply remaining changes to this &file'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1118
                b'$$ &Done, skip remaining changes and files'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1119
                b'$$ Apply &all changes to all remaining files'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1120
                b'$$ &Quit, applying no changes'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1121
                b'$$ &? (display help)'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1122
            ),
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1123
            b'discard': _(
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1124
                b'[Ynesfdaq?]'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1125
                b'$$ &Yes, discard this change'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1126
                b'$$ &No, skip this change'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1127
                b'$$ &Edit this change manually'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1128
                b'$$ &Skip remaining changes to this file'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1129
                b'$$ Discard remaining changes to this &file'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1130
                b'$$ &Done, skip remaining changes and files'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1131
                b'$$ Discard &all changes to all remaining files'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1132
                b'$$ &Quit, discarding no changes'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1133
                b'$$ &? (display help)'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1134
            ),
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1135
            b'keep': _(
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1136
                b'[Ynesfdaq?]'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1137
                b'$$ &Yes, keep this change'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1138
                b'$$ &No, skip this change'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1139
                b'$$ &Edit this change manually'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1140
                b'$$ &Skip remaining changes to this file'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1141
                b'$$ Keep remaining changes to this &file'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1142
                b'$$ &Done, skip remaining changes and files'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1143
                b'$$ Keep &all changes to all remaining files'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1144
                b'$$ &Quit, keeping all changes'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1145
                b'$$ &? (display help)'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1146
            ),
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1147
            b'record': _(
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1148
                b'[Ynesfdaq?]'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1149
                b'$$ &Yes, record this change'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1150
                b'$$ &No, skip this change'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1151
                b'$$ &Edit this change manually'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1152
                b'$$ &Skip remaining changes to this file'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1153
                b'$$ Record remaining changes to this &file'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1154
                b'$$ &Done, skip remaining changes and files'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1155
                b'$$ Record &all changes to all remaining files'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1156
                b'$$ &Quit, recording no changes'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1157
                b'$$ &? (display help)'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1158
            ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1159
        },
34059
c0170d88ed2b patch: take messages out of the function so that extensions can add entries
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34031
diff changeset
  1160
    }
c0170d88ed2b patch: take messages out of the function so that extensions can add entries
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34031
diff changeset
  1161
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1162
42071
db72f9f6580e interactive: do not prompt about files given in command line
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 41987
diff changeset
  1163
def filterpatch(ui, headers, match, operation=None):
24269
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1164
    """Interactively filter patch chunks into applied-only chunks"""
34566
60213a2eca81 patch: do not cache translated messages (API)
Jun Wu <quark@fb.com>
parents: 34561
diff changeset
  1165
    messages = getmessages()
60213a2eca81 patch: do not cache translated messages (API)
Jun Wu <quark@fb.com>
parents: 34561
diff changeset
  1166
25359
724421cb4745 record: add default value for operation argument
Laurent Charignon <lcharignon@fb.com>
parents: 25310
diff changeset
  1167
    if operation is None:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1168
        operation = b'record'
24269
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1169
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1170
    def prompt(skipfile, skipall, query, chunk):
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1171
        """prompt query, and process base inputs
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1172
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1173
        - y/n for the rest of file
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1174
        - y/n for the rest
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1175
        - ? (help)
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1176
        - q (quit)
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1177
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1178
        Return True/False and possibly updated skipfile and skipall.
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1179
        """
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1180
        newpatches = None
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1181
        if skipall is not None:
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1182
            return skipall, skipfile, skipall, newpatches
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1183
        if skipfile is not None:
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1184
            return skipfile, skipfile, skipall, newpatches
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1185
        while True:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1186
            resps = messages[b'help'][operation]
42566
f802a75da585 patch: use a short, fixed-size message for last line of prompt (issue6158)
Kyle Lippincott <spectral@google.com>
parents: 42071
diff changeset
  1187
            # IMPORTANT: keep the last line of this prompt short (<40 english
f802a75da585 patch: use a short, fixed-size message for last line of prompt (issue6158)
Kyle Lippincott <spectral@google.com>
parents: 42071
diff changeset
  1188
            # chars is a good target) because of issue6158.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1189
            r = ui.promptchoice(b"%s\n(enter ? for help) %s" % (query, resps))
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1190
            ui.write(b"\n")
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1191
            if r == 8:  # ?
24269
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1192
                for c, t in ui.extractchoices(resps)[1]:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1193
                    ui.write(b'%s - %s\n' % (c, encoding.lower(t)))
24269
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1194
                continue
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1195
            elif r == 0:  # yes
24269
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1196
                ret = True
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1197
            elif r == 1:  # no
24269
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1198
                ret = False
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1199
            elif r == 2:  # Edit patch
24269
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1200
                if chunk is None:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1201
                    ui.write(_(b'cannot edit patch for whole file'))
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1202
                    ui.write(b"\n")
24269
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1203
                    continue
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1204
                if chunk.header.binary():
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1205
                    ui.write(_(b'cannot edit patch for binary file'))
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1206
                    ui.write(b"\n")
24269
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1207
                    continue
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1208
                # Patch comment based on the Git one (based on comment at end of
26421
4b0fc75f9403 urls: bulk-change primary website URLs
Matt Mackall <mpm@selenic.com>
parents: 25660
diff changeset
  1209
                # https://mercurial-scm.org/wiki/RecordExtension)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1210
                phelp = b'---' + _(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1211
                    """
24269
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1212
To remove '-' lines, make them ' ' lines (context).
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1213
To remove '+' lines, delete them.
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1214
Lines starting with # will be removed from the patch.
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1215
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1216
If the patch applies cleanly, the edited hunk will immediately be
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1217
added to the record list. If it does not apply cleanly, a rejects
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1218
file will be generated: you can use that when you try again. If
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1219
all lines of the hunk are removed, then the edit is aborted and
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1220
the hunk is left unchanged.
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1221
"""
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1222
                )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1223
                (patchfd, patchfn) = pycompat.mkstemp(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1224
                    prefix=b"hg-editor-", suffix=b".diff"
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1225
                )
24269
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1226
                ncpatchfp = None
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1227
                try:
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1228
                    # Write the initial patch
36845
472c68cda3f8 py3: wrap file object to write patch in native eol preserving byte-ness
Yuya Nishihara <yuya@tcha.org>
parents: 36843
diff changeset
  1229
                    f = util.nativeeolwriter(os.fdopen(patchfd, r'wb'))
24269
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1230
                    chunk.header.write(f)
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1231
                    chunk.write(f)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1232
                    f.write(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1233
                        b''.join(
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1234
                            [b'# ' + i + b'\n' for i in phelp.splitlines()]
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1235
                        )
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1236
                    )
24269
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1237
                    f.close()
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1238
                    # Start the editor and wait for it to complete
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1239
                    editor = ui.geteditor()
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1240
                    ret = ui.system(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1241
                        b"%s \"%s\"" % (editor, patchfn),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1242
                        environ={b'HGUSER': ui.username()},
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1243
                        blockedtag=b'filterpatch',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1244
                    )
25483
fb04372d7b38 record: exiting editor with non-zero status should not stop recording session
Laurent Charignon <lcharignon@fb.com>
parents: 25424
diff changeset
  1245
                    if ret != 0:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1246
                        ui.warn(_(b"editor exited with exit code %d\n") % ret)
25483
fb04372d7b38 record: exiting editor with non-zero status should not stop recording session
Laurent Charignon <lcharignon@fb.com>
parents: 25424
diff changeset
  1247
                        continue
24269
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1248
                    # Remove comment lines
36846
c268ba15deb3 py3: open patch file in binary mode and convert eol manually
Yuya Nishihara <yuya@tcha.org>
parents: 36845
diff changeset
  1249
                    patchfp = open(patchfn, r'rb')
28861
86db5cb55d46 pycompat: switch to util.stringio for py3 compat
timeless <timeless@mozdev.org>
parents: 28341
diff changeset
  1250
                    ncpatchfp = stringio()
30407
564b33acc21f patch: migrate to util.iterfile
Jun Wu <quark@fb.com>
parents: 30078
diff changeset
  1251
                    for line in util.iterfile(patchfp):
36846
c268ba15deb3 py3: open patch file in binary mode and convert eol manually
Yuya Nishihara <yuya@tcha.org>
parents: 36845
diff changeset
  1252
                        line = util.fromnativeeol(line)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1253
                        if not line.startswith(b'#'):
24269
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1254
                            ncpatchfp.write(line)
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1255
                    patchfp.close()
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1256
                    ncpatchfp.seek(0)
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1257
                    newpatches = parsepatch(ncpatchfp)
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1258
                finally:
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1259
                    os.unlink(patchfn)
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1260
                    del ncpatchfp
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1261
                # Signal that the chunk shouldn't be applied as-is, but
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1262
                # provide the new patch to be used instead.
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1263
                ret = False
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1264
            elif r == 3:  # Skip
24269
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1265
                ret = skipfile = False
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1266
            elif r == 4:  # file (Record remaining)
24269
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1267
                ret = skipfile = True
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1268
            elif r == 5:  # done, skip remaining
24269
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1269
                ret = skipall = False
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1270
            elif r == 6:  # all
24269
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1271
                ret = skipall = True
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1272
            elif r == 7:  # quit
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1273
                raise error.Abort(_(b'user quit'))
24269
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1274
            return ret, skipfile, skipall, newpatches
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1275
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1276
    seen = set()
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1277
    applied = {}  # 'filename' -> [] of chunks
24269
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1278
    skipfile, skipall = None, None
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1279
    pos, total = 1, sum(len(h.hunks) for h in headers)
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1280
    for h in headers:
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1281
        pos += len(h.hunks)
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1282
        skipfile = None
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1283
        fixoffset = 0
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1284
        hdr = b''.join(h.header)
24269
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1285
        if hdr in seen:
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1286
            continue
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1287
        seen.add(hdr)
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1288
        if skipall is None:
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1289
            h.pretty(ui)
42071
db72f9f6580e interactive: do not prompt about files given in command line
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 41987
diff changeset
  1290
        files = h.files()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1291
        msg = _(b'examine changes to %s?') % _(b' and ').join(
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1292
            b"'%s'" % f for f in files
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1293
        )
42071
db72f9f6580e interactive: do not prompt about files given in command line
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 41987
diff changeset
  1294
        if all(match.exact(f) for f in files):
db72f9f6580e interactive: do not prompt about files given in command line
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 41987
diff changeset
  1295
            r, skipall, np = True, None, None
db72f9f6580e interactive: do not prompt about files given in command line
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 41987
diff changeset
  1296
        else:
db72f9f6580e interactive: do not prompt about files given in command line
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 41987
diff changeset
  1297
            r, skipfile, skipall, np = prompt(skipfile, skipall, msg, None)
24269
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1298
        if not r:
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1299
            continue
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1300
        applied[h.filename()] = [h]
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1301
        if h.allhunks():
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1302
            applied[h.filename()] += h.hunks
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1303
            continue
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1304
        for i, chunk in enumerate(h.hunks):
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1305
            if skipfile is None and skipall is None:
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1306
                chunk.pretty(ui)
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1307
            if total == 1:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1308
                msg = messages[b'single'][operation] % chunk.filename()
24269
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1309
            else:
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1310
                idx = pos - len(h.hunks) + i
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1311
                msg = messages[b'multiple'][operation] % (
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1312
                    idx,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1313
                    total,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1314
                    chunk.filename(),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1315
                )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1316
            r, skipfile, skipall, newpatches = prompt(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1317
                skipfile, skipall, msg, chunk
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1318
            )
24269
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1319
            if r:
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1320
                if fixoffset:
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1321
                    chunk = copy.copy(chunk)
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1322
                    chunk.toline += fixoffset
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1323
                applied[chunk.filename()].append(chunk)
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1324
            elif newpatches is not None:
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1325
                for newpatch in newpatches:
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1326
                    for newhunk in newpatch.hunks:
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1327
                        if fixoffset:
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1328
                            newhunk.toline += fixoffset
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1329
                        applied[newhunk.filename()].append(newhunk)
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1330
            else:
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
  1331
                fixoffset += chunk.removed - chunk.added
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1332
    return (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1333
        sum(
43104
74802979dd9d py3: define and use pycompat.itervalues()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43097
diff changeset
  1334
            [
74802979dd9d py3: define and use pycompat.itervalues()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43097
diff changeset
  1335
                h
74802979dd9d py3: define and use pycompat.itervalues()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43097
diff changeset
  1336
                for h in pycompat.itervalues(applied)
74802979dd9d py3: define and use pycompat.itervalues()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43097
diff changeset
  1337
                if h[0].special() or len(h) > 1
74802979dd9d py3: define and use pycompat.itervalues()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43097
diff changeset
  1338
            ],
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1339
            [],
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1340
        ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1341
        {},
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1342
    )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1343
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1344
8778
c5f36402daad use new style classes
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8761
diff changeset
  1345
class hunk(object):
14451
c78d41db6f88 patch: refactor file creation/removal detection
Patrick Mezard <pmezard@gmail.com>
parents: 14437
diff changeset
  1346
    def __init__(self, desc, num, lr, context):
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1347
        self.number = num
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1348
        self.desc = desc
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
  1349
        self.hunk = [desc]
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1350
        self.a = []
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1351
        self.b = []
9682
bd70f645cfb0 patch: initialize all attributes of the hunk class
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9681
diff changeset
  1352
        self.starta = self.lena = None
bd70f645cfb0 patch: initialize all attributes of the hunk class
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9681
diff changeset
  1353
        self.startb = self.lenb = None
10127
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
  1354
        if lr is not None:
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
  1355
            if context:
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
  1356
                self.read_context_hunk(lr)
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
  1357
            else:
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
  1358
                self.read_unified_hunk(lr)
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1359
10127
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
  1360
    def getnormalized(self):
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
  1361
        """Return a copy with line endings normalized to LF."""
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
  1362
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
  1363
        def normalize(lines):
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
  1364
            nlines = []
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
  1365
            for line in lines:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1366
                if line.endswith(b'\r\n'):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1367
                    line = line[:-2] + b'\n'
10127
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
  1368
                nlines.append(line)
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
  1369
            return nlines
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
  1370
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
  1371
        # Dummy object, it is rebuilt manually
14451
c78d41db6f88 patch: refactor file creation/removal detection
Patrick Mezard <pmezard@gmail.com>
parents: 14437
diff changeset
  1372
        nh = hunk(self.desc, self.number, None, None)
10127
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
  1373
        nh.number = self.number
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
  1374
        nh.desc = self.desc
10524
3212afb33116 patch: fix patching with fuzz and eol normalization
Patrick Mezard <pmezard@gmail.com>
parents: 10518
diff changeset
  1375
        nh.hunk = self.hunk
10127
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
  1376
        nh.a = normalize(self.a)
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
  1377
        nh.b = normalize(self.b)
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
  1378
        nh.starta = self.starta
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
  1379
        nh.startb = self.startb
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
  1380
        nh.lena = self.lena
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
  1381
        nh.lenb = self.lenb
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
  1382
        return nh
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
  1383
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1384
    def read_unified_hunk(self, lr):
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1385
        m = unidesc.match(self.desc)
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1386
        if not m:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1387
            raise PatchError(_(b"bad hunk #%d") % self.number)
15510
5414b56cfad6 patch: simplify hunk extents parsing
Patrick Mezard <pmezard@gmail.com>
parents: 15462
diff changeset
  1388
        self.starta, self.lena, self.startb, self.lenb = m.groups()
8527
f9a80054dd3c use 'x is None' instead of 'x == None'
Martin Geisler <mg@lazybytes.net>
parents: 8526
diff changeset
  1389
        if self.lena is None:
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1390
            self.lena = 1
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1391
        else:
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1392
            self.lena = int(self.lena)
8527
f9a80054dd3c use 'x is None' instead of 'x == None'
Martin Geisler <mg@lazybytes.net>
parents: 8526
diff changeset
  1393
        if self.lenb is None:
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1394
            self.lenb = 1
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1395
        else:
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1396
            self.lenb = int(self.lenb)
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1397
        self.starta = int(self.starta)
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1398
        self.startb = int(self.startb)
37573
49b82cdb5983 patch: error out if reached to EOF while reading hunk
Yuya Nishihara <yuya@tcha.org>
parents: 37571
diff changeset
  1399
        try:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1400
            diffhelper.addlines(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1401
                lr, self.hunk, self.lena, self.lenb, self.a, self.b
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1402
            )
37573
49b82cdb5983 patch: error out if reached to EOF while reading hunk
Yuya Nishihara <yuya@tcha.org>
parents: 37571
diff changeset
  1403
        except error.ParseError as e:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1404
            raise PatchError(_(b"bad hunk #%d: %s") % (self.number, e))
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1405
        # if we hit eof before finishing out the hunk, the last line will
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1406
        # be zero length.  Lets try to fix it up.
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1407
        while len(self.hunk[-1]) == 0:
6948
359e93ceee3a fix double indentation and trailing whitespace
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6884
diff changeset
  1408
            del self.hunk[-1]
359e93ceee3a fix double indentation and trailing whitespace
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6884
diff changeset
  1409
            del self.a[-1]
359e93ceee3a fix double indentation and trailing whitespace
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6884
diff changeset
  1410
            del self.b[-1]
359e93ceee3a fix double indentation and trailing whitespace
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6884
diff changeset
  1411
            self.lena -= 1
359e93ceee3a fix double indentation and trailing whitespace
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6884
diff changeset
  1412
            self.lenb -= 1
13699
d3c0e0033f13 patch: fix hunk newlines when parsing hunks, not in iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 13395
diff changeset
  1413
        self._fixnewline(lr)
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1414
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1415
    def read_context_hunk(self, lr):
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1416
        self.desc = lr.readline()
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1417
        m = contextdesc.match(self.desc)
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1418
        if not m:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1419
            raise PatchError(_(b"bad hunk #%d") % self.number)
15510
5414b56cfad6 patch: simplify hunk extents parsing
Patrick Mezard <pmezard@gmail.com>
parents: 15462
diff changeset
  1420
        self.starta, aend = m.groups()
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1421
        self.starta = int(self.starta)
8527
f9a80054dd3c use 'x is None' instead of 'x == None'
Martin Geisler <mg@lazybytes.net>
parents: 8526
diff changeset
  1422
        if aend is None:
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1423
            aend = self.starta
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1424
        self.lena = int(aend) - self.starta
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1425
        if self.starta:
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1426
            self.lena += 1
38823
e7aa113b14f7 global: use pycompat.xrange()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38814
diff changeset
  1427
        for x in pycompat.xrange(self.lena):
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1428
            l = lr.readline()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1429
            if l.startswith(b'---'):
12825
61f48581d8ef Test applying context diffs
Patrick Mezard <pmezard@gmail.com>
parents: 12728
diff changeset
  1430
                # lines addition, old block is empty
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1431
                lr.push(l)
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1432
                break
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1433
            s = l[2:]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1434
            if l.startswith(b'- ') or l.startswith(b'! '):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1435
                u = b'-' + s
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1436
            elif l.startswith(b'  '):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1437
                u = b' ' + s
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1438
            else:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1439
                raise PatchError(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1440
                    _(b"bad hunk #%d old text line %d") % (self.number, x)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1441
                )
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1442
            self.a.append(u)
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1443
            self.hunk.append(u)
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1444
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1445
        l = lr.readline()
41548
47c92f8ed128 patch: properly escape \ in string literals
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41546
diff changeset
  1446
        if l.startswith(br'\ '):
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1447
            s = self.a[-1][:-1]
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1448
            self.a[-1] = s
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1449
            self.hunk[-1] = s
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1450
            l = lr.readline()
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1451
        m = contextdesc.match(l)
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1452
        if not m:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1453
            raise PatchError(_(b"bad hunk #%d") % self.number)
15510
5414b56cfad6 patch: simplify hunk extents parsing
Patrick Mezard <pmezard@gmail.com>
parents: 15462
diff changeset
  1454
        self.startb, bend = m.groups()
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1455
        self.startb = int(self.startb)
8527
f9a80054dd3c use 'x is None' instead of 'x == None'
Martin Geisler <mg@lazybytes.net>
parents: 8526
diff changeset
  1456
        if bend is None:
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1457
            bend = self.startb
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1458
        self.lenb = int(bend) - self.startb
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1459
        if self.startb:
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1460
            self.lenb += 1
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1461
        hunki = 1
38823
e7aa113b14f7 global: use pycompat.xrange()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38814
diff changeset
  1462
        for x in pycompat.xrange(self.lenb):
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1463
            l = lr.readline()
41548
47c92f8ed128 patch: properly escape \ in string literals
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41546
diff changeset
  1464
            if l.startswith(br'\ '):
12825
61f48581d8ef Test applying context diffs
Patrick Mezard <pmezard@gmail.com>
parents: 12728
diff changeset
  1465
                # XXX: the only way to hit this is with an invalid line range.
61f48581d8ef Test applying context diffs
Patrick Mezard <pmezard@gmail.com>
parents: 12728
diff changeset
  1466
                # The no-eol marker is not counted in the line range, but I
61f48581d8ef Test applying context diffs
Patrick Mezard <pmezard@gmail.com>
parents: 12728
diff changeset
  1467
                # guess there are diff(1) out there which behave differently.
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1468
                s = self.b[-1][:-1]
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1469
                self.b[-1] = s
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
  1470
                self.hunk[hunki - 1] = s
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1471
                continue
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1472
            if not l:
12825
61f48581d8ef Test applying context diffs
Patrick Mezard <pmezard@gmail.com>
parents: 12728
diff changeset
  1473
                # line deletions, new block is empty and we hit EOF
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1474
                lr.push(l)
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1475
                break
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1476
            s = l[2:]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1477
            if l.startswith(b'+ ') or l.startswith(b'! '):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1478
                u = b'+' + s
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1479
            elif l.startswith(b'  '):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1480
                u = b' ' + s
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1481
            elif len(self.b) == 0:
12825
61f48581d8ef Test applying context diffs
Patrick Mezard <pmezard@gmail.com>
parents: 12728
diff changeset
  1482
                # line deletions, new block is empty
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1483
                lr.push(l)
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1484
                break
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1485
            else:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1486
                raise PatchError(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1487
                    _(b"bad hunk #%d old text line %d") % (self.number, x)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1488
                )
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1489
            self.b.append(s)
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1490
            while True:
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1491
                if hunki >= len(self.hunk):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1492
                    h = b""
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1493
                else:
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1494
                    h = self.hunk[hunki]
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1495
                hunki += 1
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1496
                if h == u:
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1497
                    break
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1498
                elif h.startswith(b'-'):
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1499
                    continue
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1500
                else:
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
  1501
                    self.hunk.insert(hunki - 1, u)
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1502
                    break
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1503
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1504
        if not self.a:
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1505
            # this happens when lines were only added to the hunk
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1506
            for x in self.hunk:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1507
                if x.startswith(b'-') or x.startswith(b' '):
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1508
                    self.a.append(x)
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1509
        if not self.b:
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1510
            # this happens when lines were only deleted from the hunk
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1511
            for x in self.hunk:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1512
                if x.startswith(b'+') or x.startswith(b' '):
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1513
                    self.b.append(x[1:])
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1514
        # @@ -start,len +start,len @@
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1515
        self.desc = b"@@ -%d,%d +%d,%d @@\n" % (
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1516
            self.starta,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1517
            self.lena,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1518
            self.startb,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1519
            self.lenb,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1520
        )
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1521
        self.hunk[0] = self.desc
13699
d3c0e0033f13 patch: fix hunk newlines when parsing hunks, not in iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 13395
diff changeset
  1522
        self._fixnewline(lr)
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1523
13699
d3c0e0033f13 patch: fix hunk newlines when parsing hunks, not in iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 13395
diff changeset
  1524
    def _fixnewline(self, lr):
d3c0e0033f13 patch: fix hunk newlines when parsing hunks, not in iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 13395
diff changeset
  1525
        l = lr.readline()
41548
47c92f8ed128 patch: properly escape \ in string literals
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41546
diff changeset
  1526
        if l.startswith(br'\ '):
37803
72f6498c040b diffhelper: rename module to avoid conflicts with ancient C module (issue5846)
Yuya Nishihara <yuya@tcha.org>
parents: 37764
diff changeset
  1527
            diffhelper.fixnewline(self.hunk, self.a, self.b)
13699
d3c0e0033f13 patch: fix hunk newlines when parsing hunks, not in iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 13395
diff changeset
  1528
        else:
d3c0e0033f13 patch: fix hunk newlines when parsing hunks, not in iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 13395
diff changeset
  1529
            lr.push(l)
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1530
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1531
    def complete(self):
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1532
        return len(self.a) == self.lena and len(self.b) == self.lenb
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1533
16121
ccba74472af2 patch: fuzz old and new lines at the same time
Patrick Mezard <patrick@mezard.eu>
parents: 16112
diff changeset
  1534
    def _fuzzit(self, old, new, fuzz, toponly):
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1535
        # this removes context lines from the top and bottom of list 'l'.  It
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1536
        # checks the hunk to make sure only context lines are removed, and then
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1537
        # returns a new shortened list of lines.
16124
0e0060bf2f44 patch: fuzz more aggressively to match patch(1) behaviour
Patrick Mezard <patrick@mezard.eu>
parents: 16123
diff changeset
  1538
        fuzz = min(fuzz, len(old))
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1539
        if fuzz:
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1540
            top = 0
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1541
            bot = 0
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1542
            hlen = len(self.hunk)
38823
e7aa113b14f7 global: use pycompat.xrange()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38814
diff changeset
  1543
            for x in pycompat.xrange(hlen - 1):
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1544
                # the hunk starts with the @@ line, so use x+1
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1545
                if self.hunk[x + 1].startswith(b' '):
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1546
                    top += 1
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1547
                else:
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1548
                    break
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1549
            if not toponly:
38823
e7aa113b14f7 global: use pycompat.xrange()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38814
diff changeset
  1550
                for x in pycompat.xrange(hlen - 1):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1551
                    if self.hunk[hlen - bot - 1].startswith(b' '):
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1552
                        bot += 1
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1553
                    else:
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1554
                        break
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1555
16124
0e0060bf2f44 patch: fuzz more aggressively to match patch(1) behaviour
Patrick Mezard <patrick@mezard.eu>
parents: 16123
diff changeset
  1556
            bot = min(fuzz, bot)
0e0060bf2f44 patch: fuzz more aggressively to match patch(1) behaviour
Patrick Mezard <patrick@mezard.eu>
parents: 16123
diff changeset
  1557
            top = min(fuzz, top)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1558
            return old[top : len(old) - bot], new[top : len(new) - bot], top
16122
9ef3a4a2c6c0 patch: make hunk.fuzzit() compute the fuzzed start locations
Patrick Mezard <patrick@mezard.eu>
parents: 16121
diff changeset
  1559
        return old, new, 0
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1560
16121
ccba74472af2 patch: fuzz old and new lines at the same time
Patrick Mezard <patrick@mezard.eu>
parents: 16112
diff changeset
  1561
    def fuzzit(self, fuzz, toponly):
16122
9ef3a4a2c6c0 patch: make hunk.fuzzit() compute the fuzzed start locations
Patrick Mezard <patrick@mezard.eu>
parents: 16121
diff changeset
  1562
        old, new, top = self._fuzzit(self.a, self.b, fuzz, toponly)
9ef3a4a2c6c0 patch: make hunk.fuzzit() compute the fuzzed start locations
Patrick Mezard <patrick@mezard.eu>
parents: 16121
diff changeset
  1563
        oldstart = self.starta + top
9ef3a4a2c6c0 patch: make hunk.fuzzit() compute the fuzzed start locations
Patrick Mezard <patrick@mezard.eu>
parents: 16121
diff changeset
  1564
        newstart = self.startb + top
9ef3a4a2c6c0 patch: make hunk.fuzzit() compute the fuzzed start locations
Patrick Mezard <patrick@mezard.eu>
parents: 16121
diff changeset
  1565
        # zero length hunk ranges already have their start decremented
16650
fcb97d9a26cd patch: fix segfault against unified diffs which start line is zero
Yuya Nishihara <yuya@tcha.org>
parents: 16524
diff changeset
  1566
        if self.lena and oldstart > 0:
16122
9ef3a4a2c6c0 patch: make hunk.fuzzit() compute the fuzzed start locations
Patrick Mezard <patrick@mezard.eu>
parents: 16121
diff changeset
  1567
            oldstart -= 1
16650
fcb97d9a26cd patch: fix segfault against unified diffs which start line is zero
Yuya Nishihara <yuya@tcha.org>
parents: 16524
diff changeset
  1568
        if self.lenb and newstart > 0:
16122
9ef3a4a2c6c0 patch: make hunk.fuzzit() compute the fuzzed start locations
Patrick Mezard <patrick@mezard.eu>
parents: 16121
diff changeset
  1569
            newstart -= 1
9ef3a4a2c6c0 patch: make hunk.fuzzit() compute the fuzzed start locations
Patrick Mezard <patrick@mezard.eu>
parents: 16121
diff changeset
  1570
        return old, oldstart, new, newstart
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1571
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1572
14764
a7d5816087a9 classes: fix class style problems found by b071cd58af50
Thomas Arendsen Hein <thomas@intevation.de>
parents: 14695
diff changeset
  1573
class binhunk(object):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1574
    b'A binary patch file.'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1575
16523
727068417b95 patch: include file name in binary patch error messages
Patrick Mezard <patrick@mezard.eu>
parents: 16522
diff changeset
  1576
    def __init__(self, lr, fname):
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1577
        self.text = None
20137
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
  1578
        self.delta = False
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1579
        self.hunk = [b'GIT binary patch\n']
16523
727068417b95 patch: include file name in binary patch error messages
Patrick Mezard <patrick@mezard.eu>
parents: 16522
diff changeset
  1580
        self._fname = fname
14384
9d59c596eb9e patch: construct and parse binary hunks at the same time
Patrick Mezard <pmezard@gmail.com>
parents: 14383
diff changeset
  1581
        self._read(lr)
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1582
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1583
    def complete(self):
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1584
        return self.text is not None
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1585
20137
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
  1586
    def new(self, lines):
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
  1587
        if self.delta:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1588
            return [applybindelta(self.text, b''.join(lines))]
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1589
        return [self.text]
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1590
14384
9d59c596eb9e patch: construct and parse binary hunks at the same time
Patrick Mezard <pmezard@gmail.com>
parents: 14383
diff changeset
  1591
    def _read(self, lr):
16524
ed6a74312176 patch: be more tolerant with EOLs in binary diffs (issue2870)
Patrick Mezard <patrick@mezard.eu>
parents: 16523
diff changeset
  1592
        def getline(lr, hunk):
ed6a74312176 patch: be more tolerant with EOLs in binary diffs (issue2870)
Patrick Mezard <patrick@mezard.eu>
parents: 16523
diff changeset
  1593
            l = lr.readline()
ed6a74312176 patch: be more tolerant with EOLs in binary diffs (issue2870)
Patrick Mezard <patrick@mezard.eu>
parents: 16523
diff changeset
  1594
            hunk.append(l)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1595
            return l.rstrip(b'\r\n')
16524
ed6a74312176 patch: be more tolerant with EOLs in binary diffs (issue2870)
Patrick Mezard <patrick@mezard.eu>
parents: 16523
diff changeset
  1596
16567
aef3d0d4631c patch: clarify binary hunk parsing loop
Patrick Mezard <patrick@mezard.eu>
parents: 16524
diff changeset
  1597
        while True:
16524
ed6a74312176 patch: be more tolerant with EOLs in binary diffs (issue2870)
Patrick Mezard <patrick@mezard.eu>
parents: 16523
diff changeset
  1598
            line = getline(lr, self.hunk)
16567
aef3d0d4631c patch: clarify binary hunk parsing loop
Patrick Mezard <patrick@mezard.eu>
parents: 16524
diff changeset
  1599
            if not line:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1600
                raise PatchError(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1601
                    _(b'could not extract "%s" binary data') % self._fname
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1602
                )
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1603
            if line.startswith(b'literal '):
20137
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
  1604
                size = int(line[8:].rstrip())
16567
aef3d0d4631c patch: clarify binary hunk parsing loop
Patrick Mezard <patrick@mezard.eu>
parents: 16524
diff changeset
  1605
                break
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1606
            if line.startswith(b'delta '):
20137
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
  1607
                size = int(line[6:].rstrip())
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
  1608
                self.delta = True
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
  1609
                break
3367
7f486971d263 Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents: 3329
diff changeset
  1610
        dec = []
16524
ed6a74312176 patch: be more tolerant with EOLs in binary diffs (issue2870)
Patrick Mezard <patrick@mezard.eu>
parents: 16523
diff changeset
  1611
        line = getline(lr, self.hunk)
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1612
        while len(line) > 1:
36230
eb91ffdaaece py3: slice over bytes to prevent getting ascii values
Pulkit Goyal <7895pulkit@gmail.com>
parents: 36084
diff changeset
  1613
            l = line[0:1]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1614
            if l <= b'Z' and l >= b'A':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1615
                l = ord(l) - ord(b'A') + 1
3374
fd43ff3b4442 Use line length field when extracting git binary patches
Brendan Cully <brendan@kublai.com>
parents: 3367
diff changeset
  1616
            else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1617
                l = ord(l) - ord(b'a') + 27
16522
a8065323c003 patch: display a nice error for invalid base85 data
Patrick Mezard <patrick@mezard.eu>
parents: 16506
diff changeset
  1618
            try:
32245
4462a981e8df base85: proxy through util module
Yuya Nishihara <yuya@tcha.org>
parents: 32237
diff changeset
  1619
                dec.append(util.b85decode(line[1:])[:l])
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25658
diff changeset
  1620
            except ValueError as e:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1621
                raise PatchError(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1622
                    _(b'could not decode "%s" binary patch: %s')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1623
                    % (self._fname, stringutil.forcebytestr(e))
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1624
                )
16524
ed6a74312176 patch: be more tolerant with EOLs in binary diffs (issue2870)
Patrick Mezard <patrick@mezard.eu>
parents: 16523
diff changeset
  1625
            line = getline(lr, self.hunk)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1626
        text = zlib.decompress(b''.join(dec))
3367
7f486971d263 Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents: 3329
diff changeset
  1627
        if len(text) != size:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1628
            raise PatchError(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1629
                _(b'"%s" length is %d bytes, should be %d')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1630
                % (self._fname, len(text), size)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1631
            )
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1632
        self.text = text
3367
7f486971d263 Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents: 3329
diff changeset
  1633
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1634
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1635
def parsefilename(str):
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1636
    # --- filename \t|space stuff
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1637
    s = str[4:].rstrip(b'\r\n')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1638
    i = s.find(b'\t')
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1639
    if i < 0:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1640
        i = s.find(b' ')
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1641
        if i < 0:
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1642
            return s
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1643
    return s[:i]
2861
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
  1644
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1645
25424
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1646
def reversehunks(hunks):
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1647
    '''reverse the signs in the hunks given as argument
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1648
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1649
    This function operates on hunks coming out of patch.filterpatch, that is
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1650
    a list of the form: [header1, hunk1, hunk2, header2...]. Example usage:
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1651
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34084
diff changeset
  1652
    >>> rawpatch = b"""diff --git a/folder1/g b/folder1/g
25424
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1653
    ... --- a/folder1/g
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1654
    ... +++ b/folder1/g
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1655
    ... @@ -1,7 +1,7 @@
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1656
    ... +firstline
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1657
    ...  c
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1658
    ...  1
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1659
    ...  2
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1660
    ... + 3
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1661
    ... -4
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1662
    ...  5
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1663
    ...  d
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1664
    ... +lastline"""
34260
5ce32fe7df34 py3: fix doctests in patch.py to be compatible with Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34259
diff changeset
  1665
    >>> hunks = parsepatch([rawpatch])
25424
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1666
    >>> hunkscomingfromfilterpatch = []
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1667
    >>> for h in hunks:
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1668
    ...     hunkscomingfromfilterpatch.append(h)
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1669
    ...     hunkscomingfromfilterpatch.extend(h.hunks)
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1670
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1671
    >>> reversedhunks = reversehunks(hunkscomingfromfilterpatch)
28861
86db5cb55d46 pycompat: switch to util.stringio for py3 compat
timeless <timeless@mozdev.org>
parents: 28341
diff changeset
  1672
    >>> from . import util
86db5cb55d46 pycompat: switch to util.stringio for py3 compat
timeless <timeless@mozdev.org>
parents: 28341
diff changeset
  1673
    >>> fp = util.stringio()
25424
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1674
    >>> for c in reversedhunks:
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1675
    ...      c.write(fp)
34260
5ce32fe7df34 py3: fix doctests in patch.py to be compatible with Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34259
diff changeset
  1676
    >>> fp.seek(0) or None
25424
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1677
    >>> reversedpatch = fp.read()
34152
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34146
diff changeset
  1678
    >>> print(pycompat.sysstr(reversedpatch))
25424
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1679
    diff --git a/folder1/g b/folder1/g
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1680
    --- a/folder1/g
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1681
    +++ b/folder1/g
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1682
    @@ -1,4 +1,3 @@
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1683
    -firstline
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1684
     c
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1685
     1
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1686
     2
32997
66117dae87f9 patch: rewrite reversehunks (issue5337)
Jun Wu <quark@fb.com>
parents: 32409
diff changeset
  1687
    @@ -2,6 +1,6 @@
25424
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1688
     c
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1689
     1
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1690
     2
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1691
    - 3
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1692
    +4
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1693
     5
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1694
     d
32997
66117dae87f9 patch: rewrite reversehunks (issue5337)
Jun Wu <quark@fb.com>
parents: 32409
diff changeset
  1695
    @@ -6,3 +5,2 @@
25424
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1696
     5
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1697
     d
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1698
    -lastline
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1699
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1700
    '''
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1701
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1702
    newhunks = []
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1703
    for c in hunks:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1704
        if util.safehasattr(c, b'reversehunk'):
32997
66117dae87f9 patch: rewrite reversehunks (issue5337)
Jun Wu <quark@fb.com>
parents: 32409
diff changeset
  1705
            c = c.reversehunk()
25424
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1706
        newhunks.append(c)
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1707
    return newhunks
69609f43c752 revert: add an experimental config to use inverted selection
Laurent Charignon <lcharignon@fb.com>
parents: 25359
diff changeset
  1708
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1709
33270
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1710
def parsepatch(originalchunks, maxcontext=None):
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1711
    """patch -> [] of headers -> [] of hunks
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1712
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1713
    If maxcontext is not None, trim context lines if necessary.
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1714
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34084
diff changeset
  1715
    >>> rawpatch = b'''diff --git a/folder1/g b/folder1/g
33270
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1716
    ... --- a/folder1/g
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1717
    ... +++ b/folder1/g
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1718
    ... @@ -1,8 +1,10 @@
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1719
    ...  1
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1720
    ...  2
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1721
    ... -3
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1722
    ...  4
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1723
    ...  5
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1724
    ...  6
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1725
    ... +6.1
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1726
    ... +6.2
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1727
    ...  7
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1728
    ...  8
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1729
    ... +9'''
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1730
    >>> out = util.stringio()
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1731
    >>> headers = parsepatch([rawpatch], maxcontext=1)
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1732
    >>> for header in headers:
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1733
    ...     header.write(out)
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1734
    ...     for hunk in header.hunks:
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1735
    ...         hunk.write(out)
34152
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34146
diff changeset
  1736
    >>> print(pycompat.sysstr(out.getvalue()))
33270
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1737
    diff --git a/folder1/g b/folder1/g
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1738
    --- a/folder1/g
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1739
    +++ b/folder1/g
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1740
    @@ -2,3 +2,2 @@
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1741
     2
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1742
    -3
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1743
     4
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1744
    @@ -6,2 +5,4 @@
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1745
     6
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1746
    +6.1
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1747
    +6.2
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1748
     7
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1749
    @@ -8,1 +9,2 @@
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1750
     8
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1751
    +9
f7b635716ef2 patch: make parsepatch optionally trim context lines
Jun Wu <quark@fb.com>
parents: 33229
diff changeset
  1752
    """
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1753
24265
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1754
    class parser(object):
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1755
        """patch parsing state machine"""
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1756
24265
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1757
        def __init__(self):
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1758
            self.fromline = 0
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1759
            self.toline = 0
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1760
            self.proc = b''
24265
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1761
            self.header = None
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1762
            self.context = []
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1763
            self.before = []
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1764
            self.hunk = []
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1765
            self.headers = []
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1766
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1767
        def addrange(self, limits):
41474
d1d3094b54f9 patch: handle 0 context lines (diff.unified=0) when parsing patches
Kyle Lippincott <spectral@google.com>
parents: 41423
diff changeset
  1768
            self.addcontext([])
24265
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1769
            fromstart, fromend, tostart, toend, proc = limits
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1770
            self.fromline = int(fromstart)
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1771
            self.toline = int(tostart)
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1772
            self.proc = proc
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1773
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1774
        def addcontext(self, context):
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1775
            if self.hunk:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1776
                h = recordhunk(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1777
                    self.header,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1778
                    self.fromline,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1779
                    self.toline,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1780
                    self.proc,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1781
                    self.before,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1782
                    self.hunk,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1783
                    context,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1784
                    maxcontext,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1785
                )
24265
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1786
                self.header.hunks.append(h)
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1787
                self.fromline += len(self.before) + h.removed
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1788
                self.toline += len(self.before) + h.added
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1789
                self.before = []
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1790
                self.hunk = []
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1791
            self.context = context
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1792
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1793
        def addhunk(self, hunk):
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1794
            if self.context:
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1795
                self.before = self.context
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1796
                self.context = []
41474
d1d3094b54f9 patch: handle 0 context lines (diff.unified=0) when parsing patches
Kyle Lippincott <spectral@google.com>
parents: 41423
diff changeset
  1797
            if self.hunk:
d1d3094b54f9 patch: handle 0 context lines (diff.unified=0) when parsing patches
Kyle Lippincott <spectral@google.com>
parents: 41423
diff changeset
  1798
                self.addcontext([])
24265
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1799
            self.hunk = hunk
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1800
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1801
        def newfile(self, hdr):
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1802
            self.addcontext([])
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1803
            h = header(hdr)
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1804
            self.headers.append(h)
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1805
            self.header = h
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1806
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1807
        def addother(self, line):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1808
            pass  # 'other' lines are ignored
24265
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1809
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1810
        def finished(self):
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1811
            self.addcontext([])
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1812
            return self.headers
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1813
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1814
        transitions = {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1815
            b'file': {
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1816
                b'context': addcontext,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1817
                b'file': newfile,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1818
                b'hunk': addhunk,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1819
                b'range': addrange,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1820
            },
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1821
            b'context': {
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1822
                b'file': newfile,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1823
                b'hunk': addhunk,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1824
                b'range': addrange,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1825
                b'other': addother,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1826
            },
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1827
            b'hunk': {
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1828
                b'context': addcontext,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1829
                b'file': newfile,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1830
                b'range': addrange,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1831
            },
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1832
            b'range': {b'context': addcontext, b'hunk': addhunk},
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1833
            b'other': {b'other': addother},
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1834
        }
24265
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1835
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1836
    p = parser()
28861
86db5cb55d46 pycompat: switch to util.stringio for py3 compat
timeless <timeless@mozdev.org>
parents: 28341
diff changeset
  1837
    fp = stringio()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1838
    fp.write(b''.join(originalchunks))
24341
616c01b69898 record: change interface of the filtering function
Laurent Charignon <lcharignon@fb.com>
parents: 24306
diff changeset
  1839
    fp.seek(0)
24265
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1840
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1841
    state = b'context'
24265
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1842
    for newstate, data in scanpatch(fp):
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1843
        try:
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1844
            p.transitions[state][newstate](p, data)
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1845
        except KeyError:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1846
            raise PatchError(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1847
                b'unhandled transition: %s -> %s' % (state, newstate)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1848
            )
24265
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1849
        state = newstate
24341
616c01b69898 record: change interface of the filtering function
Laurent Charignon <lcharignon@fb.com>
parents: 24306
diff changeset
  1850
    del fp
24265
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1851
    return p.finished()
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
  1852
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1853
24244
5918bb365c72 patch.pathtransform: add a prefix parameter
Siddharth Agarwal <sid0@fb.com>
parents: 24243
diff changeset
  1854
def pathtransform(path, strip, prefix):
24243
daee2039dd11 patch.pathtransform: add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 24242
diff changeset
  1855
    '''turn a path from a patch into a path suitable for the repository
daee2039dd11 patch.pathtransform: add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 24242
diff changeset
  1856
24244
5918bb365c72 patch.pathtransform: add a prefix parameter
Siddharth Agarwal <sid0@fb.com>
parents: 24243
diff changeset
  1857
    prefix, if not empty, is expected to be normalized with a / at the end.
5918bb365c72 patch.pathtransform: add a prefix parameter
Siddharth Agarwal <sid0@fb.com>
parents: 24243
diff changeset
  1858
24243
daee2039dd11 patch.pathtransform: add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 24242
diff changeset
  1859
    Returns (stripped components, path in repository).
daee2039dd11 patch.pathtransform: add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 24242
diff changeset
  1860
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34084
diff changeset
  1861
    >>> pathtransform(b'a/b/c', 0, b'')
24243
daee2039dd11 patch.pathtransform: add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 24242
diff changeset
  1862
    ('', 'a/b/c')
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34084
diff changeset
  1863
    >>> pathtransform(b'   a/b/c   ', 0, b'')
24243
daee2039dd11 patch.pathtransform: add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 24242
diff changeset
  1864
    ('', '   a/b/c')
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34084
diff changeset
  1865
    >>> pathtransform(b'   a/b/c   ', 2, b'')
24243
daee2039dd11 patch.pathtransform: add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 24242
diff changeset
  1866
    ('a/b/', 'c')
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34084
diff changeset
  1867
    >>> pathtransform(b'a/b/c', 0, b'd/e/')
24385
885a573fa619 patch.pathtransform: prepend prefix even if strip is 0
Siddharth Agarwal <sid0@fb.com>
parents: 24371
diff changeset
  1868
    ('', 'd/e/a/b/c')
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34084
diff changeset
  1869
    >>> pathtransform(b'   a//b/c   ', 2, b'd/e/')
24244
5918bb365c72 patch.pathtransform: add a prefix parameter
Siddharth Agarwal <sid0@fb.com>
parents: 24243
diff changeset
  1870
    ('a//b/', 'd/e/c')
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34084
diff changeset
  1871
    >>> pathtransform(b'a/b/c', 3, b'')
24243
daee2039dd11 patch.pathtransform: add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 24242
diff changeset
  1872
    Traceback (most recent call last):
daee2039dd11 patch.pathtransform: add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 24242
diff changeset
  1873
    PatchError: unable to strip away 1 of 3 dirs from a/b/c
daee2039dd11 patch.pathtransform: add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 24242
diff changeset
  1874
    '''
11022
0429d0d49f92 patch: strip paths in leaked git patchmeta objects
Mads Kiilerich <mads@kiilerich.com>
parents: 11021
diff changeset
  1875
    pathlen = len(path)
0429d0d49f92 patch: strip paths in leaked git patchmeta objects
Mads Kiilerich <mads@kiilerich.com>
parents: 11021
diff changeset
  1876
    i = 0
0429d0d49f92 patch: strip paths in leaked git patchmeta objects
Mads Kiilerich <mads@kiilerich.com>
parents: 11021
diff changeset
  1877
    if strip == 0:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1878
        return b'', prefix + path.rstrip()
11022
0429d0d49f92 patch: strip paths in leaked git patchmeta objects
Mads Kiilerich <mads@kiilerich.com>
parents: 11021
diff changeset
  1879
    count = strip
0429d0d49f92 patch: strip paths in leaked git patchmeta objects
Mads Kiilerich <mads@kiilerich.com>
parents: 11021
diff changeset
  1880
    while count > 0:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1881
        i = path.find(b'/', i)
11022
0429d0d49f92 patch: strip paths in leaked git patchmeta objects
Mads Kiilerich <mads@kiilerich.com>
parents: 11021
diff changeset
  1882
        if i == -1:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1883
            raise PatchError(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1884
                _(b"unable to strip away %d of %d dirs from %s")
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1885
                % (count, strip, path)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1886
            )
11022
0429d0d49f92 patch: strip paths in leaked git patchmeta objects
Mads Kiilerich <mads@kiilerich.com>
parents: 11021
diff changeset
  1887
        i += 1
0429d0d49f92 patch: strip paths in leaked git patchmeta objects
Mads Kiilerich <mads@kiilerich.com>
parents: 11021
diff changeset
  1888
        # consume '//' in the path
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1889
        while i < pathlen - 1 and path[i : i + 1] == b'/':
11022
0429d0d49f92 patch: strip paths in leaked git patchmeta objects
Mads Kiilerich <mads@kiilerich.com>
parents: 11021
diff changeset
  1890
            i += 1
0429d0d49f92 patch: strip paths in leaked git patchmeta objects
Mads Kiilerich <mads@kiilerich.com>
parents: 11021
diff changeset
  1891
        count -= 1
24244
5918bb365c72 patch.pathtransform: add a prefix parameter
Siddharth Agarwal <sid0@fb.com>
parents: 24243
diff changeset
  1892
    return path[:i].lstrip(), prefix + path[i:].rstrip()
11022
0429d0d49f92 patch: strip paths in leaked git patchmeta objects
Mads Kiilerich <mads@kiilerich.com>
parents: 11021
diff changeset
  1893
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1894
24245
740a17f885a1 patch.makepatchmeta: accept a prefix parameter
Siddharth Agarwal <sid0@fb.com>
parents: 24244
diff changeset
  1895
def makepatchmeta(backend, afile_orig, bfile_orig, hunk, strip, prefix):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1896
    nulla = afile_orig == b"/dev/null"
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1897
    nullb = bfile_orig == b"/dev/null"
14451
c78d41db6f88 patch: refactor file creation/removal detection
Patrick Mezard <pmezard@gmail.com>
parents: 14437
diff changeset
  1898
    create = nulla and hunk.starta == 0 and hunk.lena == 0
c78d41db6f88 patch: refactor file creation/removal detection
Patrick Mezard <pmezard@gmail.com>
parents: 14437
diff changeset
  1899
    remove = nullb and hunk.startb == 0 and hunk.lenb == 0
24245
740a17f885a1 patch.makepatchmeta: accept a prefix parameter
Siddharth Agarwal <sid0@fb.com>
parents: 24244
diff changeset
  1900
    abase, afile = pathtransform(afile_orig, strip, prefix)
14351
d54f9bbcc640 patch: add lexists() to backends, use it in selectfile()
Patrick Mezard <pmezard@gmail.com>
parents: 14350
diff changeset
  1901
    gooda = not nulla and backend.exists(afile)
24245
740a17f885a1 patch.makepatchmeta: accept a prefix parameter
Siddharth Agarwal <sid0@fb.com>
parents: 24244
diff changeset
  1902
    bbase, bfile = pathtransform(bfile_orig, strip, prefix)
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1903
    if afile == bfile:
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1904
        goodb = gooda
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1905
    else:
14351
d54f9bbcc640 patch: add lexists() to backends, use it in selectfile()
Patrick Mezard <pmezard@gmail.com>
parents: 14350
diff changeset
  1906
        goodb = not nullb and backend.exists(bfile)
14451
c78d41db6f88 patch: refactor file creation/removal detection
Patrick Mezard <pmezard@gmail.com>
parents: 14437
diff changeset
  1907
    missing = not goodb and not gooda and not create
9328
648d6a1a1cf2 patch: create file even if source is not /dev/null
Brendan Cully <brendan@kublai.com>
parents: 9248
diff changeset
  1908
11820
75de514a50f3 patch: fix typo in comment
Martin Geisler <mg@aragost.com>
parents: 11645
diff changeset
  1909
    # some diff programs apparently produce patches where the afile is
75de514a50f3 patch: fix typo in comment
Martin Geisler <mg@aragost.com>
parents: 11645
diff changeset
  1910
    # not /dev/null, but afile starts with bfile
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1911
    abasedir = afile[: afile.rfind(b'/') + 1]
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1912
    bbasedir = bfile[: bfile.rfind(b'/') + 1]
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1913
    if (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1914
        missing
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1915
        and abasedir == bbasedir
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1916
        and afile.startswith(bfile)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1917
        and hunk.starta == 0
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1918
        and hunk.lena == 0
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1919
    ):
14451
c78d41db6f88 patch: refactor file creation/removal detection
Patrick Mezard <pmezard@gmail.com>
parents: 14437
diff changeset
  1920
        create = True
c78d41db6f88 patch: refactor file creation/removal detection
Patrick Mezard <pmezard@gmail.com>
parents: 14437
diff changeset
  1921
        missing = False
9328
648d6a1a1cf2 patch: create file even if source is not /dev/null
Brendan Cully <brendan@kublai.com>
parents: 9248
diff changeset
  1922
6295
bace1990ab12 patch: fix corner case with update + copy patch handling (issue 937)
Patrick Mezard <pmezard@gmail.com>
parents: 6280
diff changeset
  1923
    # If afile is "a/b/foo" and bfile is "a/b/foo.orig" we assume the
bace1990ab12 patch: fix corner case with update + copy patch handling (issue 937)
Patrick Mezard <pmezard@gmail.com>
parents: 6280
diff changeset
  1924
    # diff is between a file and its backup. In this case, the original
bace1990ab12 patch: fix corner case with update + copy patch handling (issue 937)
Patrick Mezard <pmezard@gmail.com>
parents: 6280
diff changeset
  1925
    # file should be patched (see original mpatch code).
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1926
    isbackup = abase == bbase and bfile.startswith(afile)
5652
e90e72c6b4c7 patch: write rej files for missing targets (issue 853)
Patrick Mezard <pmezard@gmail.com>
parents: 5651
diff changeset
  1927
    fname = None
e90e72c6b4c7 patch: write rej files for missing targets (issue 853)
Patrick Mezard <pmezard@gmail.com>
parents: 5651
diff changeset
  1928
    if not missing:
e90e72c6b4c7 patch: write rej files for missing targets (issue 853)
Patrick Mezard <pmezard@gmail.com>
parents: 5651
diff changeset
  1929
        if gooda and goodb:
24306
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24269
diff changeset
  1930
            if isbackup:
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24269
diff changeset
  1931
                fname = afile
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24269
diff changeset
  1932
            else:
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24269
diff changeset
  1933
                fname = bfile
5652
e90e72c6b4c7 patch: write rej files for missing targets (issue 853)
Patrick Mezard <pmezard@gmail.com>
parents: 5651
diff changeset
  1934
        elif gooda:
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1935
            fname = afile
5760
0145f9afb0e7 Removed tabs and trailing whitespace in python files
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5706
diff changeset
  1936
5652
e90e72c6b4c7 patch: write rej files for missing targets (issue 853)
Patrick Mezard <pmezard@gmail.com>
parents: 5651
diff changeset
  1937
    if not fname:
e90e72c6b4c7 patch: write rej files for missing targets (issue 853)
Patrick Mezard <pmezard@gmail.com>
parents: 5651
diff changeset
  1938
        if not nullb:
24306
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24269
diff changeset
  1939
            if isbackup:
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24269
diff changeset
  1940
                fname = afile
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24269
diff changeset
  1941
            else:
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24269
diff changeset
  1942
                fname = bfile
5652
e90e72c6b4c7 patch: write rej files for missing targets (issue 853)
Patrick Mezard <pmezard@gmail.com>
parents: 5651
diff changeset
  1943
        elif not nulla:
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1944
            fname = afile
5652
e90e72c6b4c7 patch: write rej files for missing targets (issue 853)
Patrick Mezard <pmezard@gmail.com>
parents: 5651
diff changeset
  1945
        else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1946
            raise PatchError(_(b"undefined source and destination files"))
5760
0145f9afb0e7 Removed tabs and trailing whitespace in python files
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5706
diff changeset
  1947
14566
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
  1948
    gp = patchmeta(fname)
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
  1949
    if create:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1950
        gp.op = b'ADD'
14566
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
  1951
    elif remove:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1952
        gp.op = b'DELETE'
14566
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
  1953
    return gp
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  1954
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1955
24264
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
  1956
def scanpatch(fp):
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
  1957
    """like patch.iterhunks, but yield different events
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
  1958
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
  1959
    - ('file',    [header_lines + fromfile + tofile])
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
  1960
    - ('context', [context_lines])
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
  1961
    - ('hunk',    [hunk_lines])
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
  1962
    - ('range',   (-start,len, +start,len, proc))
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
  1963
    """
34083
871a58b5f428 py3: fix type of regex literals in patch.py
Yuya Nishihara <yuya@tcha.org>
parents: 34059
diff changeset
  1964
    lines_re = re.compile(br'@@ -(\d+),(\d+) \+(\d+),(\d+) @@\s*(.*)')
24264
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
  1965
    lr = linereader(fp)
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
  1966
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
  1967
    def scanwhile(first, p):
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
  1968
        """scan lr while predicate holds"""
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
  1969
        lines = [first]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1970
        for line in iter(lr.readline, b''):
24264
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
  1971
            if p(line):
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
  1972
                lines.append(line)
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
  1973
            else:
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
  1974
                lr.push(line)
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
  1975
                break
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
  1976
        return lines
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
  1977
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1978
    for line in iter(lr.readline, b''):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1979
        if line.startswith(b'diff --git a/') or line.startswith(b'diff -r '):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1980
24264
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
  1981
            def notheader(line):
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
  1982
                s = line.split(None, 1)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1983
                return not s or s[0] not in (b'---', b'diff')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  1984
24264
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
  1985
            header = scanwhile(line, notheader)
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
  1986
            fromfile = lr.readline()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1987
            if fromfile.startswith(b'---'):
24264
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
  1988
                tofile = lr.readline()
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
  1989
                header += [fromfile, tofile]
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
  1990
            else:
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
  1991
                lr.push(fromfile)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1992
            yield b'file', header
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1993
        elif line.startswith(b' '):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1994
            cs = (b' ', b'\\')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1995
            yield b'context', scanwhile(line, lambda l: l.startswith(cs))
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1996
        elif line.startswith((b'-', b'+')):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1997
            cs = (b'-', b'+', b'\\')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1998
            yield b'hunk', scanwhile(line, lambda l: l.startswith(cs))
24264
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
  1999
        else:
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
  2000
            m = lines_re.match(line)
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
  2001
            if m:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2002
                yield b'range', m.groups()
24264
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
  2003
            else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2004
                yield b'other', line
24264
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
  2005
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2006
7152
f0055cec8446 patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 7151
diff changeset
  2007
def scangitpatch(lr, firstline):
7186
f77c8d8331ca clean up trailing spaces, leading spaces in C
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7153
diff changeset
  2008
    """
7152
f0055cec8446 patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 7151
diff changeset
  2009
    Git patches can emit:
f0055cec8446 patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 7151
diff changeset
  2010
    - rename a to b
f0055cec8446 patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 7151
diff changeset
  2011
    - change b
f0055cec8446 patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 7151
diff changeset
  2012
    - copy a to c
f0055cec8446 patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 7151
diff changeset
  2013
    - change c
7186
f77c8d8331ca clean up trailing spaces, leading spaces in C
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7153
diff changeset
  2014
7152
f0055cec8446 patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 7151
diff changeset
  2015
    We cannot apply this sequence as-is, the renamed 'a' could not be
f0055cec8446 patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 7151
diff changeset
  2016
    found for it would have been renamed already. And we cannot copy
f0055cec8446 patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 7151
diff changeset
  2017
    from 'b' instead because 'b' would have been changed already. So
f0055cec8446 patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 7151
diff changeset
  2018
    we scan the git patch for copy and rename commands so we can
f0055cec8446 patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 7151
diff changeset
  2019
    perform the copies ahead of time.
f0055cec8446 patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 7151
diff changeset
  2020
    """
f0055cec8446 patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 7151
diff changeset
  2021
    pos = 0
f0055cec8446 patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 7151
diff changeset
  2022
    try:
f0055cec8446 patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 7151
diff changeset
  2023
        pos = lr.fp.tell()
f0055cec8446 patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 7151
diff changeset
  2024
        fp = lr.fp
f0055cec8446 patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 7151
diff changeset
  2025
    except IOError:
28861
86db5cb55d46 pycompat: switch to util.stringio for py3 compat
timeless <timeless@mozdev.org>
parents: 28341
diff changeset
  2026
        fp = stringio(lr.fp.read())
14418
0174d1f79280 patch: remove EOL support from linereader class
Patrick Mezard <pmezard@gmail.com>
parents: 14402
diff changeset
  2027
    gitlr = linereader(fp)
7152
f0055cec8446 patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 7151
diff changeset
  2028
    gitlr.push(firstline)
12669
b0fa39c68370 patch: remove unused flags from readgitpatch()
Patrick Mezard <pmezard@gmail.com>
parents: 12645
diff changeset
  2029
    gitpatches = readgitpatch(gitlr)
7152
f0055cec8446 patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 7151
diff changeset
  2030
    fp.seek(pos)
12669
b0fa39c68370 patch: remove unused flags from readgitpatch()
Patrick Mezard <pmezard@gmail.com>
parents: 12645
diff changeset
  2031
    return gitpatches
7152
f0055cec8446 patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 7151
diff changeset
  2032
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2033
14240
28762bb767dc patch: remove unused ui arg to iterhunks
Idan Kamara <idankk86@gmail.com>
parents: 14234
diff changeset
  2034
def iterhunks(fp):
5650
5d3e2f918d65 patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents: 5649
diff changeset
  2035
    """Read a patch and yield the following events:
5d3e2f918d65 patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents: 5649
diff changeset
  2036
    - ("file", afile, bfile, firsthunk): select a new target file.
5d3e2f918d65 patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents: 5649
diff changeset
  2037
    - ("hunk", hunk): a new hunk is ready to be applied, follows a
5d3e2f918d65 patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents: 5649
diff changeset
  2038
    "file" event.
5d3e2f918d65 patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents: 5649
diff changeset
  2039
    - ("git", gitchanges): current diff is in git format, gitchanges
5d3e2f918d65 patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents: 5649
diff changeset
  2040
    maps filenames to gitpatch records. Unique event.
5d3e2f918d65 patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents: 5649
diff changeset
  2041
    """
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2042
    afile = b""
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2043
    bfile = b""
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  2044
    state = None
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  2045
    hunknum = 0
14017
19a7b48446e3 patch: remove redundant variable in iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 13971
diff changeset
  2046
    emitfile = newfile = False
14388
37c997d21752 patch: stop handling hunkless git blocks out of stream
Patrick Mezard <pmezard@gmail.com>
parents: 14387
diff changeset
  2047
    gitpatches = None
2861
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
  2048
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  2049
    # our states
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  2050
    BFILE = 1
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  2051
    context = None
10128
ea7c392f2b08 patch: drop eol normalization fast-path for 'lf' and 'crlf'
Patrick Mezard <pmezard@gmail.com>
parents: 10127
diff changeset
  2052
    lr = linereader(fp)
2861
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
  2053
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2054
    for x in iter(lr.readline, b''):
14383
1bd52cb12a55 patch: refactor iterhunks() regular and binary files emission
Patrick Mezard <pmezard@gmail.com>
parents: 14382
diff changeset
  2055
        if state == BFILE and (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2056
            (not context and x.startswith(b'@'))
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2057
            or (context is not False and x.startswith(b'***************'))
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2058
            or x.startswith(b'GIT binary patch')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2059
        ):
14388
37c997d21752 patch: stop handling hunkless git blocks out of stream
Patrick Mezard <pmezard@gmail.com>
parents: 14387
diff changeset
  2060
            gp = None
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2061
            if gitpatches and gitpatches[-1].ispatching(afile, bfile):
16506
fc4e0fecf403 patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents: 16475
diff changeset
  2062
                gp = gitpatches.pop()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2063
            if x.startswith(b'GIT binary patch'):
16523
727068417b95 patch: include file name in binary patch error messages
Patrick Mezard <patrick@mezard.eu>
parents: 16522
diff changeset
  2064
                h = binhunk(lr, gp.path)
14383
1bd52cb12a55 patch: refactor iterhunks() regular and binary files emission
Patrick Mezard <pmezard@gmail.com>
parents: 14382
diff changeset
  2065
            else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2066
                if context is None and x.startswith(b'***************'):
14383
1bd52cb12a55 patch: refactor iterhunks() regular and binary files emission
Patrick Mezard <pmezard@gmail.com>
parents: 14382
diff changeset
  2067
                    context = True
14451
c78d41db6f88 patch: refactor file creation/removal detection
Patrick Mezard <pmezard@gmail.com>
parents: 14437
diff changeset
  2068
                h = hunk(x, hunknum + 1, lr, context)
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  2069
            hunknum += 1
5650
5d3e2f918d65 patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents: 5649
diff changeset
  2070
            if emitfile:
5d3e2f918d65 patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents: 5649
diff changeset
  2071
                emitfile = False
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2072
                yield b'file', (afile, bfile, h, gp and gp.copy() or None)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2073
            yield b'hunk', h
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2074
        elif x.startswith(b'diff --git a/'):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2075
            m = gitre.match(x.rstrip(b' \r\n'))
14387
e1b4a7a7263a patch: reindent code
Patrick Mezard <pmezard@gmail.com>
parents: 14386
diff changeset
  2076
            if not m:
e1b4a7a7263a patch: reindent code
Patrick Mezard <pmezard@gmail.com>
parents: 14386
diff changeset
  2077
                continue
16506
fc4e0fecf403 patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents: 16475
diff changeset
  2078
            if gitpatches is None:
14387
e1b4a7a7263a patch: reindent code
Patrick Mezard <pmezard@gmail.com>
parents: 14386
diff changeset
  2079
                # scan whole input for git metadata
16506
fc4e0fecf403 patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents: 16475
diff changeset
  2080
                gitpatches = scangitpatch(lr, x)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2081
                yield b'git', [
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2082
                    g.copy() for g in gitpatches if g.op in (b'COPY', b'RENAME')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2083
                ]
14388
37c997d21752 patch: stop handling hunkless git blocks out of stream
Patrick Mezard <pmezard@gmail.com>
parents: 14387
diff changeset
  2084
                gitpatches.reverse()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2085
            afile = b'a/' + m.group(1)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2086
            bfile = b'b/' + m.group(2)
16506
fc4e0fecf403 patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents: 16475
diff changeset
  2087
            while gitpatches and not gitpatches[-1].ispatching(afile, bfile):
fc4e0fecf403 patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents: 16475
diff changeset
  2088
                gp = gitpatches.pop()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2089
                yield b'file', (
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2090
                    b'a/' + gp.path,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2091
                    b'b/' + gp.path,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2092
                    None,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2093
                    gp.copy(),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2094
                )
16506
fc4e0fecf403 patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents: 16475
diff changeset
  2095
            if not gitpatches:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2096
                raise PatchError(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2097
                    _(b'failed to synchronize metadata for "%s"') % afile[2:]
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2098
                )
14387
e1b4a7a7263a patch: reindent code
Patrick Mezard <pmezard@gmail.com>
parents: 14386
diff changeset
  2099
            newfile = True
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2100
        elif x.startswith(b'---'):
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  2101
            # check for a unified diff
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  2102
            l2 = lr.readline()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2103
            if not l2.startswith(b'+++'):
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  2104
                lr.push(l2)
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  2105
                continue
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  2106
            newfile = True
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  2107
            context = False
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  2108
            afile = parsefilename(x)
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  2109
            bfile = parsefilename(l2)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2110
        elif x.startswith(b'***'):
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  2111
            # check for a context diff
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  2112
            l2 = lr.readline()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2113
            if not l2.startswith(b'---'):
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  2114
                lr.push(l2)
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  2115
                continue
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  2116
            l3 = lr.readline()
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  2117
            lr.push(l3)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2118
            if not l3.startswith(b"***************"):
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  2119
                lr.push(l2)
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  2120
                continue
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  2121
            newfile = True
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  2122
            context = True
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  2123
            afile = parsefilename(x)
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  2124
            bfile = parsefilename(l2)
3057
d16b93f4a6ca unlink temporary patch files even when an exception is raised
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3056
diff changeset
  2125
14017
19a7b48446e3 patch: remove redundant variable in iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 13971
diff changeset
  2126
        if newfile:
19a7b48446e3 patch: remove redundant variable in iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 13971
diff changeset
  2127
            newfile = False
5650
5d3e2f918d65 patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents: 5649
diff changeset
  2128
            emitfile = True
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  2129
            state = BFILE
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  2130
            hunknum = 0
5650
5d3e2f918d65 patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents: 5649
diff changeset
  2131
14388
37c997d21752 patch: stop handling hunkless git blocks out of stream
Patrick Mezard <pmezard@gmail.com>
parents: 14387
diff changeset
  2132
    while gitpatches:
16506
fc4e0fecf403 patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents: 16475
diff changeset
  2133
        gp = gitpatches.pop()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2134
        yield b'file', (b'a/' + gp.path, b'b/' + gp.path, None, gp.copy())
14388
37c997d21752 patch: stop handling hunkless git blocks out of stream
Patrick Mezard <pmezard@gmail.com>
parents: 14387
diff changeset
  2135
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2136
20137
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
  2137
def applybindelta(binchunk, data):
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
  2138
    """Apply a binary delta hunk
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
  2139
    The algorithm used is the algorithm from git's patch-delta.c
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
  2140
    """
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2141
20137
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
  2142
    def deltahead(binchunk):
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
  2143
        i = 0
38118
e887381e2976 py3: bytestr() bytes to get bytechar while iterating on it
Pulkit Goyal <7895pulkit@gmail.com>
parents: 38117
diff changeset
  2144
        for c in pycompat.bytestr(binchunk):
20137
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
  2145
            i += 1
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
  2146
            if not (ord(c) & 0x80):
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
  2147
                return i
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
  2148
        return i
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2149
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2150
    out = b""
20137
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
  2151
    s = deltahead(binchunk)
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
  2152
    binchunk = binchunk[s:]
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
  2153
    s = deltahead(binchunk)
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
  2154
    binchunk = binchunk[s:]
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
  2155
    i = 0
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
  2156
    while i < len(binchunk):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2157
        cmd = ord(binchunk[i : i + 1])
20137
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
  2158
        i += 1
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2159
        if cmd & 0x80:
20137
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
  2160
            offset = 0
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
  2161
            size = 0
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2162
            if cmd & 0x01:
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2163
                offset = ord(binchunk[i : i + 1])
20137
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
  2164
                i += 1
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2165
            if cmd & 0x02:
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2166
                offset |= ord(binchunk[i : i + 1]) << 8
20137
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
  2167
                i += 1
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2168
            if cmd & 0x04:
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2169
                offset |= ord(binchunk[i : i + 1]) << 16
20137
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
  2170
                i += 1
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2171
            if cmd & 0x08:
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2172
                offset |= ord(binchunk[i : i + 1]) << 24
20137
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
  2173
                i += 1
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2174
            if cmd & 0x10:
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2175
                size = ord(binchunk[i : i + 1])
20137
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
  2176
                i += 1
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2177
            if cmd & 0x20:
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2178
                size |= ord(binchunk[i : i + 1]) << 8
20137
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
  2179
                i += 1
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2180
            if cmd & 0x40:
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2181
                size |= ord(binchunk[i : i + 1]) << 16
20137
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
  2182
                i += 1
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
  2183
            if size == 0:
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
  2184
                size = 0x10000
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
  2185
            offset_end = offset + size
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
  2186
            out += data[offset:offset_end]
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
  2187
        elif cmd != 0:
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
  2188
            offset_end = i + cmd
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
  2189
            out += binchunk[i:offset_end]
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
  2190
            i += cmd
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
  2191
        else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2192
            raise PatchError(_(b'unexpected delta opcode 0'))
20137
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
  2193
    return out
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
  2194
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2195
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2196
def applydiff(ui, fp, backend, store, strip=1, prefix=b'', eolmode=b'strict'):
10966
91c58cf54eee patch: refactor applydiff to allow for mempatching
Augie Fackler <durin42@gmail.com>
parents: 10965
diff changeset
  2197
    """Reads a patch from fp and tries to apply it.
5650
5d3e2f918d65 patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents: 5649
diff changeset
  2198
14565
3cacc232f27f patch: stop updating changed files set in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14564
diff changeset
  2199
    Returns 0 for a clean patch, -1 if any rejects were found and 1 if
3cacc232f27f patch: stop updating changed files set in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14564
diff changeset
  2200
    there was any fuzz.
8810
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
  2201
10101
155fe35534d3 patch: propagate eolmode down to patchfile
Martin Geisler <mg@lazybytes.net>
parents: 9725
diff changeset
  2202
    If 'eolmode' is 'strict', the patch content and patched file are
155fe35534d3 patch: propagate eolmode down to patchfile
Martin Geisler <mg@lazybytes.net>
parents: 9725
diff changeset
  2203
    read in binary mode. Otherwise, line endings are ignored when
155fe35534d3 patch: propagate eolmode down to patchfile
Martin Geisler <mg@lazybytes.net>
parents: 9725
diff changeset
  2204
    patching then normalized according to 'eolmode'.
8810
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
  2205
    """
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2206
    return _applydiff(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2207
        ui,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2208
        fp,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2209
        patchfile,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2210
        backend,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2211
        store,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2212
        strip=strip,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2213
        prefix=prefix,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2214
        eolmode=eolmode,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2215
    )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2216
10966
91c58cf54eee patch: refactor applydiff to allow for mempatching
Augie Fackler <durin42@gmail.com>
parents: 10965
diff changeset
  2217
35085
1706eae096e2 patch: accept prefix argument to changedfiles() helper
Martin von Zweigbergk <martinvonz@google.com>
parents: 35023
diff changeset
  2218
def _canonprefix(repo, prefix):
1706eae096e2 patch: accept prefix argument to changedfiles() helper
Martin von Zweigbergk <martinvonz@google.com>
parents: 35023
diff changeset
  2219
    if prefix:
1706eae096e2 patch: accept prefix argument to changedfiles() helper
Martin von Zweigbergk <martinvonz@google.com>
parents: 35023
diff changeset
  2220
        prefix = pathutil.canonpath(repo.root, repo.getcwd(), prefix)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2221
        if prefix != b'':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2222
            prefix += b'/'
35085
1706eae096e2 patch: accept prefix argument to changedfiles() helper
Martin von Zweigbergk <martinvonz@google.com>
parents: 35023
diff changeset
  2223
    return prefix
1706eae096e2 patch: accept prefix argument to changedfiles() helper
Martin von Zweigbergk <martinvonz@google.com>
parents: 35023
diff changeset
  2224
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2225
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2226
def _applydiff(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2227
    ui, fp, patcher, backend, store, strip=1, prefix=b'', eolmode=b'strict'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2228
):
35085
1706eae096e2 patch: accept prefix argument to changedfiles() helper
Martin von Zweigbergk <martinvonz@google.com>
parents: 35023
diff changeset
  2229
    prefix = _canonprefix(backend.repo, prefix)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2230
14389
909ac6b9636b patch: stop modifying gitpatch objects
Patrick Mezard <pmezard@gmail.com>
parents: 14388
diff changeset
  2231
    def pstrip(p):
24246
394a91cb3d4a patch._applydiff: accept a prefix parameter
Siddharth Agarwal <sid0@fb.com>
parents: 24245
diff changeset
  2232
        return pathtransform(p, strip - 1, prefix)[1]
14389
909ac6b9636b patch: stop modifying gitpatch objects
Patrick Mezard <pmezard@gmail.com>
parents: 14388
diff changeset
  2233
5650
5d3e2f918d65 patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents: 5649
diff changeset
  2234
    rejects = 0
5d3e2f918d65 patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents: 5649
diff changeset
  2235
    err = 0
5d3e2f918d65 patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents: 5649
diff changeset
  2236
    current_file = None
5d3e2f918d65 patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents: 5649
diff changeset
  2237
14240
28762bb767dc patch: remove unused ui arg to iterhunks
Idan Kamara <idankk86@gmail.com>
parents: 14234
diff changeset
  2238
    for state, values in iterhunks(fp):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2239
        if state == b'hunk':
5650
5d3e2f918d65 patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents: 5649
diff changeset
  2240
            if not current_file:
5d3e2f918d65 patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents: 5649
diff changeset
  2241
                continue
11021
c47a1cfad572 patch: minor cleanup of _applydiff
Mads Kiilerich <mads@kiilerich.com>
parents: 11020
diff changeset
  2242
            ret = current_file.apply(values)
14565
3cacc232f27f patch: stop updating changed files set in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14564
diff changeset
  2243
            if ret > 0:
3cacc232f27f patch: stop updating changed files set in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14564
diff changeset
  2244
                err = 1
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2245
        elif state == b'file':
13701
bc38ff7cb919 patch: move closefile() into patchfile.close()
Patrick Mezard <pmezard@gmail.com>
parents: 13700
diff changeset
  2246
            if current_file:
bc38ff7cb919 patch: move closefile() into patchfile.close()
Patrick Mezard <pmezard@gmail.com>
parents: 13700
diff changeset
  2247
                rejects += current_file.close()
14388
37c997d21752 patch: stop handling hunkless git blocks out of stream
Patrick Mezard <pmezard@gmail.com>
parents: 14387
diff changeset
  2248
                current_file = None
37c997d21752 patch: stop handling hunkless git blocks out of stream
Patrick Mezard <pmezard@gmail.com>
parents: 14387
diff changeset
  2249
            afile, bfile, first_hunk, gp = values
37c997d21752 patch: stop handling hunkless git blocks out of stream
Patrick Mezard <pmezard@gmail.com>
parents: 14387
diff changeset
  2250
            if gp:
14566
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
  2251
                gp.path = pstrip(gp.path)
14452
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
  2252
                if gp.oldpath:
14566
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
  2253
                    gp.oldpath = pstrip(gp.oldpath)
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
  2254
            else:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2255
                gp = makepatchmeta(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2256
                    backend, afile, bfile, first_hunk, strip, prefix
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2257
                )
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2258
            if gp.op == b'RENAME':
14566
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
  2259
                backend.unlink(gp.oldpath)
14388
37c997d21752 patch: stop handling hunkless git blocks out of stream
Patrick Mezard <pmezard@gmail.com>
parents: 14387
diff changeset
  2260
            if not first_hunk:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2261
                if gp.op == b'DELETE':
14566
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
  2262
                    backend.unlink(gp.path)
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
  2263
                    continue
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
  2264
                data, mode = None, None
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2265
                if gp.op in (b'RENAME', b'COPY'):
14609
f53dc0787424 patch: extend filtestore to store an optional copy source
Patrick Mezard <pmezard@gmail.com>
parents: 14566
diff changeset
  2266
                    data, mode = store.getfile(gp.oldpath)[:2]
30078
173bdb502503 import: abort instead of crashing when copy source does not exist (issue5375)
Ryan McElroy <rmcelroy@fb.com>
parents: 29952
diff changeset
  2267
                    if data is None:
173bdb502503 import: abort instead of crashing when copy source does not exist (issue5375)
Ryan McElroy <rmcelroy@fb.com>
parents: 29952
diff changeset
  2268
                        # This means that the old path does not exist
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2269
                        raise PatchError(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2270
                            _(b"source file '%s' does not exist") % gp.oldpath
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2271
                        )
14566
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
  2272
                if gp.mode:
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
  2273
                    mode = gp.mode
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2274
                    if gp.op == b'ADD':
14566
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
  2275
                        # Added files without content have no hunk and
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
  2276
                        # must be created
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2277
                        data = b''
14566
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
  2278
                if data or mode:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2279
                    if gp.op in (b'ADD', b'RENAME', b'COPY') and backend.exists(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2280
                        gp.path
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2281
                    ):
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2282
                        raise PatchError(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2283
                            _(
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2284
                                b"cannot create %s: destination "
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2285
                                b"already exists"
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2286
                            )
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2287
                            % gp.path
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2288
                        )
14566
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
  2289
                    backend.setfile(gp.path, data, mode, gp.oldpath)
14388
37c997d21752 patch: stop handling hunkless git blocks out of stream
Patrick Mezard <pmezard@gmail.com>
parents: 14387
diff changeset
  2290
                continue
5650
5d3e2f918d65 patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents: 5649
diff changeset
  2291
            try:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2292
                current_file = patcher(ui, gp, backend, store, eolmode=eolmode)
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25658
diff changeset
  2293
            except PatchError as inst:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2294
                ui.warn(str(inst) + b'\n')
11021
c47a1cfad572 patch: minor cleanup of _applydiff
Mads Kiilerich <mads@kiilerich.com>
parents: 11020
diff changeset
  2295
                current_file = None
5650
5d3e2f918d65 patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents: 5649
diff changeset
  2296
                rejects += 1
5d3e2f918d65 patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents: 5649
diff changeset
  2297
                continue
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2298
        elif state == b'git':
11021
c47a1cfad572 patch: minor cleanup of _applydiff
Mads Kiilerich <mads@kiilerich.com>
parents: 11020
diff changeset
  2299
            for gp in values:
14452
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
  2300
                path = pstrip(gp.oldpath)
22296
650b5b6e75ed convert: use None value for missing files instead of overloading IOError
Mads Kiilerich <madski@unity3d.com>
parents: 21833
diff changeset
  2301
                data, mode = backend.getfile(path)
650b5b6e75ed convert: use None value for missing files instead of overloading IOError
Mads Kiilerich <madski@unity3d.com>
parents: 21833
diff changeset
  2302
                if data is None:
16813
6d42c797ca6e patch: keep patching after missing copy source (issue3480)
Patrick Mezard <patrick@mezard.eu>
parents: 16650
diff changeset
  2303
                    # The error ignored here will trigger a getfile()
6d42c797ca6e patch: keep patching after missing copy source (issue3480)
Patrick Mezard <patrick@mezard.eu>
parents: 16650
diff changeset
  2304
                    # error in a place more appropriate for error
6d42c797ca6e patch: keep patching after missing copy source (issue3480)
Patrick Mezard <patrick@mezard.eu>
parents: 16650
diff changeset
  2305
                    # handling, and will not interrupt the patching
6d42c797ca6e patch: keep patching after missing copy source (issue3480)
Patrick Mezard <patrick@mezard.eu>
parents: 16650
diff changeset
  2306
                    # process.
22296
650b5b6e75ed convert: use None value for missing files instead of overloading IOError
Mads Kiilerich <madski@unity3d.com>
parents: 21833
diff changeset
  2307
                    pass
16813
6d42c797ca6e patch: keep patching after missing copy source (issue3480)
Patrick Mezard <patrick@mezard.eu>
parents: 16650
diff changeset
  2308
                else:
6d42c797ca6e patch: keep patching after missing copy source (issue3480)
Patrick Mezard <patrick@mezard.eu>
parents: 16650
diff changeset
  2309
                    store.setfile(path, data, mode)
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  2310
        else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2311
            raise error.Abort(_(b'unsupported parser state: %s') % state)
5649
a583117b536a patch: move NoHunk detection up with parsing code
Patrick Mezard <pmezard@gmail.com>
parents: 5581
diff changeset
  2312
13701
bc38ff7cb919 patch: move closefile() into patchfile.close()
Patrick Mezard <pmezard@gmail.com>
parents: 13700
diff changeset
  2313
    if current_file:
bc38ff7cb919 patch: move closefile() into patchfile.close()
Patrick Mezard <pmezard@gmail.com>
parents: 13700
diff changeset
  2314
        rejects += current_file.close()
5650
5d3e2f918d65 patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents: 5649
diff changeset
  2315
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  2316
    if rejects:
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  2317
        return -1
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
  2318
    return err
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2868
diff changeset
  2319
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2320
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2321
def _externalpatch(ui, repo, patcher, patchname, strip, files, similarity):
7151
b5bc5293021c patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents: 7150
diff changeset
  2322
    """use <patcher> to apply <patchname> to the working directory.
b5bc5293021c patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents: 7150
diff changeset
  2323
    returns whether patch was applied with fuzz factor."""
b5bc5293021c patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents: 7150
diff changeset
  2324
b5bc5293021c patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents: 7150
diff changeset
  2325
    fuzz = False
12673
9ad16d1bce4b patch: simplify externalpatch() arguments
Patrick Mezard <pmezard@gmail.com>
parents: 12671
diff changeset
  2326
    args = []
14382
2d16f15da7bd patch: remove patch.patch() cwd argument
Patrick Mezard <pmezard@gmail.com>
parents: 14381
diff changeset
  2327
    cwd = repo.root
7151
b5bc5293021c patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents: 7150
diff changeset
  2328
    if cwd:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2329
        args.append(b'-d %s' % procutil.shellquote(cwd))
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2330
    cmd = b'%s %s -p%d < %s' % (
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2331
        patcher,
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2332
        b' '.join(args),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2333
        strip,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2334
        procutil.shellquote(patchname),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2335
    )
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2336
    ui.debug(b'Using external patch tool: %s\n' % cmd)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2337
    fp = procutil.popen(cmd, b'rb')
14381
d4192500586a patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents: 14370
diff changeset
  2338
    try:
30407
564b33acc21f patch: migrate to util.iterfile
Jun Wu <quark@fb.com>
parents: 30078
diff changeset
  2339
        for line in util.iterfile(fp):
14381
d4192500586a patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents: 14370
diff changeset
  2340
            line = line.rstrip()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2341
            ui.note(line + b'\n')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2342
            if line.startswith(b'patching file '):
14381
d4192500586a patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents: 14370
diff changeset
  2343
                pf = util.parsepatchoutput(line)
d4192500586a patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents: 14370
diff changeset
  2344
                printed_file = False
14564
65f4512e40e4 patch: turn patch() touched files dict into a set
Patrick Mezard <pmezard@gmail.com>
parents: 14535
diff changeset
  2345
                files.add(pf)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2346
            elif line.find(b'with fuzz') >= 0:
14381
d4192500586a patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents: 14370
diff changeset
  2347
                fuzz = True
d4192500586a patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents: 14370
diff changeset
  2348
                if not printed_file:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2349
                    ui.warn(pf + b'\n')
14381
d4192500586a patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents: 14370
diff changeset
  2350
                    printed_file = True
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2351
                ui.warn(line + b'\n')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2352
            elif line.find(b'saving rejects to file') >= 0:
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2353
                ui.warn(line + b'\n')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2354
            elif line.find(b'FAILED') >= 0:
14381
d4192500586a patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents: 14370
diff changeset
  2355
                if not printed_file:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2356
                    ui.warn(pf + b'\n')
14381
d4192500586a patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents: 14370
diff changeset
  2357
                    printed_file = True
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2358
                ui.warn(line + b'\n')
14381
d4192500586a patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents: 14370
diff changeset
  2359
    finally:
d4192500586a patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents: 14370
diff changeset
  2360
        if files:
19155
0b3689a08df5 patch: use scmutil.marktouched instead of scmutil.addremove
Siddharth Agarwal <sid0@fb.com>
parents: 18830
diff changeset
  2361
            scmutil.marktouched(repo, files, similarity)
7151
b5bc5293021c patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents: 7150
diff changeset
  2362
    code = fp.close()
b5bc5293021c patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents: 7150
diff changeset
  2363
    if code:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2364
        raise PatchError(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2365
            _(b"patch command failed: %s") % procutil.explainexit(code)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2366
        )
7151
b5bc5293021c patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents: 7150
diff changeset
  2367
    return fuzz
b5bc5293021c patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents: 7150
diff changeset
  2368
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2369
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2370
def patchbackend(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2371
    ui, backend, patchobj, strip, prefix, files=None, eolmode=b'strict'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2372
):
9683
5c8651e2f5e0 patch: don't use mutable object as default argument
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9682
diff changeset
  2373
    if files is None:
14564
65f4512e40e4 patch: turn patch() touched files dict into a set
Patrick Mezard <pmezard@gmail.com>
parents: 14535
diff changeset
  2374
        files = set()
8810
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
  2375
    if eolmode is None:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2376
        eolmode = ui.config(b'patch', b'eol')
10101
155fe35534d3 patch: propagate eolmode down to patchfile
Martin Geisler <mg@lazybytes.net>
parents: 9725
diff changeset
  2377
    if eolmode.lower() not in eolmodes:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2378
        raise error.Abort(_(b'unsupported line endings type: %s') % eolmode)
10101
155fe35534d3 patch: propagate eolmode down to patchfile
Martin Geisler <mg@lazybytes.net>
parents: 9725
diff changeset
  2379
    eolmode = eolmode.lower()
8843
eb7b247a98ea kill trailing whitespace
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8817
diff changeset
  2380
14452
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
  2381
    store = filestore()
7151
b5bc5293021c patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents: 7150
diff changeset
  2382
    try:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2383
        fp = open(patchobj, b'rb')
7151
b5bc5293021c patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents: 7150
diff changeset
  2384
    except TypeError:
b5bc5293021c patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents: 7150
diff changeset
  2385
        fp = patchobj
b5bc5293021c patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents: 7150
diff changeset
  2386
    try:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2387
        ret = applydiff(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2388
            ui, fp, backend, store, strip=strip, prefix=prefix, eolmode=eolmode
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2389
        )
7151
b5bc5293021c patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents: 7150
diff changeset
  2390
    finally:
10203
6e26e3c2083f patch: explicitely close input patch files when leaving
Patrick Mezard <pmezard@gmail.com>
parents: 10135
diff changeset
  2391
        if fp != patchobj:
6e26e3c2083f patch: explicitely close input patch files when leaving
Patrick Mezard <pmezard@gmail.com>
parents: 10135
diff changeset
  2392
            fp.close()
14564
65f4512e40e4 patch: turn patch() touched files dict into a set
Patrick Mezard <pmezard@gmail.com>
parents: 14535
diff changeset
  2393
        files.update(backend.close())
14452
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
  2394
        store.close()
7151
b5bc5293021c patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents: 7150
diff changeset
  2395
    if ret < 0:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2396
        raise PatchError(_(b'patch failed to apply'))
7151
b5bc5293021c patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents: 7150
diff changeset
  2397
    return ret > 0
b5bc5293021c patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents: 7150
diff changeset
  2398
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2399
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2400
def internalpatch(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2401
    ui,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2402
    repo,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2403
    patchobj,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2404
    strip,
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2405
    prefix=b'',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2406
    files=None,
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2407
    eolmode=b'strict',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2408
    similarity=0,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2409
):
14611
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
  2410
    """use builtin patch to apply <patchobj> to the working directory.
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
  2411
    returns whether patch was applied with fuzz factor."""
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
  2412
    backend = workingbackend(ui, repo, similarity)
24254
60c279ab7bd3 patch.internalpatch: accept a prefix parameter
Siddharth Agarwal <sid0@fb.com>
parents: 24253
diff changeset
  2413
    return patchbackend(ui, backend, patchobj, strip, prefix, files, eolmode)
14611
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
  2414
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2415
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2416
def patchrepo(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2417
    ui, repo, ctx, store, patchobj, strip, prefix, files=None, eolmode=b'strict'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2418
):
14611
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
  2419
    backend = repobackend(ui, repo, ctx, store)
24260
76225ab5a5da cmdutil.tryimportone: allow importing relative patches with --bypass
Siddharth Agarwal <sid0@fb.com>
parents: 24259
diff changeset
  2420
    return patchbackend(ui, backend, patchobj, strip, prefix, files, eolmode)
14611
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
  2421
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2422
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2423
def patch(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2424
    ui,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2425
    repo,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2426
    patchname,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2427
    strip=1,
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2428
    prefix=b'',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2429
    files=None,
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2430
    eolmode=b'strict',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2431
    similarity=0,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2432
):
8810
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
  2433
    """Apply <patchname> to the working directory.
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
  2434
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
  2435
    'eolmode' specifies how end of lines should be handled. It can be:
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
  2436
    - 'strict': inputs are read in binary mode, EOLs are preserved
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
  2437
    - 'crlf': EOLs are ignored when patching and reset to CRLF
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
  2438
    - 'lf': EOLs are ignored when patching and reset to LF
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
  2439
    - None: get it from user settings, default to 'strict'
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
  2440
    'eolmode' is ignored when using an external patcher program.
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
  2441
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
  2442
    Returns whether patch was applied with fuzz factor.
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
  2443
    """
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2444
    patcher = ui.config(b'ui', b'patch')
9683
5c8651e2f5e0 patch: don't use mutable object as default argument
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9682
diff changeset
  2445
    if files is None:
14564
65f4512e40e4 patch: turn patch() touched files dict into a set
Patrick Mezard <pmezard@gmail.com>
parents: 14535
diff changeset
  2446
        files = set()
21553
bee0e1cffdd3 import: add --partial flag to create a changeset despite failed hunks
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20972
diff changeset
  2447
    if patcher:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2448
        return _externalpatch(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2449
            ui, repo, patcher, patchname, strip, files, similarity
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2450
        )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2451
    return internalpatch(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2452
        ui, repo, patchname, strip, prefix, files, eolmode, similarity
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2453
    )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2454
7151
b5bc5293021c patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents: 7150
diff changeset
  2455
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2456
def changedfiles(ui, repo, patchpath, strip=1, prefix=b''):
14351
d54f9bbcc640 patch: add lexists() to backends, use it in selectfile()
Patrick Mezard <pmezard@gmail.com>
parents: 14350
diff changeset
  2457
    backend = fsbackend(ui, repo.root)
35085
1706eae096e2 patch: accept prefix argument to changedfiles() helper
Martin von Zweigbergk <martinvonz@google.com>
parents: 35023
diff changeset
  2458
    prefix = _canonprefix(repo, prefix)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2459
    with open(patchpath, b'rb') as fp:
14255
576256a81cb6 patch: introduce changedfiles
Idan Kamara <idankk86@gmail.com>
parents: 14240
diff changeset
  2460
        changed = set()
576256a81cb6 patch: introduce changedfiles
Idan Kamara <idankk86@gmail.com>
parents: 14240
diff changeset
  2461
        for state, values in iterhunks(fp):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2462
            if state == b'file':
14388
37c997d21752 patch: stop handling hunkless git blocks out of stream
Patrick Mezard <pmezard@gmail.com>
parents: 14387
diff changeset
  2463
                afile, bfile, first_hunk, gp = values
37c997d21752 patch: stop handling hunkless git blocks out of stream
Patrick Mezard <pmezard@gmail.com>
parents: 14387
diff changeset
  2464
                if gp:
35085
1706eae096e2 patch: accept prefix argument to changedfiles() helper
Martin von Zweigbergk <martinvonz@google.com>
parents: 35023
diff changeset
  2465
                    gp.path = pathtransform(gp.path, strip - 1, prefix)[1]
14566
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
  2466
                    if gp.oldpath:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2467
                        gp.oldpath = pathtransform(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2468
                            gp.oldpath, strip - 1, prefix
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2469
                        )[1]
14566
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
  2470
                else:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2471
                    gp = makepatchmeta(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2472
                        backend, afile, bfile, first_hunk, strip, prefix
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2473
                    )
14566
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
  2474
                changed.add(gp.path)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2475
                if gp.op == b'RENAME':
14566
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
  2476
                    changed.add(gp.oldpath)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2477
            elif state not in (b'hunk', b'git'):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2478
                raise error.Abort(_(b'unsupported parser state: %s') % state)
14255
576256a81cb6 patch: introduce changedfiles
Idan Kamara <idankk86@gmail.com>
parents: 14240
diff changeset
  2479
        return changed
576256a81cb6 patch: introduce changedfiles
Idan Kamara <idankk86@gmail.com>
parents: 14240
diff changeset
  2480
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2481
10189
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10151
diff changeset
  2482
class GitDiffRequired(Exception):
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10151
diff changeset
  2483
    pass
7198
df79ee9b6278 patch: extract local function addmodehdr
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7186
diff changeset
  2484
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2485
38588
b62000a28812 diffutil: remove diffopts() in favor of diffallopts()
Yuya Nishihara <yuya@tcha.org>
parents: 38563
diff changeset
  2486
diffopts = diffutil.diffallopts
38563
c88d2c9b00dd diffutil: extract diff options code into a dedicated util-module
Boris Feld <boris.feld@octobus.net>
parents: 38497
diff changeset
  2487
diffallopts = diffutil.diffallopts
c88d2c9b00dd diffutil: extract diff options code into a dedicated util-module
Boris Feld <boris.feld@octobus.net>
parents: 38497
diff changeset
  2488
difffeatureopts = diffutil.difffeatureopts
10615
3bb438ce4458 patch/diff: move diff related code next to each other
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10611
diff changeset
  2489
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2490
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2491
def diff(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2492
    repo,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2493
    node1=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2494
    node2=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2495
    match=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2496
    changes=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2497
    opts=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2498
    losedatafn=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2499
    pathfn=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2500
    copy=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2501
    copysourcematch=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2502
    hunksfilterfn=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2503
):
7308
b6f5490effbf patch: turn patch.diff() into a generator
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7267
diff changeset
  2504
    '''yields diff of changes to files between two nodes, or node and
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2868
diff changeset
  2505
    working directory.
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2868
diff changeset
  2506
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2868
diff changeset
  2507
    if node1 is None, use first dirstate parent instead.
10189
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10151
diff changeset
  2508
    if node2 is None, compare node1 with working directory.
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10151
diff changeset
  2509
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10151
diff changeset
  2510
    losedatafn(**kwarg) is a callable run when opts.upgrade=True and
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10151
diff changeset
  2511
    every time some change cannot be represented with the current
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10151
diff changeset
  2512
    patch format. Return False to upgrade to git patch format, True to
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10151
diff changeset
  2513
    accept the loss or raise an exception to abort the diff. It is
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10151
diff changeset
  2514
    called with the name of current file being diffed as 'fn'. If set
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10151
diff changeset
  2515
    to None, patches will always be upgraded to git format when
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10151
diff changeset
  2516
    necessary.
12167
d2c5b0927c28 diff: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12144
diff changeset
  2517
d2c5b0927c28 diff: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12144
diff changeset
  2518
    prefix is a filename prefix that is prepended to all filenames on
d2c5b0927c28 diff: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12144
diff changeset
  2519
    display (used for subrepos).
24417
f2e1e097cda1 patch.diff: add support for diffs relative to a subdirectory
Siddharth Agarwal <sid0@fb.com>
parents: 24416
diff changeset
  2520
f2e1e097cda1 patch.diff: add support for diffs relative to a subdirectory
Siddharth Agarwal <sid0@fb.com>
parents: 24416
diff changeset
  2521
    relroot, if not empty, must be normalized with a trailing /. Any match
29422
40d53d4b5925 patch: allow copy information to be passed in
Henrik Stuart <henriks@unity3d.com>
parents: 29341
diff changeset
  2522
    patterns that fall outside it will be ignored.
40d53d4b5925 patch: allow copy information to be passed in
Henrik Stuart <henriks@unity3d.com>
parents: 29341
diff changeset
  2523
40d53d4b5925 patch: allow copy information to be passed in
Henrik Stuart <henriks@unity3d.com>
parents: 29341
diff changeset
  2524
    copy, if not empty, should contain mappings {dst@y: src@x} of copy
34856
890afefa7296 diff: pass a diff hunks filter function from changeset_printer to patch.diff()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 34855
diff changeset
  2525
    information.
890afefa7296 diff: pass a diff hunks filter function from changeset_printer to patch.diff()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 34855
diff changeset
  2526
41631
74f53d3bd685 patch: accept second matcher that applies only to copy sources (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41630
diff changeset
  2527
    if copysourcematch is not None, then copy sources will be filtered by this
74f53d3bd685 patch: accept second matcher that applies only to copy sources (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41630
diff changeset
  2528
    matcher
74f53d3bd685 patch: accept second matcher that applies only to copy sources (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41630
diff changeset
  2529
34856
890afefa7296 diff: pass a diff hunks filter function from changeset_printer to patch.diff()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 34855
diff changeset
  2530
    hunksfilterfn, if not None, should be a function taking a filectx and
890afefa7296 diff: pass a diff hunks filter function from changeset_printer to patch.diff()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 34855
diff changeset
  2531
    hunks generator that may yield filtered hunks.
890afefa7296 diff: pass a diff hunks filter function from changeset_printer to patch.diff()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 34855
diff changeset
  2532
    '''
41629
e834f6f6f221 patch: pass in context objects into diffhunks() (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41548
diff changeset
  2533
    if not node1 and not node2:
e834f6f6f221 patch: pass in context objects into diffhunks() (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41548
diff changeset
  2534
        node1 = repo.dirstate.p1()
e834f6f6f221 patch: pass in context objects into diffhunks() (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41548
diff changeset
  2535
e834f6f6f221 patch: pass in context objects into diffhunks() (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41548
diff changeset
  2536
    ctx1 = repo[node1]
e834f6f6f221 patch: pass in context objects into diffhunks() (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41548
diff changeset
  2537
    ctx2 = repo[node2]
e834f6f6f221 patch: pass in context objects into diffhunks() (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41548
diff changeset
  2538
34855
35c6a54ec1ff diff: also yield file context objects in patch.trydiff() (API)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 34566
diff changeset
  2539
    for fctx1, fctx2, hdr, hunks in diffhunks(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2540
        repo,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2541
        ctx1=ctx1,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2542
        ctx2=ctx2,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2543
        match=match,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2544
        changes=changes,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2545
        opts=opts,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2546
        losedatafn=losedatafn,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2547
        pathfn=pathfn,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2548
        copy=copy,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2549
        copysourcematch=copysourcematch,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2550
    ):
34856
890afefa7296 diff: pass a diff hunks filter function from changeset_printer to patch.diff()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 34855
diff changeset
  2551
        if hunksfilterfn is not None:
34908
907ff34e1460 log: add an assertion about fctx not being None in patch.diff()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 34856
diff changeset
  2552
            # If the file has been removed, fctx2 is None; but this should
907ff34e1460 log: add an assertion about fctx not being None in patch.diff()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 34856
diff changeset
  2553
            # not occur here since we catch removed files early in
35928
c8e2d6ed1f9e cmdutil: drop aliases for logcmdutil functions (API)
Yuya Nishihara <yuya@tcha.org>
parents: 35890
diff changeset
  2554
            # logcmdutil.getlinerangerevs() for 'hg log -L'.
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2555
            assert (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2556
                fctx2 is not None
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2557
            ), b'fctx2 unexpectly None in diff hunks filtering'
34856
890afefa7296 diff: pass a diff hunks filter function from changeset_printer to patch.diff()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 34855
diff changeset
  2558
            hunks = hunksfilterfn(fctx2, hunks)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2559
        text = b''.join(sum((list(hlines) for hrange, hlines in hunks), []))
34561
fe6125ebdf91 patch: rename "header" variable into "hdr" in diff()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 34521
diff changeset
  2560
        if hdr and (text or len(hdr) > 1):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2561
            yield b'\n'.join(hdr) + b'\n'
31284
a8023a64c40d patch: add a diffhunks function yielding (diffheaders, hunks)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31283
diff changeset
  2562
        if text:
a8023a64c40d patch: add a diffhunks function yielding (diffheaders, hunks)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31283
diff changeset
  2563
            yield text
a8023a64c40d patch: add a diffhunks function yielding (diffheaders, hunks)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31283
diff changeset
  2564
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2565
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2566
def diffhunks(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2567
    repo,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2568
    ctx1,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2569
    ctx2,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2570
    match=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2571
    changes=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2572
    opts=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2573
    losedatafn=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2574
    pathfn=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2575
    copy=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2576
    copysourcematch=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2577
):
31284
a8023a64c40d patch: add a diffhunks function yielding (diffheaders, hunks)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31283
diff changeset
  2578
    """Yield diff of changes to files in the form of (`header`, `hunks`) tuples
a8023a64c40d patch: add a diffhunks function yielding (diffheaders, hunks)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31283
diff changeset
  2579
    where `header` is a list of diff headers and `hunks` is an iterable of
a8023a64c40d patch: add a diffhunks function yielding (diffheaders, hunks)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31283
diff changeset
  2580
    (`hunkrange`, `hunklines`) tuples.
a8023a64c40d patch: add a diffhunks function yielding (diffheaders, hunks)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31283
diff changeset
  2581
a8023a64c40d patch: add a diffhunks function yielding (diffheaders, hunks)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31283
diff changeset
  2582
    See diff() for the meaning of parameters.
a8023a64c40d patch: add a diffhunks function yielding (diffheaders, hunks)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31283
diff changeset
  2583
    """
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2868
diff changeset
  2584
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2868
diff changeset
  2585
    if opts is None:
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2868
diff changeset
  2586
        opts = mdiff.defaultopts
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2868
diff changeset
  2587
9123
360f61c2919f Make patch.diff filelog cache LRU of 20 files. Fixes issue1738.
Brendan Cully <brendan@kublai.com>
parents: 8891
diff changeset
  2588
    def lrugetfilectx():
360f61c2919f Make patch.diff filelog cache LRU of 20 files. Fixes issue1738.
Brendan Cully <brendan@kublai.com>
parents: 8891
diff changeset
  2589
        cache = {}
25113
0ca8410ea345 util: drop alias for collections.deque
Martin von Zweigbergk <martinvonz@google.com>
parents: 24845
diff changeset
  2590
        order = collections.deque()
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2591
9123
360f61c2919f Make patch.diff filelog cache LRU of 20 files. Fixes issue1738.
Brendan Cully <brendan@kublai.com>
parents: 8891
diff changeset
  2592
        def getfilectx(f, ctx):
360f61c2919f Make patch.diff filelog cache LRU of 20 files. Fixes issue1738.
Brendan Cully <brendan@kublai.com>
parents: 8891
diff changeset
  2593
            fctx = ctx.filectx(f, filelog=cache.get(f))
360f61c2919f Make patch.diff filelog cache LRU of 20 files. Fixes issue1738.
Brendan Cully <brendan@kublai.com>
parents: 8891
diff changeset
  2594
            if f not in cache:
360f61c2919f Make patch.diff filelog cache LRU of 20 files. Fixes issue1738.
Brendan Cully <brendan@kublai.com>
parents: 8891
diff changeset
  2595
                if len(cache) > 20:
16803
107a3270a24a cleanup: use the deque type where appropriate
Bryan O'Sullivan <bryano@fb.com>
parents: 16705
diff changeset
  2596
                    del cache[order.popleft()]
9684
618af2034ca6 patch: use the public ctx API instead of the internals
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9683
diff changeset
  2597
                cache[f] = fctx.filelog()
9123
360f61c2919f Make patch.diff filelog cache LRU of 20 files. Fixes issue1738.
Brendan Cully <brendan@kublai.com>
parents: 8891
diff changeset
  2598
            else:
360f61c2919f Make patch.diff filelog cache LRU of 20 files. Fixes issue1738.
Brendan Cully <brendan@kublai.com>
parents: 8891
diff changeset
  2599
                order.remove(f)
360f61c2919f Make patch.diff filelog cache LRU of 20 files. Fixes issue1738.
Brendan Cully <brendan@kublai.com>
parents: 8891
diff changeset
  2600
            order.append(f)
360f61c2919f Make patch.diff filelog cache LRU of 20 files. Fixes issue1738.
Brendan Cully <brendan@kublai.com>
parents: 8891
diff changeset
  2601
            return fctx
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2602
9123
360f61c2919f Make patch.diff filelog cache LRU of 20 files. Fixes issue1738.
Brendan Cully <brendan@kublai.com>
parents: 8891
diff changeset
  2603
        return getfilectx
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2604
9123
360f61c2919f Make patch.diff filelog cache LRU of 20 files. Fixes issue1738.
Brendan Cully <brendan@kublai.com>
parents: 8891
diff changeset
  2605
    getfilectx = lrugetfilectx()
2934
2f190e998eb3 Teach mq about git patches
Brendan Cully <brendan@kublai.com>
parents: 2933
diff changeset
  2606
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2868
diff changeset
  2607
    if not changes:
38814
59af0c7d103f patch: use ctx1.status(ctx2) instead of repo.status(ctx1, ctx2)
Martin von Zweigbergk <martinvonz@google.com>
parents: 38630
diff changeset
  2608
        changes = ctx1.status(ctx2, match=match)
6760
4faaa0535ea7 status: clean up all users for unknown files
Matt Mackall <mpm@selenic.com>
parents: 6758
diff changeset
  2609
    modified, added, removed = changes[:3]
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2868
diff changeset
  2610
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2868
diff changeset
  2611
    if not modified and not added and not removed:
10189
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10151
diff changeset
  2612
        return []
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10151
diff changeset
  2613
24306
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24269
diff changeset
  2614
    if repo.ui.debugflag:
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24269
diff changeset
  2615
        hexfunc = hex
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24269
diff changeset
  2616
    else:
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24269
diff changeset
  2617
        hexfunc = short
21833
c1ceec0c8cb4 patch: use ctx.node() instead of bare node variable
Sean Farley <sean.michael.farley@gmail.com>
parents: 21790
diff changeset
  2618
    revs = [hexfunc(node) for node in [ctx1.node(), ctx2.node()] if node]
10189
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10151
diff changeset
  2619
29422
40d53d4b5925 patch: allow copy information to be passed in
Henrik Stuart <henriks@unity3d.com>
parents: 29341
diff changeset
  2620
    if copy is None:
40d53d4b5925 patch: allow copy information to be passed in
Henrik Stuart <henriks@unity3d.com>
parents: 29341
diff changeset
  2621
        copy = {}
40d53d4b5925 patch: allow copy information to be passed in
Henrik Stuart <henriks@unity3d.com>
parents: 29341
diff changeset
  2622
        if opts.git or opts.upgrade:
40d53d4b5925 patch: allow copy information to be passed in
Henrik Stuart <henriks@unity3d.com>
parents: 29341
diff changeset
  2623
            copy = copies.pathcopies(ctx1, ctx2, match=match)
10189
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10151
diff changeset
  2624
41631
74f53d3bd685 patch: accept second matcher that applies only to copy sources (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41630
diff changeset
  2625
    if copysourcematch:
74f53d3bd685 patch: accept second matcher that applies only to copy sources (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41630
diff changeset
  2626
        # filter out copies where source side isn't inside the matcher
41513
a5d8824483ba diff: drop duplicate filter of copies by destination
Martin von Zweigbergk <martinvonz@google.com>
parents: 41512
diff changeset
  2627
        # (copies.pathcopies() already filtered out the destination)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2628
        copy = {
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2629
            dst: src for dst, src in copy.iteritems() if copysourcematch(src)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2630
        }
24417
f2e1e097cda1 patch.diff: add support for diffs relative to a subdirectory
Siddharth Agarwal <sid0@fb.com>
parents: 24416
diff changeset
  2631
27900
27572a5cc409 diff: move status fixup earlier, out of _filepairs()
Martin von Zweigbergk <martinvonz@google.com>
parents: 27796
diff changeset
  2632
    modifiedset = set(modified)
27572a5cc409 diff: move status fixup earlier, out of _filepairs()
Martin von Zweigbergk <martinvonz@google.com>
parents: 27796
diff changeset
  2633
    addedset = set(added)
27901
29c8e35d3283 diff: don't crash when merged-in addition was removed (issue4786)
Martin von Zweigbergk <martinvonz@google.com>
parents: 27900
diff changeset
  2634
    removedset = set(removed)
27900
27572a5cc409 diff: move status fixup earlier, out of _filepairs()
Martin von Zweigbergk <martinvonz@google.com>
parents: 27796
diff changeset
  2635
    for f in modified:
27572a5cc409 diff: move status fixup earlier, out of _filepairs()
Martin von Zweigbergk <martinvonz@google.com>
parents: 27796
diff changeset
  2636
        if f not in ctx1:
27572a5cc409 diff: move status fixup earlier, out of _filepairs()
Martin von Zweigbergk <martinvonz@google.com>
parents: 27796
diff changeset
  2637
            # Fix up added, since merged-in additions appear as
27572a5cc409 diff: move status fixup earlier, out of _filepairs()
Martin von Zweigbergk <martinvonz@google.com>
parents: 27796
diff changeset
  2638
            # modifications during merges
27572a5cc409 diff: move status fixup earlier, out of _filepairs()
Martin von Zweigbergk <martinvonz@google.com>
parents: 27796
diff changeset
  2639
            modifiedset.remove(f)
27572a5cc409 diff: move status fixup earlier, out of _filepairs()
Martin von Zweigbergk <martinvonz@google.com>
parents: 27796
diff changeset
  2640
            addedset.add(f)
27901
29c8e35d3283 diff: don't crash when merged-in addition was removed (issue4786)
Martin von Zweigbergk <martinvonz@google.com>
parents: 27900
diff changeset
  2641
    for f in removed:
29c8e35d3283 diff: don't crash when merged-in addition was removed (issue4786)
Martin von Zweigbergk <martinvonz@google.com>
parents: 27900
diff changeset
  2642
        if f not in ctx1:
29c8e35d3283 diff: don't crash when merged-in addition was removed (issue4786)
Martin von Zweigbergk <martinvonz@google.com>
parents: 27900
diff changeset
  2643
            # Merged-in additions that are then removed are reported as removed.
29c8e35d3283 diff: don't crash when merged-in addition was removed (issue4786)
Martin von Zweigbergk <martinvonz@google.com>
parents: 27900
diff changeset
  2644
            # They are not in ctx1, so We don't want to show them in the diff.
29c8e35d3283 diff: don't crash when merged-in addition was removed (issue4786)
Martin von Zweigbergk <martinvonz@google.com>
parents: 27900
diff changeset
  2645
            removedset.remove(f)
27900
27572a5cc409 diff: move status fixup earlier, out of _filepairs()
Martin von Zweigbergk <martinvonz@google.com>
parents: 27796
diff changeset
  2646
    modified = sorted(modifiedset)
27572a5cc409 diff: move status fixup earlier, out of _filepairs()
Martin von Zweigbergk <martinvonz@google.com>
parents: 27796
diff changeset
  2647
    added = sorted(addedset)
27901
29c8e35d3283 diff: don't crash when merged-in addition was removed (issue4786)
Martin von Zweigbergk <martinvonz@google.com>
parents: 27900
diff changeset
  2648
    removed = sorted(removedset)
35589
3328d53254d9 py3: use list() to get a list of items using dict.items()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35582
diff changeset
  2649
    for dst, src in list(copy.items()):
27902
51b6ce257e0a diff: don't crash when merged-in addition is copied
Martin von Zweigbergk <martinvonz@google.com>
parents: 27901
diff changeset
  2650
        if src not in ctx1:
51b6ce257e0a diff: don't crash when merged-in addition is copied
Martin von Zweigbergk <martinvonz@google.com>
parents: 27901
diff changeset
  2651
            # Files merged in during a merge and then copied/renamed are
51b6ce257e0a diff: don't crash when merged-in addition is copied
Martin von Zweigbergk <martinvonz@google.com>
parents: 27901
diff changeset
  2652
            # reported as copies. We want to show them in the diff as additions.
51b6ce257e0a diff: don't crash when merged-in addition is copied
Martin von Zweigbergk <martinvonz@google.com>
parents: 27901
diff changeset
  2653
            del copy[dst]
27900
27572a5cc409 diff: move status fixup earlier, out of _filepairs()
Martin von Zweigbergk <martinvonz@google.com>
parents: 27796
diff changeset
  2654
37764
5e67c20915a7 diff: invoke the file prefetch hook
Matt Harbison <matt_harbison@yahoo.com>
parents: 37732
diff changeset
  2655
    prefetchmatch = scmutil.matchfiles(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2656
        repo, list(modifiedset | addedset | removedset)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2657
    )
37764
5e67c20915a7 diff: invoke the file prefetch hook
Matt Harbison <matt_harbison@yahoo.com>
parents: 37732
diff changeset
  2658
    scmutil.prefetchfiles(repo, [ctx1.rev(), ctx2.rev()], prefetchmatch)
5e67c20915a7 diff: invoke the file prefetch hook
Matt Harbison <matt_harbison@yahoo.com>
parents: 37732
diff changeset
  2659
17299
e51d4aedace9 check-code: indent 4 spaces in py files
Mads Kiilerich <mads@kiilerich.com>
parents: 16834
diff changeset
  2660
    def difffn(opts, losedata):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2661
        return trydiff(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2662
            repo,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2663
            revs,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2664
            ctx1,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2665
            ctx2,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2666
            modified,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2667
            added,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2668
            removed,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2669
            copy,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2670
            getfilectx,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2671
            opts,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2672
            losedata,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2673
            pathfn,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2674
        )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2675
10189
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10151
diff changeset
  2676
    if opts.upgrade and not opts.git:
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10151
diff changeset
  2677
        try:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2678
10189
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10151
diff changeset
  2679
            def losedata(fn):
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10151
diff changeset
  2680
                if not losedatafn or not losedatafn(fn=fn):
16687
e34106fa0dc3 cleanup: "raise SomeException()" -> "raise SomeException"
Brodie Rao <brodie@sf.io>
parents: 16686
diff changeset
  2681
                    raise GitDiffRequired
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2682
10189
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10151
diff changeset
  2683
            # Buffer the whole output until we are sure it can be generated
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10151
diff changeset
  2684
            return list(difffn(opts.copy(git=False), losedata))
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10151
diff changeset
  2685
        except GitDiffRequired:
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10151
diff changeset
  2686
            return difffn(opts.copy(git=True), None)
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10151
diff changeset
  2687
    else:
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10151
diff changeset
  2688
        return difffn(opts, None)
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10151
diff changeset
  2689
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2690
37731
5471348921c1 patch: buffer lines for a same hunk
Jun Wu <quark@fb.com>
parents: 37730
diff changeset
  2691
def diffsinglehunk(hunklines):
5471348921c1 patch: buffer lines for a same hunk
Jun Wu <quark@fb.com>
parents: 37730
diff changeset
  2692
    """yield tokens for a list of lines in a single hunk"""
5471348921c1 patch: buffer lines for a same hunk
Jun Wu <quark@fb.com>
parents: 37730
diff changeset
  2693
    for line in hunklines:
5471348921c1 patch: buffer lines for a same hunk
Jun Wu <quark@fb.com>
parents: 37730
diff changeset
  2694
        # chomp
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2695
        chompline = line.rstrip(b'\r\n')
37731
5471348921c1 patch: buffer lines for a same hunk
Jun Wu <quark@fb.com>
parents: 37730
diff changeset
  2696
        # highlight tabs and trailing whitespace
5471348921c1 patch: buffer lines for a same hunk
Jun Wu <quark@fb.com>
parents: 37730
diff changeset
  2697
        stripline = chompline.rstrip()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2698
        if line.startswith(b'-'):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2699
            label = b'diff.deleted'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2700
        elif line.startswith(b'+'):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2701
            label = b'diff.inserted'
37731
5471348921c1 patch: buffer lines for a same hunk
Jun Wu <quark@fb.com>
parents: 37730
diff changeset
  2702
        else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2703
            raise error.ProgrammingError(b'unexpected hunk line: %s' % line)
37731
5471348921c1 patch: buffer lines for a same hunk
Jun Wu <quark@fb.com>
parents: 37730
diff changeset
  2704
        for token in tabsplitter.findall(stripline):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2705
            if token.startswith(b'\t'):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2706
                yield (token, b'diff.tab')
37731
5471348921c1 patch: buffer lines for a same hunk
Jun Wu <quark@fb.com>
parents: 37730
diff changeset
  2707
            else:
5471348921c1 patch: buffer lines for a same hunk
Jun Wu <quark@fb.com>
parents: 37730
diff changeset
  2708
                yield (token, label)
5471348921c1 patch: buffer lines for a same hunk
Jun Wu <quark@fb.com>
parents: 37730
diff changeset
  2709
5471348921c1 patch: buffer lines for a same hunk
Jun Wu <quark@fb.com>
parents: 37730
diff changeset
  2710
        if chompline != stripline:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2711
            yield (chompline[len(stripline) :], b'diff.trailingwhitespace')
37731
5471348921c1 patch: buffer lines for a same hunk
Jun Wu <quark@fb.com>
parents: 37730
diff changeset
  2712
        if chompline != line:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2713
            yield (line[len(chompline) :], b'')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2714
37731
5471348921c1 patch: buffer lines for a same hunk
Jun Wu <quark@fb.com>
parents: 37730
diff changeset
  2715
37732
35632d392279 patch: implement a new worddiff algorithm
Jun Wu <quark@fb.com>
parents: 37731
diff changeset
  2716
def diffsinglehunkinline(hunklines):
35632d392279 patch: implement a new worddiff algorithm
Jun Wu <quark@fb.com>
parents: 37731
diff changeset
  2717
    """yield tokens for a list of lines in a single hunk, with inline colors"""
35632d392279 patch: implement a new worddiff algorithm
Jun Wu <quark@fb.com>
parents: 37731
diff changeset
  2718
    # prepare deleted, and inserted content
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2719
    a = b''
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2720
    b = b''
37732
35632d392279 patch: implement a new worddiff algorithm
Jun Wu <quark@fb.com>
parents: 37731
diff changeset
  2721
    for line in hunklines:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2722
        if line[0:1] == b'-':
37732
35632d392279 patch: implement a new worddiff algorithm
Jun Wu <quark@fb.com>
parents: 37731
diff changeset
  2723
            a += line[1:]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2724
        elif line[0:1] == b'+':
37732
35632d392279 patch: implement a new worddiff algorithm
Jun Wu <quark@fb.com>
parents: 37731
diff changeset
  2725
            b += line[1:]
35632d392279 patch: implement a new worddiff algorithm
Jun Wu <quark@fb.com>
parents: 37731
diff changeset
  2726
        else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2727
            raise error.ProgrammingError(b'unexpected hunk line: %s' % line)
37732
35632d392279 patch: implement a new worddiff algorithm
Jun Wu <quark@fb.com>
parents: 37731
diff changeset
  2728
    # fast path: if either side is empty, use diffsinglehunk
35632d392279 patch: implement a new worddiff algorithm
Jun Wu <quark@fb.com>
parents: 37731
diff changeset
  2729
    if not a or not b:
35632d392279 patch: implement a new worddiff algorithm
Jun Wu <quark@fb.com>
parents: 37731
diff changeset
  2730
        for t in diffsinglehunk(hunklines):
35632d392279 patch: implement a new worddiff algorithm
Jun Wu <quark@fb.com>
parents: 37731
diff changeset
  2731
            yield t
35632d392279 patch: implement a new worddiff algorithm
Jun Wu <quark@fb.com>
parents: 37731
diff changeset
  2732
        return
35632d392279 patch: implement a new worddiff algorithm
Jun Wu <quark@fb.com>
parents: 37731
diff changeset
  2733
    # re-split the content into words
35632d392279 patch: implement a new worddiff algorithm
Jun Wu <quark@fb.com>
parents: 37731
diff changeset
  2734
    al = wordsplitter.findall(a)
35632d392279 patch: implement a new worddiff algorithm
Jun Wu <quark@fb.com>
parents: 37731
diff changeset
  2735
    bl = wordsplitter.findall(b)
35632d392279 patch: implement a new worddiff algorithm
Jun Wu <quark@fb.com>
parents: 37731
diff changeset
  2736
    # re-arrange the words to lines since the diff algorithm is line-based
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2737
    aln = [s if s == b'\n' else s + b'\n' for s in al]
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2738
    bln = [s if s == b'\n' else s + b'\n' for s in bl]
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2739
    an = b''.join(aln)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2740
    bn = b''.join(bln)
37732
35632d392279 patch: implement a new worddiff algorithm
Jun Wu <quark@fb.com>
parents: 37731
diff changeset
  2741
    # run the diff algorithm, prepare atokens and btokens
35632d392279 patch: implement a new worddiff algorithm
Jun Wu <quark@fb.com>
parents: 37731
diff changeset
  2742
    atokens = []
35632d392279 patch: implement a new worddiff algorithm
Jun Wu <quark@fb.com>
parents: 37731
diff changeset
  2743
    btokens = []
35632d392279 patch: implement a new worddiff algorithm
Jun Wu <quark@fb.com>
parents: 37731
diff changeset
  2744
    blocks = mdiff.allblocks(an, bn, lines1=aln, lines2=bln)
35632d392279 patch: implement a new worddiff algorithm
Jun Wu <quark@fb.com>
parents: 37731
diff changeset
  2745
    for (a1, a2, b1, b2), btype in blocks:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2746
        changed = btype == b'!'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2747
        for token in mdiff.splitnewlines(b''.join(al[a1:a2])):
37732
35632d392279 patch: implement a new worddiff algorithm
Jun Wu <quark@fb.com>
parents: 37731
diff changeset
  2748
            atokens.append((changed, token))
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2749
        for token in mdiff.splitnewlines(b''.join(bl[b1:b2])):
37732
35632d392279 patch: implement a new worddiff algorithm
Jun Wu <quark@fb.com>
parents: 37731
diff changeset
  2750
            btokens.append((changed, token))
35632d392279 patch: implement a new worddiff algorithm
Jun Wu <quark@fb.com>
parents: 37731
diff changeset
  2751
35632d392279 patch: implement a new worddiff algorithm
Jun Wu <quark@fb.com>
parents: 37731
diff changeset
  2752
    # yield deleted tokens, then inserted ones
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2753
    for prefix, label, tokens in [
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2754
        (b'-', b'diff.deleted', atokens),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2755
        (b'+', b'diff.inserted', btokens),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2756
    ]:
37732
35632d392279 patch: implement a new worddiff algorithm
Jun Wu <quark@fb.com>
parents: 37731
diff changeset
  2757
        nextisnewline = True
35632d392279 patch: implement a new worddiff algorithm
Jun Wu <quark@fb.com>
parents: 37731
diff changeset
  2758
        for changed, token in tokens:
35632d392279 patch: implement a new worddiff algorithm
Jun Wu <quark@fb.com>
parents: 37731
diff changeset
  2759
            if nextisnewline:
35632d392279 patch: implement a new worddiff algorithm
Jun Wu <quark@fb.com>
parents: 37731
diff changeset
  2760
                yield (prefix, label)
35632d392279 patch: implement a new worddiff algorithm
Jun Wu <quark@fb.com>
parents: 37731
diff changeset
  2761
                nextisnewline = False
35632d392279 patch: implement a new worddiff algorithm
Jun Wu <quark@fb.com>
parents: 37731
diff changeset
  2762
            # special handling line end
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2763
            isendofline = token.endswith(b'\n')
37732
35632d392279 patch: implement a new worddiff algorithm
Jun Wu <quark@fb.com>
parents: 37731
diff changeset
  2764
            if isendofline:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2765
                chomp = token[:-1]  # chomp
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2766
                if chomp.endswith(b'\r'):
38630
e1987261dd05 patch: don't separate \r and \n when colorizing diff output
Sune Foldager <cryo@cyanite.org>
parents: 38589
diff changeset
  2767
                    chomp = chomp[:-1]
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2768
                endofline = token[len(chomp) :]
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2769
                token = chomp.rstrip()  # detect spaces at the end
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2770
                endspaces = chomp[len(token) :]
37732
35632d392279 patch: implement a new worddiff algorithm
Jun Wu <quark@fb.com>
parents: 37731
diff changeset
  2771
            # scan tabs
35632d392279 patch: implement a new worddiff algorithm
Jun Wu <quark@fb.com>
parents: 37731
diff changeset
  2772
            for maybetab in tabsplitter.findall(token):
40282
e4f82db071a4 py3: fix test-diff-color.t
Mark Thomas <mbthomas@fb.com>
parents: 39632
diff changeset
  2773
                if b'\t' == maybetab[0:1]:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2774
                    currentlabel = b'diff.tab'
37732
35632d392279 patch: implement a new worddiff algorithm
Jun Wu <quark@fb.com>
parents: 37731
diff changeset
  2775
                else:
35632d392279 patch: implement a new worddiff algorithm
Jun Wu <quark@fb.com>
parents: 37731
diff changeset
  2776
                    if changed:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2777
                        currentlabel = label + b'.changed'
37732
35632d392279 patch: implement a new worddiff algorithm
Jun Wu <quark@fb.com>
parents: 37731
diff changeset
  2778
                    else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2779
                        currentlabel = label + b'.unchanged'
37732
35632d392279 patch: implement a new worddiff algorithm
Jun Wu <quark@fb.com>
parents: 37731
diff changeset
  2780
                yield (maybetab, currentlabel)
35632d392279 patch: implement a new worddiff algorithm
Jun Wu <quark@fb.com>
parents: 37731
diff changeset
  2781
            if isendofline:
35632d392279 patch: implement a new worddiff algorithm
Jun Wu <quark@fb.com>
parents: 37731
diff changeset
  2782
                if endspaces:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2783
                    yield (endspaces, b'diff.trailingwhitespace')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2784
                yield (endofline, b'')
37732
35632d392279 patch: implement a new worddiff algorithm
Jun Wu <quark@fb.com>
parents: 37731
diff changeset
  2785
                nextisnewline = True
35632d392279 patch: implement a new worddiff algorithm
Jun Wu <quark@fb.com>
parents: 37731
diff changeset
  2786
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2787
10818
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
  2788
def difflabel(func, *args, **kw):
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
  2789
    '''yields 2-tuples of (output, label) based on the output of func()'''
37732
35632d392279 patch: implement a new worddiff algorithm
Jun Wu <quark@fb.com>
parents: 37731
diff changeset
  2790
    if kw.get(r'opts') and kw[r'opts'].worddiff:
35632d392279 patch: implement a new worddiff algorithm
Jun Wu <quark@fb.com>
parents: 37731
diff changeset
  2791
        dodiffhunk = diffsinglehunkinline
35632d392279 patch: implement a new worddiff algorithm
Jun Wu <quark@fb.com>
parents: 37731
diff changeset
  2792
    else:
35632d392279 patch: implement a new worddiff algorithm
Jun Wu <quark@fb.com>
parents: 37731
diff changeset
  2793
        dodiffhunk = diffsinglehunk
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2794
    headprefixes = [
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2795
        (b'diff', b'diff.diffline'),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2796
        (b'copy', b'diff.extended'),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2797
        (b'rename', b'diff.extended'),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2798
        (b'old', b'diff.extended'),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2799
        (b'new', b'diff.extended'),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2800
        (b'deleted', b'diff.extended'),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2801
        (b'index', b'diff.extended'),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2802
        (b'similarity', b'diff.extended'),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2803
        (b'---', b'diff.file_a'),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2804
        (b'+++', b'diff.file_b'),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2805
    ]
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2806
    textprefixes = [
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2807
        (b'@', b'diff.hunk'),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2808
        # - and + are handled by diffsinglehunk
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2809
    ]
15201
2c4fdee4d1a8 diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents: 15159
diff changeset
  2810
    head = False
37731
5471348921c1 patch: buffer lines for a same hunk
Jun Wu <quark@fb.com>
parents: 37730
diff changeset
  2811
5471348921c1 patch: buffer lines for a same hunk
Jun Wu <quark@fb.com>
parents: 37730
diff changeset
  2812
    # buffers a hunk, i.e. adjacent "-", "+" lines without other changes.
5471348921c1 patch: buffer lines for a same hunk
Jun Wu <quark@fb.com>
parents: 37730
diff changeset
  2813
    hunkbuffer = []
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2814
37731
5471348921c1 patch: buffer lines for a same hunk
Jun Wu <quark@fb.com>
parents: 37730
diff changeset
  2815
    def consumehunkbuffer():
5471348921c1 patch: buffer lines for a same hunk
Jun Wu <quark@fb.com>
parents: 37730
diff changeset
  2816
        if hunkbuffer:
37732
35632d392279 patch: implement a new worddiff algorithm
Jun Wu <quark@fb.com>
parents: 37731
diff changeset
  2817
            for token in dodiffhunk(hunkbuffer):
37731
5471348921c1 patch: buffer lines for a same hunk
Jun Wu <quark@fb.com>
parents: 37730
diff changeset
  2818
                yield token
5471348921c1 patch: buffer lines for a same hunk
Jun Wu <quark@fb.com>
parents: 37730
diff changeset
  2819
            hunkbuffer[:] = []
5471348921c1 patch: buffer lines for a same hunk
Jun Wu <quark@fb.com>
parents: 37730
diff changeset
  2820
10818
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
  2821
    for chunk in func(*args, **kw):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2822
        lines = chunk.split(b'\n')
37730
8d730f96e792 patch: move yielding "\n" to the end of loop
Jun Wu <quark@fb.com>
parents: 37621
diff changeset
  2823
        linecount = len(lines)
10818
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
  2824
        for i, line in enumerate(lines):
15201
2c4fdee4d1a8 diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents: 15159
diff changeset
  2825
            if head:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2826
                if line.startswith(b'@'):
15201
2c4fdee4d1a8 diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents: 15159
diff changeset
  2827
                    head = False
2c4fdee4d1a8 diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents: 15159
diff changeset
  2828
            else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2829
                if line and not line.startswith(
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2830
                    (b' ', b'+', b'-', b'@', b'\\')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2831
                ):
15201
2c4fdee4d1a8 diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents: 15159
diff changeset
  2832
                    head = True
22460
c343557a8442 patch: enable diff.tab markup for the color extension
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 22296
diff changeset
  2833
            diffline = False
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2834
            if not head and line and line.startswith((b'+', b'-')):
22460
c343557a8442 patch: enable diff.tab markup for the color extension
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 22296
diff changeset
  2835
                diffline = True
c343557a8442 patch: enable diff.tab markup for the color extension
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 22296
diff changeset
  2836
15201
2c4fdee4d1a8 diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents: 15159
diff changeset
  2837
            prefixes = textprefixes
2c4fdee4d1a8 diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents: 15159
diff changeset
  2838
            if head:
2c4fdee4d1a8 diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents: 15159
diff changeset
  2839
                prefixes = headprefixes
37731
5471348921c1 patch: buffer lines for a same hunk
Jun Wu <quark@fb.com>
parents: 37730
diff changeset
  2840
            if diffline:
5471348921c1 patch: buffer lines for a same hunk
Jun Wu <quark@fb.com>
parents: 37730
diff changeset
  2841
                # buffered
5471348921c1 patch: buffer lines for a same hunk
Jun Wu <quark@fb.com>
parents: 37730
diff changeset
  2842
                bufferedline = line
5471348921c1 patch: buffer lines for a same hunk
Jun Wu <quark@fb.com>
parents: 37730
diff changeset
  2843
                if i + 1 < linecount:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2844
                    bufferedline += b"\n"
37731
5471348921c1 patch: buffer lines for a same hunk
Jun Wu <quark@fb.com>
parents: 37730
diff changeset
  2845
                hunkbuffer.append(bufferedline)
10818
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
  2846
            else:
37731
5471348921c1 patch: buffer lines for a same hunk
Jun Wu <quark@fb.com>
parents: 37730
diff changeset
  2847
                # unbuffered
5471348921c1 patch: buffer lines for a same hunk
Jun Wu <quark@fb.com>
parents: 37730
diff changeset
  2848
                for token in consumehunkbuffer():
5471348921c1 patch: buffer lines for a same hunk
Jun Wu <quark@fb.com>
parents: 37730
diff changeset
  2849
                    yield token
5471348921c1 patch: buffer lines for a same hunk
Jun Wu <quark@fb.com>
parents: 37730
diff changeset
  2850
                stripline = line.rstrip()
5471348921c1 patch: buffer lines for a same hunk
Jun Wu <quark@fb.com>
parents: 37730
diff changeset
  2851
                for prefix, label in prefixes:
5471348921c1 patch: buffer lines for a same hunk
Jun Wu <quark@fb.com>
parents: 37730
diff changeset
  2852
                    if stripline.startswith(prefix):
5471348921c1 patch: buffer lines for a same hunk
Jun Wu <quark@fb.com>
parents: 37730
diff changeset
  2853
                        yield (stripline, label)
5471348921c1 patch: buffer lines for a same hunk
Jun Wu <quark@fb.com>
parents: 37730
diff changeset
  2854
                        if line != stripline:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2855
                            yield (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2856
                                line[len(stripline) :],
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2857
                                b'diff.trailingwhitespace',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2858
                            )
35286
6ba79cf34f5e patch: add within-line color diff capacity
Matthieu Laneuville <matthieu.laneuville@octobus.net>
parents: 35202
diff changeset
  2859
                        break
37731
5471348921c1 patch: buffer lines for a same hunk
Jun Wu <quark@fb.com>
parents: 37730
diff changeset
  2860
                else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2861
                    yield (line, b'')
37731
5471348921c1 patch: buffer lines for a same hunk
Jun Wu <quark@fb.com>
parents: 37730
diff changeset
  2862
                if i + 1 < linecount:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2863
                    yield (b'\n', b'')
37731
5471348921c1 patch: buffer lines for a same hunk
Jun Wu <quark@fb.com>
parents: 37730
diff changeset
  2864
        for token in consumehunkbuffer():
5471348921c1 patch: buffer lines for a same hunk
Jun Wu <quark@fb.com>
parents: 37730
diff changeset
  2865
            yield token
35286
6ba79cf34f5e patch: add within-line color diff capacity
Matthieu Laneuville <matthieu.laneuville@octobus.net>
parents: 35202
diff changeset
  2866
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2867
10818
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
  2868
def diffui(*args, **kw):
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
  2869
    '''like diff(), but yields 2-tuples of (output, label) for ui.write()'''
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
  2870
    return difflabel(diff, *args, **kw)
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
  2871
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2872
27900
27572a5cc409 diff: move status fixup earlier, out of _filepairs()
Martin von Zweigbergk <martinvonz@google.com>
parents: 27796
diff changeset
  2873
def _filepairs(modified, added, removed, copy, opts):
24106
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
  2874
    '''generates tuples (f1, f2, copyop), where f1 is the name of the file
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
  2875
    before and f2 is the the name after. For added files, f1 will be None,
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
  2876
    and for removed files, f2 will be None. copyop may be set to None, 'copy'
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
  2877
    or 'rename' (the latter two only if opts.git is set).'''
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
  2878
    gone = set()
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
  2879
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
  2880
    copyto = dict([(v, k) for k, v in copy.items()])
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
  2881
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
  2882
    addedset, removedset = set(added), set(removed)
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
  2883
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
  2884
    for f in sorted(modified + added + removed):
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
  2885
        copyop = None
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
  2886
        f1, f2 = f, f
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
  2887
        if f in addedset:
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
  2888
            f1 = None
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
  2889
            if f in copy:
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
  2890
                if opts.git:
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
  2891
                    f1 = copy[f]
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
  2892
                    if f1 in removedset and f1 not in gone:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2893
                        copyop = b'rename'
24106
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
  2894
                        gone.add(f1)
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
  2895
                    else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2896
                        copyop = b'copy'
24106
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
  2897
        elif f in removedset:
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
  2898
            f2 = None
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
  2899
            if opts.git:
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
  2900
                # have we already reported a copy above?
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2901
                if (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2902
                    f in copyto
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2903
                    and copyto[f] in addedset
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2904
                    and copy[copyto[f]] == f
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2905
                ):
24106
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
  2906
                    continue
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
  2907
        yield f1, f2, copyop
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
  2908
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2909
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2910
def trydiff(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2911
    repo,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2912
    revs,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2913
    ctx1,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2914
    ctx2,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2915
    modified,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2916
    added,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2917
    removed,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2918
    copy,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2919
    getfilectx,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2920
    opts,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2921
    losedatafn,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2922
    pathfn,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2923
):
24371
8a997bd73448 patch.trydiff: add a docstring
Siddharth Agarwal <sid0@fb.com>
parents: 24346
diff changeset
  2924
    '''given input data, generate a diff and yield it in blocks
8a997bd73448 patch.trydiff: add a docstring
Siddharth Agarwal <sid0@fb.com>
parents: 24346
diff changeset
  2925
8a997bd73448 patch.trydiff: add a docstring
Siddharth Agarwal <sid0@fb.com>
parents: 24346
diff changeset
  2926
    If generating a diff would lose data like flags or binary data and
8a997bd73448 patch.trydiff: add a docstring
Siddharth Agarwal <sid0@fb.com>
parents: 24346
diff changeset
  2927
    losedatafn is not None, it will be called.
8a997bd73448 patch.trydiff: add a docstring
Siddharth Agarwal <sid0@fb.com>
parents: 24346
diff changeset
  2928
41657
d4c9eebdd72d patch: replace "prefix" and "relroot" arguments by "pathfn" (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41635
diff changeset
  2929
    pathfn is applied to every path in the diff output.
d4c9eebdd72d patch: replace "prefix" and "relroot" arguments by "pathfn" (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41635
diff changeset
  2930
    '''
12167
d2c5b0927c28 diff: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12144
diff changeset
  2931
17946
1e13b1184292 diff: move index header generation to patch
Guillermo Pérez <bisho@fb.com>
parents: 17945
diff changeset
  2932
    def gitindex(text):
1e13b1184292 diff: move index header generation to patch
Guillermo Pérez <bisho@fb.com>
parents: 17945
diff changeset
  2933
        if not text:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2934
            text = b""
17946
1e13b1184292 diff: move index header generation to patch
Guillermo Pérez <bisho@fb.com>
parents: 17945
diff changeset
  2935
        l = len(text)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2936
        s = hashlib.sha1(b'blob %d\0' % l)
17946
1e13b1184292 diff: move index header generation to patch
Guillermo Pérez <bisho@fb.com>
parents: 17945
diff changeset
  2937
        s.update(text)
35582
72b91f905065 py3: use node.hex(h.digest()) instead of h.hexdigest()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35392
diff changeset
  2938
        return hex(s.digest())
17946
1e13b1184292 diff: move index header generation to patch
Guillermo Pérez <bisho@fb.com>
parents: 17945
diff changeset
  2939
23300
f8b5c3e77d4b patch.trydiff: add support for noprefix
Siddharth Agarwal <sid0@fb.com>
parents: 23297
diff changeset
  2940
    if opts.noprefix:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2941
        aprefix = bprefix = b''
23300
f8b5c3e77d4b patch.trydiff: add support for noprefix
Siddharth Agarwal <sid0@fb.com>
parents: 23297
diff changeset
  2942
    else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2943
        aprefix = b'a/'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2944
        bprefix = b'b/'
23300
f8b5c3e77d4b patch.trydiff: add support for noprefix
Siddharth Agarwal <sid0@fb.com>
parents: 23297
diff changeset
  2945
24021
f51a822dcf3b trydiff: remove unused argument to diffline()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24020
diff changeset
  2946
    def diffline(f, revs):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2947
        revinfo = b' '.join([b"-r %s" % rev for rev in revs])
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2948
        return b'diff %s %s' % (revinfo, f)
17941
9a6e4d5d7ea8 diff: move diffline to patch module
Guillermo Pérez <bisho@fb.com>
parents: 17940
diff changeset
  2949
32234
776127b29a5c diff: use fctx.size() to test empty
Jun Wu <quark@fb.com>
parents: 32233
diff changeset
  2950
    def isempty(fctx):
776127b29a5c diff: use fctx.size() to test empty
Jun Wu <quark@fb.com>
parents: 32233
diff changeset
  2951
        return fctx is None or fctx.size() == 0
776127b29a5c diff: use fctx.size() to test empty
Jun Wu <quark@fb.com>
parents: 32233
diff changeset
  2952
36636
c6061cadb400 util: extract all date-related utils in utils/dateutil module
Boris Feld <boris.feld@octobus.net>
parents: 36477
diff changeset
  2953
    date1 = dateutil.datestr(ctx1.date())
c6061cadb400 util: extract all date-related utils in utils/dateutil module
Boris Feld <boris.feld@octobus.net>
parents: 36477
diff changeset
  2954
    date2 = dateutil.datestr(ctx2.date())
3967
dccb83241dd0 patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3963
diff changeset
  2955
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2956
    gitmode = {b'l': b'120000', b'x': b'100755', b'': b'100644'}
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2868
diff changeset
  2957
41657
d4c9eebdd72d patch: replace "prefix" and "relroot" arguments by "pathfn" (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41635
diff changeset
  2958
    if not pathfn:
d4c9eebdd72d patch: replace "prefix" and "relroot" arguments by "pathfn" (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41635
diff changeset
  2959
        pathfn = lambda f: f
24416
f07047a506d1 patch.trydiff: add support for stripping a relative root
Siddharth Agarwal <sid0@fb.com>
parents: 24390
diff changeset
  2960
27900
27572a5cc409 diff: move status fixup earlier, out of _filepairs()
Martin von Zweigbergk <martinvonz@google.com>
parents: 27796
diff changeset
  2961
    for f1, f2, copyop in _filepairs(modified, added, removed, copy, opts):
24105
0f8baebcdbea trydiff: read file data in only one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 24104
diff changeset
  2962
        content1 = None
0f8baebcdbea trydiff: read file data in only one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 24104
diff changeset
  2963
        content2 = None
32233
e62cf13e0858 diff: use fctx.isbinary() to test binary
Jun Wu <quark@fb.com>
parents: 32068
diff changeset
  2964
        fctx1 = None
e62cf13e0858 diff: use fctx.isbinary() to test binary
Jun Wu <quark@fb.com>
parents: 32068
diff changeset
  2965
        fctx2 = None
24103
c666c85f71ba trydiff: read flags in one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 24102
diff changeset
  2966
        flag1 = None
c666c85f71ba trydiff: read flags in one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 24102
diff changeset
  2967
        flag2 = None
24107
32e8d94b9473 trydiff: transpose 'if opts.git or losedatafn' with 'if f[12]'
Martin von Zweigbergk <martinvonz@google.com>
parents: 24106
diff changeset
  2968
        if f1:
32233
e62cf13e0858 diff: use fctx.isbinary() to test binary
Jun Wu <quark@fb.com>
parents: 32068
diff changeset
  2969
            fctx1 = getfilectx(f1, ctx1)
24107
32e8d94b9473 trydiff: transpose 'if opts.git or losedatafn' with 'if f[12]'
Martin von Zweigbergk <martinvonz@google.com>
parents: 24106
diff changeset
  2970
            if opts.git or losedatafn:
32e8d94b9473 trydiff: transpose 'if opts.git or losedatafn' with 'if f[12]'
Martin von Zweigbergk <martinvonz@google.com>
parents: 24106
diff changeset
  2971
                flag1 = ctx1.flags(f1)
32e8d94b9473 trydiff: transpose 'if opts.git or losedatafn' with 'if f[12]'
Martin von Zweigbergk <martinvonz@google.com>
parents: 24106
diff changeset
  2972
        if f2:
32233
e62cf13e0858 diff: use fctx.isbinary() to test binary
Jun Wu <quark@fb.com>
parents: 32068
diff changeset
  2973
            fctx2 = getfilectx(f2, ctx2)
24107
32e8d94b9473 trydiff: transpose 'if opts.git or losedatafn' with 'if f[12]'
Martin von Zweigbergk <martinvonz@google.com>
parents: 24106
diff changeset
  2974
            if opts.git or losedatafn:
32e8d94b9473 trydiff: transpose 'if opts.git or losedatafn' with 'if f[12]'
Martin von Zweigbergk <martinvonz@google.com>
parents: 24106
diff changeset
  2975
                flag2 = ctx2.flags(f2)
32236
0c67ab3d77d5 diff: correct binary testing logic
Jun Wu <quark@fb.com>
parents: 32235
diff changeset
  2976
        # if binary is True, output "summary" or "base85", but not "text diff"
35890
079b27b5a869 patch: avoid repeated binary checks if all files in a patch are text
Joerg Sonnenberger <joerg@bec.de>
parents: 35633
diff changeset
  2977
        if opts.text:
079b27b5a869 patch: avoid repeated binary checks if all files in a patch are text
Joerg Sonnenberger <joerg@bec.de>
parents: 35633
diff changeset
  2978
            binary = False
079b27b5a869 patch: avoid repeated binary checks if all files in a patch are text
Joerg Sonnenberger <joerg@bec.de>
parents: 35633
diff changeset
  2979
        else:
35990
8b6dd3922f70 patch: unify check_binary and binary flags
Yuya Nishihara <yuya@tcha.org>
parents: 35928
diff changeset
  2980
            binary = any(f.isbinary() for f in [fctx1, fctx2] if f is not None)
24057
696d0fd77d94 trydiff: collect all lossiness checks in one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 24056
diff changeset
  2981
696d0fd77d94 trydiff: collect all lossiness checks in one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 24056
diff changeset
  2982
        if losedatafn and not opts.git:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2983
            if (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2984
                binary
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2985
                or
24057
696d0fd77d94 trydiff: collect all lossiness checks in one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 24056
diff changeset
  2986
                # copy/rename
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2987
                f2 in copy
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2988
                or
24057
696d0fd77d94 trydiff: collect all lossiness checks in one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 24056
diff changeset
  2989
                # empty file creation
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2990
                (not f1 and isempty(fctx2))
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2991
                or
24057
696d0fd77d94 trydiff: collect all lossiness checks in one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 24056
diff changeset
  2992
                # empty file deletion
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2993
                (isempty(fctx1) and not f2)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2994
                or
24057
696d0fd77d94 trydiff: collect all lossiness checks in one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 24056
diff changeset
  2995
                # create with flags
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2996
                (not f1 and flag2)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2997
                or
24057
696d0fd77d94 trydiff: collect all lossiness checks in one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 24056
diff changeset
  2998
                # change flags
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  2999
                (f1 and f2 and flag1 != flag2)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  3000
            ):
24106
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
  3001
                losedatafn(f2 or f1)
10189
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10151
diff changeset
  3002
41657
d4c9eebdd72d patch: replace "prefix" and "relroot" arguments by "pathfn" (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41635
diff changeset
  3003
        path1 = pathfn(f1 or f2)
d4c9eebdd72d patch: replace "prefix" and "relroot" arguments by "pathfn" (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41635
diff changeset
  3004
        path2 = pathfn(f2 or f1)
23998
b65637247c69 trydiff: collect header-writing in one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 23997
diff changeset
  3005
        header = []
24022
da63f557d0dc trydiff: make 'revs' ignored if opts.git is set
Martin von Zweigbergk <martinvonz@google.com>
parents: 24021
diff changeset
  3006
        if opts.git:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  3007
            header.append(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  3008
                b'diff --git %s%s %s%s' % (aprefix, path1, bprefix, path2)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  3009
            )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  3010
            if not f1:  # added
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  3011
                header.append(b'new file mode %s' % gitmode[flag2])
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  3012
            elif not f2:  # removed
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  3013
                header.append(b'deleted file mode %s' % gitmode[flag1])
23998
b65637247c69 trydiff: collect header-writing in one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 23997
diff changeset
  3014
            else:  # modified/copied/renamed
24000
82e3324c4df9 trydiff: inline sole addmodehdr() call
Martin von Zweigbergk <martinvonz@google.com>
parents: 23999
diff changeset
  3015
                mode1, mode2 = gitmode[flag1], gitmode[flag2]
82e3324c4df9 trydiff: inline sole addmodehdr() call
Martin von Zweigbergk <martinvonz@google.com>
parents: 23999
diff changeset
  3016
                if mode1 != mode2:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  3017
                    header.append(b'old mode %s' % mode1)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  3018
                    header.append(b'new mode %s' % mode2)
24055
7f4e6b5fce03 trydiff: rename 'op' to make it more specific
Martin von Zweigbergk <martinvonz@google.com>
parents: 24025
diff changeset
  3019
                if copyop is not None:
30807
6381a6dbc325 patch: use opt.showsimilarity to calculate and show the similarity
Sean Farley <sean@farley.io>
parents: 30806
diff changeset
  3020
                    if opts.showsimilarity:
6381a6dbc325 patch: use opt.showsimilarity to calculate and show the similarity
Sean Farley <sean@farley.io>
parents: 30806
diff changeset
  3021
                        sim = similar.score(ctx1[path1], ctx2[path2]) * 100
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  3022
                        header.append(b'similarity index %d%%' % sim)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  3023
                    header.append(b'%s from %s' % (copyop, path1))
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  3024
                    header.append(b'%s to %s' % (copyop, path2))
41793
251332dbf33d diff: make sure we output stat even when --git is not passed (issue4037) (BC)
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41768
diff changeset
  3025
        elif revs:
24022
da63f557d0dc trydiff: make 'revs' ignored if opts.git is set
Martin von Zweigbergk <martinvonz@google.com>
parents: 24021
diff changeset
  3026
            header.append(diffline(path1, revs))
23998
b65637247c69 trydiff: collect header-writing in one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 23997
diff changeset
  3027
32235
15f10ee778f8 diff: draw a table about binary diff behaviors
Jun Wu <quark@fb.com>
parents: 32234
diff changeset
  3028
        #  fctx.is  | diffopts                | what to   | is fctx.data()
15f10ee778f8 diff: draw a table about binary diff behaviors
Jun Wu <quark@fb.com>
parents: 32234
diff changeset
  3029
        #  binary() | text nobinary git index | output?   | outputted?
15f10ee778f8 diff: draw a table about binary diff behaviors
Jun Wu <quark@fb.com>
parents: 32234
diff changeset
  3030
        # ------------------------------------|----------------------------
15f10ee778f8 diff: draw a table about binary diff behaviors
Jun Wu <quark@fb.com>
parents: 32234
diff changeset
  3031
        #  yes      | no   no       no  *     | summary   | no
15f10ee778f8 diff: draw a table about binary diff behaviors
Jun Wu <quark@fb.com>
parents: 32234
diff changeset
  3032
        #  yes      | no   no       yes *     | base85    | yes
15f10ee778f8 diff: draw a table about binary diff behaviors
Jun Wu <quark@fb.com>
parents: 32234
diff changeset
  3033
        #  yes      | no   yes      no  *     | summary   | no
15f10ee778f8 diff: draw a table about binary diff behaviors
Jun Wu <quark@fb.com>
parents: 32234
diff changeset
  3034
        #  yes      | no   yes      yes 0     | summary   | no
15f10ee778f8 diff: draw a table about binary diff behaviors
Jun Wu <quark@fb.com>
parents: 32234
diff changeset
  3035
        #  yes      | no   yes      yes >0    | summary   | semi [1]
15f10ee778f8 diff: draw a table about binary diff behaviors
Jun Wu <quark@fb.com>
parents: 32234
diff changeset
  3036
        #  yes      | yes  *        *   *     | text diff | yes
15f10ee778f8 diff: draw a table about binary diff behaviors
Jun Wu <quark@fb.com>
parents: 32234
diff changeset
  3037
        #  no       | *    *        *   *     | text diff | yes
15f10ee778f8 diff: draw a table about binary diff behaviors
Jun Wu <quark@fb.com>
parents: 32234
diff changeset
  3038
        # [1]: hash(fctx.data()) is outputted. so fctx.data() cannot be faked
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  3039
        if binary and (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  3040
            not opts.git or (opts.git and opts.nobinary and not opts.index)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  3041
        ):
32237
31f42e683321 diff: add a fast path to avoid loading binary contents
Jun Wu <quark@fb.com>
parents: 32236
diff changeset
  3042
            # fast path: no binary content will be displayed, content1 and
31f42e683321 diff: add a fast path to avoid loading binary contents
Jun Wu <quark@fb.com>
parents: 32236
diff changeset
  3043
            # content2 are only used for equivalent test. cmp() could have a
31f42e683321 diff: add a fast path to avoid loading binary contents
Jun Wu <quark@fb.com>
parents: 32236
diff changeset
  3044
            # fast path.
31f42e683321 diff: add a fast path to avoid loading binary contents
Jun Wu <quark@fb.com>
parents: 32236
diff changeset
  3045
            if fctx1 is not None:
31f42e683321 diff: add a fast path to avoid loading binary contents
Jun Wu <quark@fb.com>
parents: 32236
diff changeset
  3046
                content1 = b'\0'
31f42e683321 diff: add a fast path to avoid loading binary contents
Jun Wu <quark@fb.com>
parents: 32236
diff changeset
  3047
            if fctx2 is not None:
31f42e683321 diff: add a fast path to avoid loading binary contents
Jun Wu <quark@fb.com>
parents: 32236
diff changeset
  3048
                if fctx1 is not None and not fctx1.cmp(fctx2):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  3049
                    content2 = b'\0'  # not different
32237
31f42e683321 diff: add a fast path to avoid loading binary contents
Jun Wu <quark@fb.com>
parents: 32236
diff changeset
  3050
                else:
31f42e683321 diff: add a fast path to avoid loading binary contents
Jun Wu <quark@fb.com>
parents: 32236
diff changeset
  3051
                    content2 = b'\0\0'
31f42e683321 diff: add a fast path to avoid loading binary contents
Jun Wu <quark@fb.com>
parents: 32236
diff changeset
  3052
        else:
31f42e683321 diff: add a fast path to avoid loading binary contents
Jun Wu <quark@fb.com>
parents: 32236
diff changeset
  3053
            # normal path: load contents
31f42e683321 diff: add a fast path to avoid loading binary contents
Jun Wu <quark@fb.com>
parents: 32236
diff changeset
  3054
            if fctx1 is not None:
31f42e683321 diff: add a fast path to avoid loading binary contents
Jun Wu <quark@fb.com>
parents: 32236
diff changeset
  3055
                content1 = fctx1.data()
31f42e683321 diff: add a fast path to avoid loading binary contents
Jun Wu <quark@fb.com>
parents: 32236
diff changeset
  3056
            if fctx2 is not None:
31f42e683321 diff: add a fast path to avoid loading binary contents
Jun Wu <quark@fb.com>
parents: 32236
diff changeset
  3057
                content2 = fctx2.data()
31f42e683321 diff: add a fast path to avoid loading binary contents
Jun Wu <quark@fb.com>
parents: 32236
diff changeset
  3058
32236
0c67ab3d77d5 diff: correct binary testing logic
Jun Wu <quark@fb.com>
parents: 32235
diff changeset
  3059
        if binary and opts.git and not opts.nobinary:
23997
8b88870cbd1e trydiff: make variable names more consistent
Martin von Zweigbergk <martinvonz@google.com>
parents: 23996
diff changeset
  3060
            text = mdiff.b85diff(content1, content2)
24056
ae453d166d51 trydiff: replace 'binarydiff' variable by 'binary' variable
Martin von Zweigbergk <martinvonz@google.com>
parents: 24055
diff changeset
  3061
            if text:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  3062
                header.append(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  3063
                    b'index %s..%s' % (gitindex(content1), gitindex(content2))
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  3064
                )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  3065
            hunks = ((None, [text]),)
23753
e30c6aa6f2a2 trydiff: replace 'dodiff = False' by 'continue'
Martin von Zweigbergk <martinvonz@google.com>
parents: 23752
diff changeset
  3066
        else:
30789
b8ad243f5ded patch: add index line for diff output
Sean Farley <sean@farley.io>
parents: 30788
diff changeset
  3067
            if opts.git and opts.index > 0:
b8ad243f5ded patch: add index line for diff output
Sean Farley <sean@farley.io>
parents: 30788
diff changeset
  3068
                flag = flag1
b8ad243f5ded patch: add index line for diff output
Sean Farley <sean@farley.io>
parents: 30788
diff changeset
  3069
                if flag is None:
b8ad243f5ded patch: add index line for diff output
Sean Farley <sean@farley.io>
parents: 30788
diff changeset
  3070
                    flag = flag2
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  3071
                header.append(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  3072
                    b'index %s..%s %s'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  3073
                    % (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  3074
                        gitindex(content1)[0 : opts.index],
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  3075
                        gitindex(content2)[0 : opts.index],
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  3076
                        gitmode[flag],
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  3077
                    )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  3078
                )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  3079
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  3080
            uheaders, hunks = mdiff.unidiff(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  3081
                content1,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  3082
                date1,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  3083
                content2,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  3084
                date2,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  3085
                path1,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  3086
                path2,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  3087
                binary=binary,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  3088
                opts=opts,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  3089
            )
31281
b3861be6aa6c mdiff: distinguish diff headers from hunks in unidiff()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31243
diff changeset
  3090
            header.extend(uheaders)
34855
35c6a54ec1ff diff: also yield file context objects in patch.trydiff() (API)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 34566
diff changeset
  3091
        yield fctx1, fctx2, header, hunks
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2868
diff changeset
  3092
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  3093
14401
7bb7be1c1385 patch: add diffstatsum helper
Matt Mackall <mpm@selenic.com>
parents: 14400
diff changeset
  3094
def diffstatsum(stats):
14437
cbe13e6bdc34 patch: restore the previous output of 'diff --stat'
Steven Brown <StevenGBrown@gmail.com>
parents: 14435
diff changeset
  3095
    maxfile, maxtotal, addtotal, removetotal, binary = 0, 0, 0, 0, False
14401
7bb7be1c1385 patch: add diffstatsum helper
Matt Mackall <mpm@selenic.com>
parents: 14400
diff changeset
  3096
    for f, a, r, b in stats:
7bb7be1c1385 patch: add diffstatsum helper
Matt Mackall <mpm@selenic.com>
parents: 14400
diff changeset
  3097
        maxfile = max(maxfile, encoding.colwidth(f))
14437
cbe13e6bdc34 patch: restore the previous output of 'diff --stat'
Steven Brown <StevenGBrown@gmail.com>
parents: 14435
diff changeset
  3098
        maxtotal = max(maxtotal, a + r)
14401
7bb7be1c1385 patch: add diffstatsum helper
Matt Mackall <mpm@selenic.com>
parents: 14400
diff changeset
  3099
        addtotal += a
7bb7be1c1385 patch: add diffstatsum helper
Matt Mackall <mpm@selenic.com>
parents: 14400
diff changeset
  3100
        removetotal += r
7bb7be1c1385 patch: add diffstatsum helper
Matt Mackall <mpm@selenic.com>
parents: 14400
diff changeset
  3101
        binary = binary or b
7bb7be1c1385 patch: add diffstatsum helper
Matt Mackall <mpm@selenic.com>
parents: 14400
diff changeset
  3102
14437
cbe13e6bdc34 patch: restore the previous output of 'diff --stat'
Steven Brown <StevenGBrown@gmail.com>
parents: 14435
diff changeset
  3103
    return maxfile, maxtotal, addtotal, removetotal, binary
14401
7bb7be1c1385 patch: add diffstatsum helper
Matt Mackall <mpm@selenic.com>
parents: 14400
diff changeset
  3104
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  3105
7547
4949729ee9ee python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7521
diff changeset
  3106
def diffstatdata(lines):
41546
bd3f03d8cc9f global: use raw strings for regular expressions with escapes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41513
diff changeset
  3107
    diffre = re.compile(br'^diff .*-r [a-z0-9]+\s(.*)$')
13395
104c9ed93fc5 diffstat: fix parsing of filenames with spaces
Gastón Kleiman <gaston.kleiman@gmail.com>
parents: 13112
diff changeset
  3108
14400
cd1ca2556cac diffstatdata: no longer a generator
Matt Mackall <mpm@selenic.com>
parents: 14392
diff changeset
  3109
    results = []
15363
628a4a9e411d diffstat: be more picky when marking file as 'binary' (issue2816)
Patrick Mezard <pmezard@gmail.com>
parents: 15201
diff changeset
  3110
    filename, adds, removes, isbinary = None, 0, 0, False
14400
cd1ca2556cac diffstatdata: no longer a generator
Matt Mackall <mpm@selenic.com>
parents: 14392
diff changeset
  3111
cd1ca2556cac diffstatdata: no longer a generator
Matt Mackall <mpm@selenic.com>
parents: 14392
diff changeset
  3112
    def addresult():
cd1ca2556cac diffstatdata: no longer a generator
Matt Mackall <mpm@selenic.com>
parents: 14392
diff changeset
  3113
        if filename:
cd1ca2556cac diffstatdata: no longer a generator
Matt Mackall <mpm@selenic.com>
parents: 14392
diff changeset
  3114
            results.append((filename, adds, removes, isbinary))
cd1ca2556cac diffstatdata: no longer a generator
Matt Mackall <mpm@selenic.com>
parents: 14392
diff changeset
  3115
32360
0e29ce16ec38 diffstat: properly count lines starting in '--' or '++' (issue5479)
Andrew Zwicky <andrew.zwicky@gmail.com>
parents: 32245
diff changeset
  3116
    # inheader is used to track if a line is in the
0e29ce16ec38 diffstat: properly count lines starting in '--' or '++' (issue5479)
Andrew Zwicky <andrew.zwicky@gmail.com>
parents: 32245
diff changeset
  3117
    # header portion of the diff.  This helps properly account
0e29ce16ec38 diffstat: properly count lines starting in '--' or '++' (issue5479)
Andrew Zwicky <andrew.zwicky@gmail.com>
parents: 32245
diff changeset
  3118
    # for lines that start with '--' or '++'
0e29ce16ec38 diffstat: properly count lines starting in '--' or '++' (issue5479)
Andrew Zwicky <andrew.zwicky@gmail.com>
parents: 32245
diff changeset
  3119
    inheader = False
0e29ce16ec38 diffstat: properly count lines starting in '--' or '++' (issue5479)
Andrew Zwicky <andrew.zwicky@gmail.com>
parents: 32245
diff changeset
  3120
7547
4949729ee9ee python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7521
diff changeset
  3121
    for line in lines:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  3122
        if line.startswith(b'diff'):
14400
cd1ca2556cac diffstatdata: no longer a generator
Matt Mackall <mpm@selenic.com>
parents: 14392
diff changeset
  3123
            addresult()
32360
0e29ce16ec38 diffstat: properly count lines starting in '--' or '++' (issue5479)
Andrew Zwicky <andrew.zwicky@gmail.com>
parents: 32245
diff changeset
  3124
            # starting a new file diff
0e29ce16ec38 diffstat: properly count lines starting in '--' or '++' (issue5479)
Andrew Zwicky <andrew.zwicky@gmail.com>
parents: 32245
diff changeset
  3125
            # set numbers to 0 and reset inheader
0e29ce16ec38 diffstat: properly count lines starting in '--' or '++' (issue5479)
Andrew Zwicky <andrew.zwicky@gmail.com>
parents: 32245
diff changeset
  3126
            inheader = True
15363
628a4a9e411d diffstat: be more picky when marking file as 'binary' (issue2816)
Patrick Mezard <pmezard@gmail.com>
parents: 15201
diff changeset
  3127
            adds, removes, isbinary = 0, 0, False
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  3128
            if line.startswith(b'diff --git a/'):
20972
4e2fb0ad00a9 diff: use second filename for --stat reporting on git patches (issue4221)
Matt Mackall <mpm@selenic.com>
parents: 20869
diff changeset
  3129
                filename = gitre.search(line).group(2)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  3130
            elif line.startswith(b'diff -r'):
8761
0289f384e1e5 Generally replace "file name" with "filename" in help and comments.
timeless <timeless@gmail.com>
parents: 8632
diff changeset
  3131
                # format: "diff -r ... -r ... filename"
13395
104c9ed93fc5 diffstat: fix parsing of filenames with spaces
Gastón Kleiman <gaston.kleiman@gmail.com>
parents: 13112
diff changeset
  3132
                filename = diffre.search(line).group(1)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  3133
        elif line.startswith(b'@@'):
32360
0e29ce16ec38 diffstat: properly count lines starting in '--' or '++' (issue5479)
Andrew Zwicky <andrew.zwicky@gmail.com>
parents: 32245
diff changeset
  3134
            inheader = False
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  3135
        elif line.startswith(b'+') and not inheader:
7547
4949729ee9ee python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7521
diff changeset
  3136
            adds += 1
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  3137
        elif line.startswith(b'-') and not inheader:
7547
4949729ee9ee python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7521
diff changeset
  3138
            removes += 1
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  3139
        elif line.startswith(b'GIT binary patch') or line.startswith(
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  3140
            b'Binary file'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  3141
        ):
15363
628a4a9e411d diffstat: be more picky when marking file as 'binary' (issue2816)
Patrick Mezard <pmezard@gmail.com>
parents: 15201
diff changeset
  3142
            isbinary = True
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  3143
        elif line.startswith(b'rename from'):
41423
4a33a6bf2b52 diffstat: support filenames with whitespaces on renames
Navaneeth Suresh <navaneeths1998@gmail.com>
parents: 41397
diff changeset
  3144
            filename = line[12:]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  3145
        elif line.startswith(b'rename to'):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  3146
            filename += b' => %s' % line[10:]
14400
cd1ca2556cac diffstatdata: no longer a generator
Matt Mackall <mpm@selenic.com>
parents: 14392
diff changeset
  3147
    addresult()
cd1ca2556cac diffstatdata: no longer a generator
Matt Mackall <mpm@selenic.com>
parents: 14392
diff changeset
  3148
    return results
7547
4949729ee9ee python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7521
diff changeset
  3149
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  3150
30417
e1677cc29da6 patch: remove unused git parameter from patch.diffstat()
Henning Schild <henning@hennsch.de>
parents: 30407
diff changeset
  3151
def diffstat(lines, width=80):
7547
4949729ee9ee python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7521
diff changeset
  3152
    output = []
14402
f03f08240c32 patch: use diffstatsum in diffstat
Matt Mackall <mpm@selenic.com>
parents: 14401
diff changeset
  3153
    stats = diffstatdata(lines)
14437
cbe13e6bdc34 patch: restore the previous output of 'diff --stat'
Steven Brown <StevenGBrown@gmail.com>
parents: 14435
diff changeset
  3154
    maxname, maxtotal, totaladds, totalremoves, hasbinary = diffstatsum(stats)
7547
4949729ee9ee python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7521
diff changeset
  3155
4949729ee9ee python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7521
diff changeset
  3156
    countwidth = len(str(maxtotal))
9642
7d17794f08a9 diffstat: with --git, mark binary files with Bin
Brodie Rao <me+hg@dackz.net>
parents: 9639
diff changeset
  3157
    if hasbinary and countwidth < 3:
7d17794f08a9 diffstat: with --git, mark binary files with Bin
Brodie Rao <me+hg@dackz.net>
parents: 9639
diff changeset
  3158
        countwidth = 3
9330
be2a13153372 diffstat: scale adds/removes proportionally to graph width
Brodie Rao <me+hg@dackz.net>
parents: 9328
diff changeset
  3159
    graphwidth = width - countwidth - maxname - 6
7547
4949729ee9ee python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7521
diff changeset
  3160
    if graphwidth < 10:
4949729ee9ee python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7521
diff changeset
  3161
        graphwidth = 10
4949729ee9ee python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7521
diff changeset
  3162
9330
be2a13153372 diffstat: scale adds/removes proportionally to graph width
Brodie Rao <me+hg@dackz.net>
parents: 9328
diff changeset
  3163
    def scale(i):
be2a13153372 diffstat: scale adds/removes proportionally to graph width
Brodie Rao <me+hg@dackz.net>
parents: 9328
diff changeset
  3164
        if maxtotal <= graphwidth:
be2a13153372 diffstat: scale adds/removes proportionally to graph width
Brodie Rao <me+hg@dackz.net>
parents: 9328
diff changeset
  3165
            return i
be2a13153372 diffstat: scale adds/removes proportionally to graph width
Brodie Rao <me+hg@dackz.net>
parents: 9328
diff changeset
  3166
        # If diffstat runs out of room it doesn't print anything,
be2a13153372 diffstat: scale adds/removes proportionally to graph width
Brodie Rao <me+hg@dackz.net>
parents: 9328
diff changeset
  3167
        # which isn't very useful, so always print at least one + or -
be2a13153372 diffstat: scale adds/removes proportionally to graph width
Brodie Rao <me+hg@dackz.net>
parents: 9328
diff changeset
  3168
        # if there were at least some changes.
be2a13153372 diffstat: scale adds/removes proportionally to graph width
Brodie Rao <me+hg@dackz.net>
parents: 9328
diff changeset
  3169
        return max(i * graphwidth // maxtotal, int(bool(i)))
7547
4949729ee9ee python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7521
diff changeset
  3170
14402
f03f08240c32 patch: use diffstatsum in diffstat
Matt Mackall <mpm@selenic.com>
parents: 14401
diff changeset
  3171
    for filename, adds, removes, isbinary in stats:
15363
628a4a9e411d diffstat: be more picky when marking file as 'binary' (issue2816)
Patrick Mezard <pmezard@gmail.com>
parents: 15201
diff changeset
  3172
        if isbinary:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  3173
            count = b'Bin'
9642
7d17794f08a9 diffstat: with --git, mark binary files with Bin
Brodie Rao <me+hg@dackz.net>
parents: 9639
diff changeset
  3174
        else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  3175
            count = b'%d' % (adds + removes)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  3176
        pluses = b'+' * scale(adds)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  3177
        minuses = b'-' * scale(removes)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  3178
        output.append(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  3179
            b' %s%s |  %*s %s%s\n'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  3180
            % (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  3181
                filename,
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  3182
                b' ' * (maxname - encoding.colwidth(filename)),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  3183
                countwidth,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  3184
                count,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  3185
                pluses,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  3186
                minuses,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  3187
            )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  3188
        )
7547
4949729ee9ee python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7521
diff changeset
  3189
4949729ee9ee python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7521
diff changeset
  3190
    if stats:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  3191
        output.append(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  3192
            _(b' %d files changed, %d insertions(+), ' b'%d deletions(-)\n')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  3193
            % (len(stats), totaladds, totalremoves)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  3194
        )
7547
4949729ee9ee python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7521
diff changeset
  3195
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  3196
    return b''.join(output)
10818
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
  3197
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43066
diff changeset
  3198
10818
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
  3199
def diffstatui(*args, **kw):
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
  3200
    '''like diffstat(), but yields 2-tuples of (output, label) for
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
  3201
    ui.write()
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
  3202
    '''
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
  3203
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
  3204
    for line in diffstat(*args, **kw).splitlines():
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  3205
        if line and line[-1] in b'+-':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  3206
            name, graph = line.rsplit(b' ', 1)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  3207
            yield (name + b' ', b'')
33108
d9962854a4a2 py3: add b'' to make the regex pattern bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33006
diff changeset
  3208
            m = re.search(br'\++', graph)
10818
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
  3209
            if m:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  3210
                yield (m.group(0), b'diffstat.inserted')
33108
d9962854a4a2 py3: add b'' to make the regex pattern bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33006
diff changeset
  3211
            m = re.search(br'-+', graph)
10818
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
  3212
            if m:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  3213
                yield (m.group(0), b'diffstat.deleted')
10818
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
  3214
        else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  3215
            yield (line, b'')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  3216
        yield (b'\n', b'')