annotate mercurial/diffhelper.py @ 39762:f7228c907ef4

changegroup: factor changelog chunk generation into own function We have separate functions for generating manifests and filelogs. Let's split changelog into its own function so things are consistent. As part of this, we refactor the code slightly. Before, the changelog linknode callback was updating state on variables inherited via a closure. Since the closure is now separate from generate(), we need to a way pass state between generate() and _generatechangelog(). The return value of _generatechangelog() is a 2-tuple where the first item is a dict containing accumulated state. We then alias some of its members into the scope of generate() to reduce code churn. I will be converting other functions to a similar pattern in future commits. Differential Revision: https://phab.mercurial-scm.org/D4133
author Gregory Szorc <gregory.szorc@gmail.com>
date Fri, 03 Aug 2018 17:59:56 -0700 (2018-08-04)
parents e7aa113b14f7
children 57875cf423c9
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
38589
72f6498c040b diffhelper: rename module to avoid conflicts with ancient C module (issue5846)
Yuya Nishihara <yuya@tcha.org>
parents: 38588
diff changeset
1 # diffhelper.py - helper routines for patch
7702
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
2 #
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
3 # Copyright 2009 Matt Mackall <mpm@selenic.com> and others
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
4 #
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 7702
diff changeset
5 # 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: 8225
diff changeset
6 # GNU General Public License version 2 or any later version.
7702
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
7
27983
80214358ac88 diffhelpers: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 12387
diff changeset
8 from __future__ import absolute_import
80214358ac88 diffhelpers: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 12387
diff changeset
9
38359
49b82cdb5983 patch: error out if reached to EOF while reading hunk
Yuya Nishihara <yuya@tcha.org>
parents: 38358
diff changeset
10 from .i18n import _
49b82cdb5983 patch: error out if reached to EOF while reading hunk
Yuya Nishihara <yuya@tcha.org>
parents: 38358
diff changeset
11
49b82cdb5983 patch: error out if reached to EOF while reading hunk
Yuya Nishihara <yuya@tcha.org>
parents: 38358
diff changeset
12 from . import (
49b82cdb5983 patch: error out if reached to EOF while reading hunk
Yuya Nishihara <yuya@tcha.org>
parents: 38358
diff changeset
13 error,
39569
e7aa113b14f7 global: use pycompat.xrange()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38622
diff changeset
14 pycompat,
38359
49b82cdb5983 patch: error out if reached to EOF while reading hunk
Yuya Nishihara <yuya@tcha.org>
parents: 38358
diff changeset
15 )
49b82cdb5983 patch: error out if reached to EOF while reading hunk
Yuya Nishihara <yuya@tcha.org>
parents: 38358
diff changeset
16
7702
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
17 def addlines(fp, hunk, lena, lenb, a, b):
38353
53021c4ef0b2 diffhelpers: port docstrings from cext to pure
Yuya Nishihara <yuya@tcha.org>
parents: 38352
diff changeset
18 """Read lines from fp into the hunk
53021c4ef0b2 diffhelpers: port docstrings from cext to pure
Yuya Nishihara <yuya@tcha.org>
parents: 38352
diff changeset
19
53021c4ef0b2 diffhelpers: port docstrings from cext to pure
Yuya Nishihara <yuya@tcha.org>
parents: 38352
diff changeset
20 The hunk is parsed into two arrays, a and b. a gets the old state of
53021c4ef0b2 diffhelpers: port docstrings from cext to pure
Yuya Nishihara <yuya@tcha.org>
parents: 38352
diff changeset
21 the text, b gets the new state. The control char from the hunk is saved
53021c4ef0b2 diffhelpers: port docstrings from cext to pure
Yuya Nishihara <yuya@tcha.org>
parents: 38352
diff changeset
22 when inserting into a, but not b (for performance while deleting files.)
53021c4ef0b2 diffhelpers: port docstrings from cext to pure
Yuya Nishihara <yuya@tcha.org>
parents: 38352
diff changeset
23 """
7702
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
24 while True:
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
25 todoa = lena - len(a)
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
26 todob = lenb - len(b)
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
27 num = max(todoa, todob)
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
28 if num == 0:
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
29 break
39569
e7aa113b14f7 global: use pycompat.xrange()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38622
diff changeset
30 for i in pycompat.xrange(num):
7702
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
31 s = fp.readline()
38359
49b82cdb5983 patch: error out if reached to EOF while reading hunk
Yuya Nishihara <yuya@tcha.org>
parents: 38358
diff changeset
32 if not s:
49b82cdb5983 patch: error out if reached to EOF while reading hunk
Yuya Nishihara <yuya@tcha.org>
parents: 38358
diff changeset
33 raise error.ParseError(_('incomplete hunk'))
7702
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
34 if s == "\\ No newline at end of file\n":
38356
c4c8d0d1267f diffhelpers: naming and whitespace cleanup
Yuya Nishihara <yuya@tcha.org>
parents: 38353
diff changeset
35 fixnewline(hunk, a, b)
7702
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
36 continue
38361
230eb9594150 diffhelpers: be more tolerant for stripped empty lines of CRLF ending
Yuya Nishihara <yuya@tcha.org>
parents: 38360
diff changeset
37 if s == '\n' or s == '\r\n':
7702
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
38 # Some patches may be missing the control char
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
39 # on empty lines. Supply a leading space.
38361
230eb9594150 diffhelpers: be more tolerant for stripped empty lines of CRLF ending
Yuya Nishihara <yuya@tcha.org>
parents: 38360
diff changeset
40 s = ' ' + s
7702
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
41 hunk.append(s)
38352
f53b55b162f4 py3: get rid of character access from pure.diffhelpers
Yuya Nishihara <yuya@tcha.org>
parents: 27983
diff changeset
42 if s.startswith('+'):
7702
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
43 b.append(s[1:])
38352
f53b55b162f4 py3: get rid of character access from pure.diffhelpers
Yuya Nishihara <yuya@tcha.org>
parents: 27983
diff changeset
44 elif s.startswith('-'):
7702
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
45 a.append(s)
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
46 else:
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
47 b.append(s[1:])
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
48 a.append(s)
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
49
38356
c4c8d0d1267f diffhelpers: naming and whitespace cleanup
Yuya Nishihara <yuya@tcha.org>
parents: 38353
diff changeset
50 def fixnewline(hunk, a, b):
38353
53021c4ef0b2 diffhelpers: port docstrings from cext to pure
Yuya Nishihara <yuya@tcha.org>
parents: 38352
diff changeset
51 """Fix up the last lines of a and b when the patch has no newline at EOF"""
7702
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
52 l = hunk[-1]
10551
f61dced1367a fix test-mq-eol under --pure (mimic diffhelper.c behaviour)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10263
diff changeset
53 # tolerate CRLF in last line
f61dced1367a fix test-mq-eol under --pure (mimic diffhelper.c behaviour)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10263
diff changeset
54 if l.endswith('\r\n'):
f61dced1367a fix test-mq-eol under --pure (mimic diffhelper.c behaviour)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10263
diff changeset
55 hline = l[:-2]
f61dced1367a fix test-mq-eol under --pure (mimic diffhelper.c behaviour)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10263
diff changeset
56 else:
f61dced1367a fix test-mq-eol under --pure (mimic diffhelper.c behaviour)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10263
diff changeset
57 hline = l[:-1]
7702
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
58
38352
f53b55b162f4 py3: get rid of character access from pure.diffhelpers
Yuya Nishihara <yuya@tcha.org>
parents: 27983
diff changeset
59 if hline.startswith((' ', '+')):
10551
f61dced1367a fix test-mq-eol under --pure (mimic diffhelper.c behaviour)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10263
diff changeset
60 b[-1] = hline[1:]
38352
f53b55b162f4 py3: get rid of character access from pure.diffhelpers
Yuya Nishihara <yuya@tcha.org>
parents: 27983
diff changeset
61 if hline.startswith((' ', '-')):
7702
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
62 a[-1] = hline
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
63 hunk[-1] = hline
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
64
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
65 def testhunk(a, b, bstart):
38353
53021c4ef0b2 diffhelpers: port docstrings from cext to pure
Yuya Nishihara <yuya@tcha.org>
parents: 38352
diff changeset
66 """Compare the lines in a with the lines in b
53021c4ef0b2 diffhelpers: port docstrings from cext to pure
Yuya Nishihara <yuya@tcha.org>
parents: 38352
diff changeset
67
53021c4ef0b2 diffhelpers: port docstrings from cext to pure
Yuya Nishihara <yuya@tcha.org>
parents: 38352
diff changeset
68 a is assumed to have a control char at the start of each line, this char
53021c4ef0b2 diffhelpers: port docstrings from cext to pure
Yuya Nishihara <yuya@tcha.org>
parents: 38352
diff changeset
69 is ignored in the compare.
53021c4ef0b2 diffhelpers: port docstrings from cext to pure
Yuya Nishihara <yuya@tcha.org>
parents: 38352
diff changeset
70 """
7702
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
71 alen = len(a)
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
72 blen = len(b)
38588
090c89a8db32 diffhelpers: backport 9e40bc4c1bde from C implementation
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
73 if alen > blen - bstart or bstart < 0:
38360
a1bcc7ff0eac diffhelpers: make return value of testhunk() more Pythonic
Yuya Nishihara <yuya@tcha.org>
parents: 38359
diff changeset
74 return False
39569
e7aa113b14f7 global: use pycompat.xrange()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38622
diff changeset
75 for i in pycompat.xrange(alen):
7702
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
76 if a[i][1:] != b[i + bstart]:
38360
a1bcc7ff0eac diffhelpers: make return value of testhunk() more Pythonic
Yuya Nishihara <yuya@tcha.org>
parents: 38359
diff changeset
77 return False
a1bcc7ff0eac diffhelpers: make return value of testhunk() more Pythonic
Yuya Nishihara <yuya@tcha.org>
parents: 38359
diff changeset
78 return True