Mercurial > hg
annotate mercurial/patch.py @ 18122:730b769fb634 stable
bookmarks: fix head selection for merge with two bookmarked heads
A type mismatch caused the search for the other head to fail. The code is
fragile, and instead it ended up using the 'first' bookmark head, but the
ordering is undefined and it could thus randomly use the wrong bookmarkhead
and fail with:
$ hg up -q -C e@diverged
$ hg merge
abort: merging with a working directory ancestor has no effect
author | Mads Kiilerich <mads@kiilerich.com> |
---|---|
date | Mon, 24 Dec 2012 13:26:13 +0100 |
parents | e51d4aedace9 |
children | d587925680d9 |
rev | line source |
---|---|
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 | 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 |
13112
039a964dbbb3
opener: always reset flags on 'w'rite
Adrian Buehlmann <adrian@cadifra.com>
parents:
13104
diff
changeset
|
9 import cStringIO, email.Parser, os, errno, re |
14452
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
10 import tempfile, zlib, shutil |
10965
7faef79a89c7
patch: move mercurial-specific imports after stdlib imports
Augie Fackler <durin42@gmail.com>
parents:
10905
diff
changeset
|
11 |
3891 | 12 from i18n import _ |
6211
f89fd07fc51d
Expand import * to allow Pyflakes to find problems
Joel Rosdahl <joel@rosdahl.net>
parents:
6179
diff
changeset
|
13 from node import hex, nullid, short |
14611
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
14 import base85, mdiff, scmutil, util, diffhelpers, copies, encoding, error |
16834
cafd8a8fb713
util: subclass deque for Python 2.4 backwards compatibility
Bryan O'Sullivan <bryano@fb.com>
parents:
16828
diff
changeset
|
15 import context |
2866
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
16 |
7199
dd891d0d97a3
patch: consolidate two different regexes for parsing of git diffs
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
7198
diff
changeset
|
17 gitre = re.compile('diff --git a/(.*) b/(.*)') |
dd891d0d97a3
patch: consolidate two different regexes for parsing of git diffs
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
7198
diff
changeset
|
18 |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
19 class PatchError(Exception): |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
20 pass |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
21 |
2933
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
22 |
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
23 # public functions |
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
24 |
10384
832f35386067
import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents:
10282
diff
changeset
|
25 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
|
26 '''return an iterator of individual patches from a stream''' |
832f35386067
import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents:
10282
diff
changeset
|
27 def 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
|
28 if inheader and line[0] in (' ', '\t'): |
832f35386067
import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents:
10282
diff
changeset
|
29 # continuation |
832f35386067
import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents:
10282
diff
changeset
|
30 return True |
10883
196908117c27
patch: don't look for headers in diff lines
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
10748
diff
changeset
|
31 if line[0] in (' ', '-', '+'): |
196908117c27
patch: don't look for headers in diff lines
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
10748
diff
changeset
|
32 # 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
|
33 return False |
10384
832f35386067
import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents:
10282
diff
changeset
|
34 l = line.split(': ', 1) |
832f35386067
import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents:
10282
diff
changeset
|
35 return len(l) == 2 and ' ' not in l[0] |
832f35386067
import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents:
10282
diff
changeset
|
36 |
832f35386067
import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents:
10282
diff
changeset
|
37 def chunk(lines): |
832f35386067
import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents:
10282
diff
changeset
|
38 return cStringIO.StringIO(''.join(lines)) |
832f35386067
import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents:
10282
diff
changeset
|
39 |
832f35386067
import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents:
10282
diff
changeset
|
40 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
|
41 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
|
42 |
832f35386067
import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents:
10282
diff
changeset
|
43 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
|
44 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
|
45 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
|
46 if not inheader and line.startswith('# HG changeset patch'): |
832f35386067
import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents:
10282
diff
changeset
|
47 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
|
48 cur = [] |
832f35386067
import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents:
10282
diff
changeset
|
49 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
|
50 |
832f35386067
import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents:
10282
diff
changeset
|
51 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
|
52 |
832f35386067
import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents:
10282
diff
changeset
|
53 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
|
54 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
|
55 |
832f35386067
import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents:
10282
diff
changeset
|
56 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
|
57 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
|
58 if line.startswith('From '): |
832f35386067
import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents:
10282
diff
changeset
|
59 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
|
60 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
|
61 cur = [] |
832f35386067
import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents:
10282
diff
changeset
|
62 |
832f35386067
import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents:
10282
diff
changeset
|
63 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
|
64 |
832f35386067
import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents:
10282
diff
changeset
|
65 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
|
66 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
|
67 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
|
68 |
832f35386067
import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents:
10282
diff
changeset
|
69 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
|
70 def 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
|
71 fp = cStringIO.StringIO() |
832f35386067
import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents:
10282
diff
changeset
|
72 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
|
73 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
|
74 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
|
75 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
|
76 |
832f35386067
import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents:
10282
diff
changeset
|
77 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
|
78 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
|
79 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
|
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 m = email.Parser.Parser().parse(c) |
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 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
|
83 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
|
84 else: |
832f35386067
import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents:
10282
diff
changeset
|
85 ok_types = ('text/plain', 'text/x-diff', 'text/x-patch') |
832f35386067
import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents:
10282
diff
changeset
|
86 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
|
87 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
|
88 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
|
89 continue |
832f35386067
import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents:
10282
diff
changeset
|
90 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
|
91 |
832f35386067
import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents:
10282
diff
changeset
|
92 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
|
93 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
|
94 |
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: |
832f35386067
import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents:
10282
diff
changeset
|
96 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
|
97 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
|
98 cur = [] |
832f35386067
import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents:
10282
diff
changeset
|
99 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
|
100 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
|
101 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
|
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 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
|
104 |
832f35386067
import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents:
10282
diff
changeset
|
105 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
|
106 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
|
107 |
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 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
|
109 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
|
110 |
832f35386067
import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents:
10282
diff
changeset
|
111 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
|
112 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
|
113 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
|
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 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
|
116 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
|
117 |
832f35386067
import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents:
10282
diff
changeset
|
118 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
|
119 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
|
120 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
|
121 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
|
122 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
|
123 |
832f35386067
import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents:
10282
diff
changeset
|
124 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
|
125 cur = [] |
832f35386067
import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents:
10282
diff
changeset
|
126 |
832f35386067
import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents:
10282
diff
changeset
|
127 mimeheaders = ['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
|
128 |
14966
0588fb0e2e8d
patch: use safehasattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents:
14832
diff
changeset
|
129 if not util.safehasattr(stream, '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
|
130 # 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
|
131 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
|
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 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
|
135 if line.startswith('# HG changeset patch'): |
832f35386067
import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents:
10282
diff
changeset
|
136 return 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
|
137 elif line.startswith('From '): |
832f35386067
import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents:
10282
diff
changeset
|
138 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
|
139 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
|
140 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
|
141 if line.split(':', 1)[0].lower() in mimeheaders: |
832f35386067
import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents:
10282
diff
changeset
|
142 # 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
|
143 return mimesplit(stream, cur) |
10501
a27af7229850
import: if in doubt, consume stream until start of diff
Brendan Cully <brendan@kublai.com>
parents:
10467
diff
changeset
|
144 elif line.startswith('--- ') and inheader: |
a27af7229850
import: if in doubt, consume stream until start of diff
Brendan Cully <brendan@kublai.com>
parents:
10467
diff
changeset
|
145 # 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
|
146 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
|
147 # 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
|
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 # 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
|
150 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
|
151 |
2866
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
152 def extract(ui, fileobj): |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
153 '''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
|
154 |
4263 | 155 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
|
156 |
11645
88b89ace643b
patch: fix extract() docstring, it returns branch as well
Dan Drake <drake@kaist.edu>
parents:
11611
diff
changeset
|
157 return tuple (filename, message, user, date, branch, node, p1, p2). |
4263 | 158 Any item in the returned tuple can be None. If filename is None, |
159 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
|
160 |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
161 # 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
|
162 # (this heuristic is borrowed from quilt) |
7736
fb0776fe3e38
patch: turned strings with backslashes into raw strings
Martin Geisler <mg@daimi.au.dk>
parents:
7670
diff
changeset
|
163 diffre = re.compile(r'^(?:Index:[ \t]|diff[ \t]|RCS file: |' |
fb0776fe3e38
patch: turned strings with backslashes into raw strings
Martin Geisler <mg@daimi.au.dk>
parents:
7670
diff
changeset
|
164 r'retrieving revision [0-9]+(\.[0-9]+)*$|' |
10736
a528a1046dba
patch: second line of a context diff starts with '--- ', not '+++ '
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10729
diff
changeset
|
165 r'---[ \t].*?^\+\+\+[ \t]|' |
a528a1046dba
patch: second line of a context diff starts with '--- ', not '+++ '
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10729
diff
changeset
|
166 r'\*\*\*[ \t].*?^---[ \t])', re.MULTILINE|re.DOTALL) |
2866
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
167 |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
168 fd, tmpname = tempfile.mkstemp(prefix='hg-patch-') |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
169 tmpfp = os.fdopen(fd, 'w') |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
170 try: |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
171 msg = email.Parser.Parser().parse(fileobj) |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
172 |
4777
5ee5cbfceff3
patch.extract: do not prepend subject if the description already starts with it
Brendan Cully <brendan@kublai.com>
parents:
4659
diff
changeset
|
173 subject = msg['Subject'] |
2866
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
174 user = msg['From'] |
9573
b8352a3617f3
patch: do not swallow header-like patch first line (issue1859)
Patrick Mezard <pmezard@gmail.com>
parents:
9243
diff
changeset
|
175 if not subject and not user: |
b8352a3617f3
patch: do not swallow header-like patch first line (issue1859)
Patrick Mezard <pmezard@gmail.com>
parents:
9243
diff
changeset
|
176 # Not an email, restore parsed headers if any |
b8352a3617f3
patch: do not swallow header-like patch first line (issue1859)
Patrick Mezard <pmezard@gmail.com>
parents:
9243
diff
changeset
|
177 subject = '\n'.join(': '.join(h) for h in msg.items()) + '\n' |
b8352a3617f3
patch: do not swallow header-like patch first line (issue1859)
Patrick Mezard <pmezard@gmail.com>
parents:
9243
diff
changeset
|
178 |
5418
9b469bdb1ce1
patch: fix git sendmail handling without proper mail headers
Patrick Mezard <pmezard@gmail.com>
parents:
5403
diff
changeset
|
179 gitsendmail = 'git-send-email' in msg.get('X-Mailer', '') |
2866
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
180 # should try to parse msg['Date'] |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
181 date = None |
4263 | 182 nodeid = None |
4443
eff2eefdb65a
Add ability to parse branch information to hg import
Eric Hopper <hopper@omnifarious.org>
parents:
4436
diff
changeset
|
183 branch = None |
4263 | 184 parents = [] |
2866
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
185 |
4777
5ee5cbfceff3
patch.extract: do not prepend subject if the description already starts with it
Brendan Cully <brendan@kublai.com>
parents:
4659
diff
changeset
|
186 if subject: |
5ee5cbfceff3
patch.extract: do not prepend subject if the description already starts with it
Brendan Cully <brendan@kublai.com>
parents:
4659
diff
changeset
|
187 if subject.startswith('[PATCH'): |
5ee5cbfceff3
patch.extract: do not prepend subject if the description already starts with it
Brendan Cully <brendan@kublai.com>
parents:
4659
diff
changeset
|
188 pend = subject.find(']') |
4208
bd9b84b9a84b
Make [PATCH] removal slightly more robust
Brendan Cully <brendan@kublai.com>
parents:
4201
diff
changeset
|
189 if pend >= 0: |
10282
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
190 subject = subject[pend + 1:].lstrip() |
15158
7ce7177e029a
patch: correctly handle non-tabular Subject: line
Steffen Daode Nurpmeso <sdaoden@googlemail.com>
parents:
15086
diff
changeset
|
191 subject = re.sub(r'\n[ \t]+', ' ', subject) |
4777
5ee5cbfceff3
patch.extract: do not prepend subject if the description already starts with it
Brendan Cully <brendan@kublai.com>
parents:
4659
diff
changeset
|
192 ui.debug('Subject: %s\n' % subject) |
2866
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
193 if user: |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
194 ui.debug('From: %s\n' % user) |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
195 diffs_seen = 0 |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
196 ok_types = ('text/plain', 'text/x-diff', 'text/x-patch') |
4900
e56c7e05c7e6
patch.py: re-add the ability to use an external patch program
Bryan O'Sullivan <bos@serpentine.com>
parents:
4899
diff
changeset
|
197 message = '' |
2866
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
198 for part in msg.walk(): |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
199 content_type = part.get_content_type() |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
200 ui.debug('Content-Type: %s\n' % content_type) |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
201 if content_type not in ok_types: |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
202 continue |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
203 payload = part.get_payload(decode=True) |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
204 m = diffre.search(payload) |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
205 if m: |
4220
1253703853a8
git-send-email compatibility: stop reading changelog after ^---$
Brendan Cully <brendan@kublai.com>
parents:
4208
diff
changeset
|
206 hgpatch = False |
12645
d7452292f9d3
import: don't strip '#' lines from patch descriptions (issue 2417)
Mads Kiilerich <mads@kiilerich.com>
parents:
12577
diff
changeset
|
207 hgpatchheader = False |
4220
1253703853a8
git-send-email compatibility: stop reading changelog after ^---$
Brendan Cully <brendan@kublai.com>
parents:
4208
diff
changeset
|
208 ignoretext = False |
1253703853a8
git-send-email compatibility: stop reading changelog after ^---$
Brendan Cully <brendan@kublai.com>
parents:
4208
diff
changeset
|
209 |
9467
4c041f1ee1b4
do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents:
9393
diff
changeset
|
210 ui.debug('found patch at byte %d\n' % m.start(0)) |
2866
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
211 diffs_seen += 1 |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
212 cfp = cStringIO.StringIO() |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
213 for line in payload[:m.start(0)].splitlines(): |
12728
80a3d1121c10
import: only the first hg patch marker should be processed (issue2417)
Mads Kiilerich <mads@kiilerich.com>
parents:
12675
diff
changeset
|
214 if line.startswith('# HG changeset patch') and not hgpatch: |
9467
4c041f1ee1b4
do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents:
9393
diff
changeset
|
215 ui.debug('patch generated by hg export\n') |
12728
80a3d1121c10
import: only the first hg patch marker should be processed (issue2417)
Mads Kiilerich <mads@kiilerich.com>
parents:
12675
diff
changeset
|
216 hgpatch = True |
12645
d7452292f9d3
import: don't strip '#' lines from patch descriptions (issue 2417)
Mads Kiilerich <mads@kiilerich.com>
parents:
12577
diff
changeset
|
217 hgpatchheader = True |
2866
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
218 # drop earlier commit message content |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
219 cfp.seek(0) |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
220 cfp.truncate() |
4778
e321f16f4eac
patch.extract: fix test-import breakage introduced in the previous changeset
Brendan Cully <brendan@kublai.com>
parents:
4777
diff
changeset
|
221 subject = None |
12645
d7452292f9d3
import: don't strip '#' lines from patch descriptions (issue 2417)
Mads Kiilerich <mads@kiilerich.com>
parents:
12577
diff
changeset
|
222 elif hgpatchheader: |
2866
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
223 if line.startswith('# User '): |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
224 user = line[7:] |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
225 ui.debug('From: %s\n' % user) |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
226 elif line.startswith("# Date "): |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
227 date = line[7:] |
4443
eff2eefdb65a
Add ability to parse branch information to hg import
Eric Hopper <hopper@omnifarious.org>
parents:
4436
diff
changeset
|
228 elif line.startswith("# Branch "): |
eff2eefdb65a
Add ability to parse branch information to hg import
Eric Hopper <hopper@omnifarious.org>
parents:
4436
diff
changeset
|
229 branch = line[9:] |
4263 | 230 elif line.startswith("# Node ID "): |
231 nodeid = line[10:] | |
232 elif line.startswith("# Parent "): | |
16475
1f75c1decdeb
patch: be more tolerant with "Parent" header (issue3356)
Patrick Mezard <patrick@mezard.eu>
parents:
16358
diff
changeset
|
233 parents.append(line[9:].lstrip()) |
12645
d7452292f9d3
import: don't strip '#' lines from patch descriptions (issue 2417)
Mads Kiilerich <mads@kiilerich.com>
parents:
12577
diff
changeset
|
234 elif not line.startswith("# "): |
d7452292f9d3
import: don't strip '#' lines from patch descriptions (issue 2417)
Mads Kiilerich <mads@kiilerich.com>
parents:
12577
diff
changeset
|
235 hgpatchheader = False |
5418
9b469bdb1ce1
patch: fix git sendmail handling without proper mail headers
Patrick Mezard <pmezard@gmail.com>
parents:
5403
diff
changeset
|
236 elif line == '---' and gitsendmail: |
4220
1253703853a8
git-send-email compatibility: stop reading changelog after ^---$
Brendan Cully <brendan@kublai.com>
parents:
4208
diff
changeset
|
237 ignoretext = True |
12645
d7452292f9d3
import: don't strip '#' lines from patch descriptions (issue 2417)
Mads Kiilerich <mads@kiilerich.com>
parents:
12577
diff
changeset
|
238 if not hgpatchheader and not ignoretext: |
2866
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
239 cfp.write(line) |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
240 cfp.write('\n') |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
241 message = cfp.getvalue() |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
242 if tmpfp: |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
243 tmpfp.write(payload) |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
244 if not payload.endswith('\n'): |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
245 tmpfp.write('\n') |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
246 elif not diffs_seen and message and content_type == 'text/plain': |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
247 message += '\n' + payload |
16705
c2d9ef43ff6c
check-code: ignore naked excepts with a "re-raise" comment
Brodie Rao <brodie@sf.io>
parents:
16687
diff
changeset
|
248 except: # re-raises |
2866
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
249 tmpfp.close() |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
250 os.unlink(tmpname) |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
251 raise |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
252 |
4777
5ee5cbfceff3
patch.extract: do not prepend subject if the description already starts with it
Brendan Cully <brendan@kublai.com>
parents:
4659
diff
changeset
|
253 if subject and not message.startswith(subject): |
5ee5cbfceff3
patch.extract: do not prepend subject if the description already starts with it
Brendan Cully <brendan@kublai.com>
parents:
4659
diff
changeset
|
254 message = '%s\n%s' % (subject, message) |
2866
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
255 tmpfp.close() |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
256 if not diffs_seen: |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
257 os.unlink(tmpname) |
4443
eff2eefdb65a
Add ability to parse branch information to hg import
Eric Hopper <hopper@omnifarious.org>
parents:
4436
diff
changeset
|
258 return None, message, user, date, branch, None, None, None |
4263 | 259 p1 = parents and parents.pop(0) or None |
260 p2 = parents and parents.pop(0) or None | |
4443
eff2eefdb65a
Add ability to parse branch information to hg import
Eric Hopper <hopper@omnifarious.org>
parents:
4436
diff
changeset
|
261 return tmpname, message, user, date, branch, nodeid, p1, p2 |
2861
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
262 |
8778
c5f36402daad
use new style classes
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
8761
diff
changeset
|
263 class patchmeta(object): |
7148
7d84e5b00e29
patch: extract and rename gitpatch into patchmeta, document
Patrick Mezard <pmezard@gmail.com>
parents:
7147
diff
changeset
|
264 """Patched file metadata |
7d84e5b00e29
patch: extract and rename gitpatch into patchmeta, document
Patrick Mezard <pmezard@gmail.com>
parents:
7147
diff
changeset
|
265 |
7d84e5b00e29
patch: extract and rename gitpatch into patchmeta, document
Patrick Mezard <pmezard@gmail.com>
parents:
7147
diff
changeset
|
266 '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
|
267 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
|
268 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
|
269 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
|
270 '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
|
271 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
|
272 """ |
7d84e5b00e29
patch: extract and rename gitpatch into patchmeta, document
Patrick Mezard <pmezard@gmail.com>
parents:
7147
diff
changeset
|
273 def __init__(self, path): |
7d84e5b00e29
patch: extract and rename gitpatch into patchmeta, document
Patrick Mezard <pmezard@gmail.com>
parents:
7147
diff
changeset
|
274 self.path = path |
7d84e5b00e29
patch: extract and rename gitpatch into patchmeta, document
Patrick Mezard <pmezard@gmail.com>
parents:
7147
diff
changeset
|
275 self.oldpath = None |
7d84e5b00e29
patch: extract and rename gitpatch into patchmeta, document
Patrick Mezard <pmezard@gmail.com>
parents:
7147
diff
changeset
|
276 self.mode = None |
7d84e5b00e29
patch: extract and rename gitpatch into patchmeta, document
Patrick Mezard <pmezard@gmail.com>
parents:
7147
diff
changeset
|
277 self.op = 'MODIFY' |
7d84e5b00e29
patch: extract and rename gitpatch into patchmeta, document
Patrick Mezard <pmezard@gmail.com>
parents:
7147
diff
changeset
|
278 self.binary = False |
7d84e5b00e29
patch: extract and rename gitpatch into patchmeta, document
Patrick Mezard <pmezard@gmail.com>
parents:
7147
diff
changeset
|
279 |
7149
01a056c54385
patch: patchmeta gives (islink, isexec) tuple instead of int mode
Patrick Mezard <pmezard@gmail.com>
parents:
7148
diff
changeset
|
280 def setmode(self, mode): |
01a056c54385
patch: patchmeta gives (islink, isexec) tuple instead of int mode
Patrick Mezard <pmezard@gmail.com>
parents:
7148
diff
changeset
|
281 islink = mode & 020000 |
01a056c54385
patch: patchmeta gives (islink, isexec) tuple instead of int mode
Patrick Mezard <pmezard@gmail.com>
parents:
7148
diff
changeset
|
282 isexec = mode & 0100 |
01a056c54385
patch: patchmeta gives (islink, isexec) tuple instead of int mode
Patrick Mezard <pmezard@gmail.com>
parents:
7148
diff
changeset
|
283 self.mode = (islink, isexec) |
01a056c54385
patch: patchmeta gives (islink, isexec) tuple instead of int mode
Patrick Mezard <pmezard@gmail.com>
parents:
7148
diff
changeset
|
284 |
14566
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
285 def copy(self): |
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
286 other = patchmeta(self.path) |
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
287 other.oldpath = self.oldpath |
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
288 other.mode = self.mode |
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
289 other.op = self.op |
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
290 other.binary = self.binary |
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
291 return other |
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
292 |
16506
fc4e0fecf403
patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents:
16475
diff
changeset
|
293 def _ispatchinga(self, afile): |
fc4e0fecf403
patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents:
16475
diff
changeset
|
294 if afile == '/dev/null': |
fc4e0fecf403
patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents:
16475
diff
changeset
|
295 return self.op == 'ADD' |
fc4e0fecf403
patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents:
16475
diff
changeset
|
296 return afile == 'a/' + (self.oldpath or self.path) |
fc4e0fecf403
patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents:
16475
diff
changeset
|
297 |
fc4e0fecf403
patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents:
16475
diff
changeset
|
298 def _ispatchingb(self, bfile): |
fc4e0fecf403
patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents:
16475
diff
changeset
|
299 if bfile == '/dev/null': |
fc4e0fecf403
patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents:
16475
diff
changeset
|
300 return self.op == 'DELETE' |
fc4e0fecf403
patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents:
16475
diff
changeset
|
301 return bfile == 'b/' + self.path |
fc4e0fecf403
patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents:
16475
diff
changeset
|
302 |
fc4e0fecf403
patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents:
16475
diff
changeset
|
303 def ispatching(self, afile, bfile): |
fc4e0fecf403
patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents:
16475
diff
changeset
|
304 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
|
305 |
11018
17cf756ba25d
patch: descriptive patchmeta.__repr__ to help debugging
Mads Kiilerich <mads@kiilerich.com>
parents:
10966
diff
changeset
|
306 def __repr__(self): |
17cf756ba25d
patch: descriptive patchmeta.__repr__ to help debugging
Mads Kiilerich <mads@kiilerich.com>
parents:
10966
diff
changeset
|
307 return "<patchmeta %s %r>" % (self.op, self.path) |
17cf756ba25d
patch: descriptive patchmeta.__repr__ to help debugging
Mads Kiilerich <mads@kiilerich.com>
parents:
10966
diff
changeset
|
308 |
7152
f0055cec8446
patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents:
7151
diff
changeset
|
309 def readgitpatch(lr): |
2861
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
310 """extract git-style metadata about patches from <patchname>""" |
3223
53e843840349
Whitespace/Tab cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
3199
diff
changeset
|
311 |
2861
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
312 # Filter patch for git information |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
313 gp = None |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
314 gitpatches = [] |
7152
f0055cec8446
patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents:
7151
diff
changeset
|
315 for line in lr: |
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
|
316 line = line.rstrip(' \r\n') |
2861
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
317 if line.startswith('diff --git'): |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
318 m = gitre.match(line) |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
319 if m: |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
320 if gp: |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
321 gitpatches.append(gp) |
9392
039bce1b505f
patch: readgitpatch: remove unused variable 'src'
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
9331
diff
changeset
|
322 dst = m.group(2) |
7148
7d84e5b00e29
patch: extract and rename gitpatch into patchmeta, document
Patrick Mezard <pmezard@gmail.com>
parents:
7147
diff
changeset
|
323 gp = patchmeta(dst) |
2861
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
324 elif gp: |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
325 if line.startswith('--- '): |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
326 gitpatches.append(gp) |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
327 gp = None |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
328 continue |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
329 if line.startswith('rename from '): |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
330 gp.op = '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
|
331 gp.oldpath = line[12:] |
2861
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
332 elif line.startswith('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
|
333 gp.path = line[10:] |
2861
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
334 elif line.startswith('copy from '): |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
335 gp.op = '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
|
336 gp.oldpath = line[10:] |
2861
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
337 elif line.startswith('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
|
338 gp.path = line[8:] |
2861
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
339 elif line.startswith('deleted file'): |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
340 gp.op = 'DELETE' |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
341 elif line.startswith('new file mode '): |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
342 gp.op = '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
|
343 gp.setmode(int(line[-6:], 8)) |
2861
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
344 elif line.startswith('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
|
345 gp.setmode(int(line[-6:], 8)) |
3367
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
346 elif line.startswith('GIT binary patch'): |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
347 gp.binary = True |
2861
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
348 if gp: |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
349 gitpatches.append(gp) |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
350 |
12669
b0fa39c68370
patch: remove unused flags from readgitpatch()
Patrick Mezard <pmezard@gmail.com>
parents:
12645
diff
changeset
|
351 return gitpatches |
2861
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
352 |
8891
5fe8dc75aa4a
patch: use new style class in linereader
Simon Heimberg <simohe@besonet.ch>
parents:
8843
diff
changeset
|
353 class linereader(object): |
8810
ac92775b3b80
Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents:
8778
diff
changeset
|
354 # 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
|
355 def __init__(self, fp): |
8810
ac92775b3b80
Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents:
8778
diff
changeset
|
356 self.fp = fp |
ac92775b3b80
Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents:
8778
diff
changeset
|
357 self.buf = [] |
ac92775b3b80
Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents:
8778
diff
changeset
|
358 |
ac92775b3b80
Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents:
8778
diff
changeset
|
359 def push(self, line): |
ac92775b3b80
Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents:
8778
diff
changeset
|
360 if line is not None: |
ac92775b3b80
Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents:
8778
diff
changeset
|
361 self.buf.append(line) |
ac92775b3b80
Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents:
8778
diff
changeset
|
362 |
ac92775b3b80
Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents:
8778
diff
changeset
|
363 def readline(self): |
ac92775b3b80
Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents:
8778
diff
changeset
|
364 if self.buf: |
ac92775b3b80
Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents:
8778
diff
changeset
|
365 l = self.buf[0] |
ac92775b3b80
Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents:
8778
diff
changeset
|
366 del self.buf[0] |
ac92775b3b80
Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents:
8778
diff
changeset
|
367 return l |
14418
0174d1f79280
patch: remove EOL support from linereader class
Patrick Mezard <pmezard@gmail.com>
parents:
14402
diff
changeset
|
368 return self.fp.readline() |
8810
ac92775b3b80
Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents:
8778
diff
changeset
|
369 |
ac92775b3b80
Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents:
8778
diff
changeset
|
370 def __iter__(self): |
14494
1ffeeb91c55d
check-code: flag 0/1 used as constant Boolean expression
Martin Geisler <mg@lazybytes.net>
parents:
14453
diff
changeset
|
371 while True: |
8810
ac92775b3b80
Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents:
8778
diff
changeset
|
372 l = self.readline() |
ac92775b3b80
Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents:
8778
diff
changeset
|
373 if not l: |
ac92775b3b80
Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents:
8778
diff
changeset
|
374 break |
ac92775b3b80
Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents:
8778
diff
changeset
|
375 yield l |
ac92775b3b80
Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents:
8778
diff
changeset
|
376 |
14348
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
377 class abstractbackend(object): |
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
378 def __init__(self, ui): |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
379 self.ui = ui |
14348
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
380 |
14391
1e64e1e12195
patch: unify backend file access interface
Patrick Mezard <pmezard@gmail.com>
parents:
14390
diff
changeset
|
381 def getfile(self, fname): |
1e64e1e12195
patch: unify backend file access interface
Patrick Mezard <pmezard@gmail.com>
parents:
14390
diff
changeset
|
382 """Return target file data and flags as a (data, (islink, |
1e64e1e12195
patch: unify backend file access interface
Patrick Mezard <pmezard@gmail.com>
parents:
14390
diff
changeset
|
383 isexec)) tuple. |
14348
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
384 """ |
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
385 raise NotImplementedError |
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
386 |
14452
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
387 def setfile(self, fname, data, mode, copysource): |
14391
1e64e1e12195
patch: unify backend file access interface
Patrick Mezard <pmezard@gmail.com>
parents:
14390
diff
changeset
|
388 """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
|
389 (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
|
390 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
|
391 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
|
392 """ |
14348
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
393 raise NotImplementedError |
5652
e90e72c6b4c7
patch: write rej files for missing targets (issue 853)
Patrick Mezard <pmezard@gmail.com>
parents:
5651
diff
changeset
|
394 |
14348
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
395 def unlink(self, fname): |
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
396 """Unlink target file.""" |
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
397 raise NotImplementedError |
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
398 |
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
399 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
|
400 """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
|
401 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
|
402 files. |
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
403 """ |
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
404 pass |
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
405 |
14351
d54f9bbcc640
patch: add lexists() to backends, use it in selectfile()
Patrick Mezard <pmezard@gmail.com>
parents:
14350
diff
changeset
|
406 def exists(self, fname): |
d54f9bbcc640
patch: add lexists() to backends, use it in selectfile()
Patrick Mezard <pmezard@gmail.com>
parents:
14350
diff
changeset
|
407 raise NotImplementedError |
d54f9bbcc640
patch: add lexists() to backends, use it in selectfile()
Patrick Mezard <pmezard@gmail.com>
parents:
14350
diff
changeset
|
408 |
14348
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
409 class fsbackend(abstractbackend): |
14350
00da6624e167
patch: move copyfile() into backends, abstract basedir
Patrick Mezard <pmezard@gmail.com>
parents:
14349
diff
changeset
|
410 def __init__(self, ui, basedir): |
14348
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
411 super(fsbackend, self).__init__(ui) |
14350
00da6624e167
patch: move copyfile() into backends, abstract basedir
Patrick Mezard <pmezard@gmail.com>
parents:
14349
diff
changeset
|
412 self.opener = scmutil.opener(basedir) |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
413 |
14366
992a7e398ddd
patch: stop changing current directory before patching
Patrick Mezard <pmezard@gmail.com>
parents:
14352
diff
changeset
|
414 def _join(self, f): |
992a7e398ddd
patch: stop changing current directory before patching
Patrick Mezard <pmezard@gmail.com>
parents:
14352
diff
changeset
|
415 return os.path.join(self.opener.base, f) |
992a7e398ddd
patch: stop changing current directory before patching
Patrick Mezard <pmezard@gmail.com>
parents:
14352
diff
changeset
|
416 |
14391
1e64e1e12195
patch: unify backend file access interface
Patrick Mezard <pmezard@gmail.com>
parents:
14390
diff
changeset
|
417 def getfile(self, fname): |
1e64e1e12195
patch: unify backend file access interface
Patrick Mezard <pmezard@gmail.com>
parents:
14390
diff
changeset
|
418 path = self._join(fname) |
1e64e1e12195
patch: unify backend file access interface
Patrick Mezard <pmezard@gmail.com>
parents:
14390
diff
changeset
|
419 if os.path.islink(path): |
1e64e1e12195
patch: unify backend file access interface
Patrick Mezard <pmezard@gmail.com>
parents:
14390
diff
changeset
|
420 return (os.readlink(path), (True, False)) |
14531
b88368a3ade4
patch: remove redundant islink() call
Patrick Mezard <pmezard@gmail.com>
parents:
14494
diff
changeset
|
421 isexec = False |
7392
564326a6ef9c
patch: isolate patchfile filesystem calls into methods
Patrick Mezard <pmezard@gmail.com>
parents:
7391
diff
changeset
|
422 try: |
14391
1e64e1e12195
patch: unify backend file access interface
Patrick Mezard <pmezard@gmail.com>
parents:
14390
diff
changeset
|
423 isexec = os.lstat(path).st_mode & 0100 != 0 |
1e64e1e12195
patch: unify backend file access interface
Patrick Mezard <pmezard@gmail.com>
parents:
14390
diff
changeset
|
424 except OSError, e: |
1e64e1e12195
patch: unify backend file access interface
Patrick Mezard <pmezard@gmail.com>
parents:
14390
diff
changeset
|
425 if e.errno != errno.ENOENT: |
1e64e1e12195
patch: unify backend file access interface
Patrick Mezard <pmezard@gmail.com>
parents:
14390
diff
changeset
|
426 raise |
14531
b88368a3ade4
patch: remove redundant islink() call
Patrick Mezard <pmezard@gmail.com>
parents:
14494
diff
changeset
|
427 return (self.opener.read(fname), (False, isexec)) |
7392
564326a6ef9c
patch: isolate patchfile filesystem calls into methods
Patrick Mezard <pmezard@gmail.com>
parents:
7391
diff
changeset
|
428 |
14452
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
429 def setfile(self, fname, data, mode, copysource): |
14391
1e64e1e12195
patch: unify backend file access interface
Patrick Mezard <pmezard@gmail.com>
parents:
14390
diff
changeset
|
430 islink, isexec = mode |
1e64e1e12195
patch: unify backend file access interface
Patrick Mezard <pmezard@gmail.com>
parents:
14390
diff
changeset
|
431 if data is None: |
1e64e1e12195
patch: unify backend file access interface
Patrick Mezard <pmezard@gmail.com>
parents:
14390
diff
changeset
|
432 util.setflags(self._join(fname), islink, isexec) |
14390
ce77c275bec3
patch: merge backend setmode() into writelines()
Patrick Mezard <pmezard@gmail.com>
parents:
14389
diff
changeset
|
433 return |
14391
1e64e1e12195
patch: unify backend file access interface
Patrick Mezard <pmezard@gmail.com>
parents:
14390
diff
changeset
|
434 if islink: |
1e64e1e12195
patch: unify backend file access interface
Patrick Mezard <pmezard@gmail.com>
parents:
14390
diff
changeset
|
435 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
|
436 else: |
14391
1e64e1e12195
patch: unify backend file access interface
Patrick Mezard <pmezard@gmail.com>
parents:
14390
diff
changeset
|
437 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
|
438 if isexec: |
468d7d1744b4
patch: set desired mode when patching, not in updatedir()
Patrick Mezard <pmezard@gmail.com>
parents:
14366
diff
changeset
|
439 util.setflags(self._join(fname), False, True) |
7392
564326a6ef9c
patch: isolate patchfile filesystem calls into methods
Patrick Mezard <pmezard@gmail.com>
parents:
7391
diff
changeset
|
440 |
564326a6ef9c
patch: isolate patchfile filesystem calls into methods
Patrick Mezard <pmezard@gmail.com>
parents:
7391
diff
changeset
|
441 def unlink(self, fname): |
14368
baf2807b9a7d
patch: remove files while patching, not in updatedir()
Patrick Mezard <pmezard@gmail.com>
parents:
14367
diff
changeset
|
442 try: |
baf2807b9a7d
patch: remove files while patching, not in updatedir()
Patrick Mezard <pmezard@gmail.com>
parents:
14367
diff
changeset
|
443 util.unlinkpath(self._join(fname)) |
baf2807b9a7d
patch: remove files while patching, not in updatedir()
Patrick Mezard <pmezard@gmail.com>
parents:
14367
diff
changeset
|
444 except OSError, inst: |
baf2807b9a7d
patch: remove files while patching, not in updatedir()
Patrick Mezard <pmezard@gmail.com>
parents:
14367
diff
changeset
|
445 if inst.errno != errno.ENOENT: |
baf2807b9a7d
patch: remove files while patching, not in updatedir()
Patrick Mezard <pmezard@gmail.com>
parents:
14367
diff
changeset
|
446 raise |
7392
564326a6ef9c
patch: isolate patchfile filesystem calls into methods
Patrick Mezard <pmezard@gmail.com>
parents:
7391
diff
changeset
|
447 |
14348
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
448 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
|
449 fname = fname + ".rej" |
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
450 self.ui.warn( |
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
451 _("%d out of %d hunks FAILED -- saving rejects to file %s\n") % |
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
452 (failed, total, fname)) |
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
453 fp = self.opener(fname, 'w') |
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
454 fp.writelines(lines) |
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
455 fp.close() |
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
456 |
14351
d54f9bbcc640
patch: add lexists() to backends, use it in selectfile()
Patrick Mezard <pmezard@gmail.com>
parents:
14350
diff
changeset
|
457 def exists(self, fname): |
14366
992a7e398ddd
patch: stop changing current directory before patching
Patrick Mezard <pmezard@gmail.com>
parents:
14352
diff
changeset
|
458 return os.path.lexists(self._join(fname)) |
14351
d54f9bbcc640
patch: add lexists() to backends, use it in selectfile()
Patrick Mezard <pmezard@gmail.com>
parents:
14350
diff
changeset
|
459 |
14370
17cea10c343e
patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14369
diff
changeset
|
460 class workingbackend(fsbackend): |
17cea10c343e
patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14369
diff
changeset
|
461 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
|
462 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
|
463 self.repo = repo |
17cea10c343e
patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14369
diff
changeset
|
464 self.similarity = similarity |
17cea10c343e
patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14369
diff
changeset
|
465 self.removed = set() |
17cea10c343e
patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14369
diff
changeset
|
466 self.changed = set() |
17cea10c343e
patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14369
diff
changeset
|
467 self.copied = [] |
17cea10c343e
patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14369
diff
changeset
|
468 |
14453
ea3d548132cc
patch: do not patch unknown files (issue752)
Patrick Mezard <pmezard@gmail.com>
parents:
14452
diff
changeset
|
469 def _checkknown(self, fname): |
ea3d548132cc
patch: do not patch unknown files (issue752)
Patrick Mezard <pmezard@gmail.com>
parents:
14452
diff
changeset
|
470 if self.repo.dirstate[fname] == '?' and self.exists(fname): |
ea3d548132cc
patch: do not patch unknown files (issue752)
Patrick Mezard <pmezard@gmail.com>
parents:
14452
diff
changeset
|
471 raise PatchError(_('cannot patch %s: file is not tracked') % fname) |
ea3d548132cc
patch: do not patch unknown files (issue752)
Patrick Mezard <pmezard@gmail.com>
parents:
14452
diff
changeset
|
472 |
14452
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
473 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
|
474 self._checkknown(fname) |
14452
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
475 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
|
476 if copysource is not None: |
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
477 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
|
478 self.changed.add(fname) |
17cea10c343e
patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14369
diff
changeset
|
479 |
17cea10c343e
patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14369
diff
changeset
|
480 def unlink(self, fname): |
14453
ea3d548132cc
patch: do not patch unknown files (issue752)
Patrick Mezard <pmezard@gmail.com>
parents:
14452
diff
changeset
|
481 self._checkknown(fname) |
14370
17cea10c343e
patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14369
diff
changeset
|
482 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
|
483 self.removed.add(fname) |
17cea10c343e
patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14369
diff
changeset
|
484 self.changed.add(fname) |
17cea10c343e
patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14369
diff
changeset
|
485 |
17cea10c343e
patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14369
diff
changeset
|
486 def close(self): |
17cea10c343e
patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14369
diff
changeset
|
487 wctx = self.repo[None] |
17cea10c343e
patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14369
diff
changeset
|
488 addremoved = set(self.changed) |
17cea10c343e
patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14369
diff
changeset
|
489 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
|
490 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
|
491 if self.removed: |
14435
5f6090e559fa
context: make forget work like commands.forget
Matt Mackall <mpm@selenic.com>
parents:
14418
diff
changeset
|
492 wctx.forget(sorted(self.removed)) |
16112
d7829b2ecf32
import: handle git renames and --similarity (issue3187)
Patrick Mezard <patrick@mezard.eu>
parents:
15971
diff
changeset
|
493 for f in self.removed: |
d7829b2ecf32
import: handle git renames and --similarity (issue3187)
Patrick Mezard <patrick@mezard.eu>
parents:
15971
diff
changeset
|
494 if f not in self.repo.dirstate: |
d7829b2ecf32
import: handle git renames and --similarity (issue3187)
Patrick Mezard <patrick@mezard.eu>
parents:
15971
diff
changeset
|
495 # 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
|
496 # dirstate, it was probably marked added then |
d7829b2ecf32
import: handle git renames and --similarity (issue3187)
Patrick Mezard <patrick@mezard.eu>
parents:
15971
diff
changeset
|
497 # deleted, and should not be considered by |
d7829b2ecf32
import: handle git renames and --similarity (issue3187)
Patrick Mezard <patrick@mezard.eu>
parents:
15971
diff
changeset
|
498 # addremove(). |
d7829b2ecf32
import: handle git renames and --similarity (issue3187)
Patrick Mezard <patrick@mezard.eu>
parents:
15971
diff
changeset
|
499 addremoved.discard(f) |
14370
17cea10c343e
patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14369
diff
changeset
|
500 if addremoved: |
17cea10c343e
patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14369
diff
changeset
|
501 cwd = self.repo.getcwd() |
17cea10c343e
patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14369
diff
changeset
|
502 if cwd: |
17cea10c343e
patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14369
diff
changeset
|
503 addremoved = [util.pathto(self.repo.root, cwd, f) |
17cea10c343e
patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14369
diff
changeset
|
504 for f in addremoved] |
17cea10c343e
patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14369
diff
changeset
|
505 scmutil.addremove(self.repo, addremoved, similarity=self.similarity) |
17cea10c343e
patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14369
diff
changeset
|
506 return sorted(self.changed) |
17cea10c343e
patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14369
diff
changeset
|
507 |
14452
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
508 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
|
509 def __init__(self, maxsize=None): |
14452
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
510 self.opener = None |
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
511 self.files = {} |
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
512 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
|
513 self.maxsize = maxsize |
7ddf9a607b75
patch: make filestore store data in memory and fallback to fs
Patrick Mezard <pmezard@gmail.com>
parents:
14611
diff
changeset
|
514 if self.maxsize is None: |
7ddf9a607b75
patch: make filestore store data in memory and fallback to fs
Patrick Mezard <pmezard@gmail.com>
parents:
14611
diff
changeset
|
515 self.maxsize = 4*(2**20) |
7ddf9a607b75
patch: make filestore store data in memory and fallback to fs
Patrick Mezard <pmezard@gmail.com>
parents:
14611
diff
changeset
|
516 self.size = 0 |
7ddf9a607b75
patch: make filestore store data in memory and fallback to fs
Patrick Mezard <pmezard@gmail.com>
parents:
14611
diff
changeset
|
517 self.data = {} |
14452
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
518 |
14609
f53dc0787424
patch: extend filtestore to store an optional copy source
Patrick Mezard <pmezard@gmail.com>
parents:
14566
diff
changeset
|
519 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
|
520 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
|
521 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
|
522 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
|
523 else: |
7ddf9a607b75
patch: make filestore store data in memory and fallback to fs
Patrick Mezard <pmezard@gmail.com>
parents:
14611
diff
changeset
|
524 if self.opener is None: |
7ddf9a607b75
patch: make filestore store data in memory and fallback to fs
Patrick Mezard <pmezard@gmail.com>
parents:
14611
diff
changeset
|
525 root = tempfile.mkdtemp(prefix='hg-patch-') |
7ddf9a607b75
patch: make filestore store data in memory and fallback to fs
Patrick Mezard <pmezard@gmail.com>
parents:
14611
diff
changeset
|
526 self.opener = scmutil.opener(root) |
7ddf9a607b75
patch: make filestore store data in memory and fallback to fs
Patrick Mezard <pmezard@gmail.com>
parents:
14611
diff
changeset
|
527 # Avoid filename issues with these simple names |
7ddf9a607b75
patch: make filestore store data in memory and fallback to fs
Patrick Mezard <pmezard@gmail.com>
parents:
14611
diff
changeset
|
528 fn = str(self.created) |
7ddf9a607b75
patch: make filestore store data in memory and fallback to fs
Patrick Mezard <pmezard@gmail.com>
parents:
14611
diff
changeset
|
529 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
|
530 self.created += 1 |
7ddf9a607b75
patch: make filestore store data in memory and fallback to fs
Patrick Mezard <pmezard@gmail.com>
parents:
14611
diff
changeset
|
531 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
|
532 |
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
533 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
|
534 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
|
535 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
|
536 if not self.opener or fname not in self.files: |
16687
e34106fa0dc3
cleanup: "raise SomeException()" -> "raise SomeException"
Brodie Rao <brodie@sf.io>
parents:
16686
diff
changeset
|
537 raise IOError |
14609
f53dc0787424
patch: extend filtestore to store an optional copy source
Patrick Mezard <pmezard@gmail.com>
parents:
14566
diff
changeset
|
538 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
|
539 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
|
540 |
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
541 def close(self): |
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
542 if self.opener: |
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
543 shutil.rmtree(self.opener.base) |
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
544 |
14611
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
545 class repobackend(abstractbackend): |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
546 def __init__(self, ui, repo, ctx, store): |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
547 super(repobackend, self).__init__(ui) |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
548 self.repo = repo |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
549 self.ctx = ctx |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
550 self.store = store |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
551 self.changed = set() |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
552 self.removed = set() |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
553 self.copied = {} |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
554 |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
555 def _checkknown(self, fname): |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
556 if fname not in self.ctx: |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
557 raise PatchError(_('cannot patch %s: file is not tracked') % fname) |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
558 |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
559 def getfile(self, fname): |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
560 try: |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
561 fctx = self.ctx[fname] |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
562 except error.LookupError: |
16687
e34106fa0dc3
cleanup: "raise SomeException()" -> "raise SomeException"
Brodie Rao <brodie@sf.io>
parents:
16686
diff
changeset
|
563 raise IOError |
14611
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
564 flags = fctx.flags() |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
565 return fctx.data(), ('l' in flags, 'x' in flags) |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
566 |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
567 def setfile(self, fname, data, mode, copysource): |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
568 if copysource: |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
569 self._checkknown(copysource) |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
570 if data is None: |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
571 data = self.ctx[fname].data() |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
572 self.store.setfile(fname, data, mode, copysource) |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
573 self.changed.add(fname) |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
574 if copysource: |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
575 self.copied[fname] = copysource |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
576 |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
577 def unlink(self, fname): |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
578 self._checkknown(fname) |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
579 self.removed.add(fname) |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
580 |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
581 def exists(self, fname): |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
582 return fname in self.ctx |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
583 |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
584 def close(self): |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
585 return self.changed | self.removed |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
586 |
14348
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
587 # @@ -start,len +start,len @@ or @@ -start +start @@ if len is 1 |
15510
5414b56cfad6
patch: simplify hunk extents parsing
Patrick Mezard <pmezard@gmail.com>
parents:
15462
diff
changeset
|
588 unidesc = re.compile('@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@') |
5414b56cfad6
patch: simplify hunk extents parsing
Patrick Mezard <pmezard@gmail.com>
parents:
15462
diff
changeset
|
589 contextdesc = re.compile('(?:---|\*\*\*) (\d+)(?:,(\d+))? (?:---|\*\*\*)') |
14348
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
590 eolmodes = ['strict', 'crlf', 'lf', 'auto'] |
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
591 |
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
592 class patchfile(object): |
14566
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
593 def __init__(self, ui, gp, backend, store, eolmode='strict'): |
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
594 self.fname = gp.path |
14348
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
595 self.eolmode = eolmode |
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
596 self.eol = None |
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
597 self.backend = backend |
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
598 self.ui = ui |
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
599 self.lines = [] |
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
600 self.exists = False |
14452
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
601 self.missing = True |
14566
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
602 self.mode = gp.mode |
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
603 self.copysource = gp.oldpath |
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
604 self.create = gp.op in ('ADD', 'COPY', 'RENAME') |
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
605 self.remove = gp.op == 'DELETE' |
14452
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
606 try: |
14566
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
607 if self.copysource is None: |
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
608 data, mode = backend.getfile(self.fname) |
14348
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
609 self.exists = True |
14452
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
610 else: |
14609
f53dc0787424
patch: extend filtestore to store an optional copy source
Patrick Mezard <pmezard@gmail.com>
parents:
14566
diff
changeset
|
611 data, mode = store.getfile(self.copysource)[:2] |
14566
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
612 self.exists = backend.exists(self.fname) |
14452
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
613 self.missing = False |
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
614 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
|
615 self.lines = mdiff.splitnewlines(data) |
14452
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
616 if self.mode is None: |
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
617 self.mode = mode |
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
618 if self.lines: |
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
619 # Normalize line endings |
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
620 if self.lines[0].endswith('\r\n'): |
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
621 self.eol = '\r\n' |
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
622 elif self.lines[0].endswith('\n'): |
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
623 self.eol = '\n' |
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
624 if eolmode != 'strict': |
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
625 nlines = [] |
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
626 for l in self.lines: |
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
627 if l.endswith('\r\n'): |
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
628 l = l[:-2] + '\n' |
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
629 nlines.append(l) |
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
630 self.lines = nlines |
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
631 except IOError: |
14566
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
632 if self.create: |
14452
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
633 self.missing = False |
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
634 if self.mode is None: |
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
635 self.mode = (False, False) |
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
636 if self.missing: |
17299
e51d4aedace9
check-code: indent 4 spaces in py files
Mads Kiilerich <mads@kiilerich.com>
parents:
16834
diff
changeset
|
637 self.ui.warn(_("unable to find '%s' for patching\n") % self.fname) |
14348
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
638 |
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
639 self.hash = {} |
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
640 self.dirty = 0 |
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
641 self.offset = 0 |
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
642 self.skew = 0 |
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
643 self.rej = [] |
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
644 self.fileprinted = False |
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
645 self.printfile(False) |
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
646 self.hunks = 0 |
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
647 |
14367
468d7d1744b4
patch: set desired mode when patching, not in updatedir()
Patrick Mezard <pmezard@gmail.com>
parents:
14366
diff
changeset
|
648 def writelines(self, fname, lines, mode): |
14348
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
649 if self.eolmode == 'auto': |
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
650 eol = self.eol |
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
651 elif self.eolmode == 'crlf': |
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
652 eol = '\r\n' |
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
653 else: |
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
654 eol = '\n' |
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
655 |
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
656 if self.eolmode != 'strict' and eol and eol != '\n': |
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
657 rawlines = [] |
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
658 for l in lines: |
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
659 if l and l[-1] == '\n': |
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
660 l = l[:-1] + eol |
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
661 rawlines.append(l) |
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
662 lines = rawlines |
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
663 |
14452
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
664 self.backend.setfile(fname, ''.join(lines), mode, self.copysource) |
14348
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
665 |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
666 def printfile(self, warn): |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
667 if self.fileprinted: |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
668 return |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
669 if warn or self.ui.verbose: |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
670 self.fileprinted = True |
4898
bc905a6c0e76
patch.py: fix some incorrect uses of _() for i18n
Bryan O'Sullivan <bos@serpentine.com>
parents:
4897
diff
changeset
|
671 s = _("patching file %s\n") % self.fname |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
672 if warn: |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
673 self.ui.warn(s) |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
674 else: |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
675 self.ui.note(s) |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
676 |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
677 |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
678 def findlines(self, l, linenum): |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
679 # 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
|
680 # 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
|
681 # from linenum |
5143
d4fa6bafc43a
Remove trailing spaces, fix indentation
Thomas Arendsen Hein <thomas@intevation.de>
parents:
5116
diff
changeset
|
682 |
9681
ac3a68cb16eb
patch: simplify logic
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
9642
diff
changeset
|
683 cand = self.hash.get(l, []) |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
684 if len(cand) > 1: |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
685 # 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
|
686 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
|
687 return cand |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
688 |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
689 def write_rej(self): |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
690 # 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
|
691 # 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
|
692 # 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
|
693 # without having to type the filename. |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
694 if not self.rej: |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
695 return |
14349
776ae95b8835
patch: merge makerejlines() into write_rej()
Patrick Mezard <pmezard@gmail.com>
parents:
14348
diff
changeset
|
696 base = os.path.basename(self.fname) |
776ae95b8835
patch: merge makerejlines() into write_rej()
Patrick Mezard <pmezard@gmail.com>
parents:
14348
diff
changeset
|
697 lines = ["--- %s\n+++ %s\n" % (base, base)] |
776ae95b8835
patch: merge makerejlines() into write_rej()
Patrick Mezard <pmezard@gmail.com>
parents:
14348
diff
changeset
|
698 for x in self.rej: |
776ae95b8835
patch: merge makerejlines() into write_rej()
Patrick Mezard <pmezard@gmail.com>
parents:
14348
diff
changeset
|
699 for l in x.hunk: |
776ae95b8835
patch: merge makerejlines() into write_rej()
Patrick Mezard <pmezard@gmail.com>
parents:
14348
diff
changeset
|
700 lines.append(l) |
776ae95b8835
patch: merge makerejlines() into write_rej()
Patrick Mezard <pmezard@gmail.com>
parents:
14348
diff
changeset
|
701 if l[-1] != '\n': |
776ae95b8835
patch: merge makerejlines() into write_rej()
Patrick Mezard <pmezard@gmail.com>
parents:
14348
diff
changeset
|
702 lines.append("\n\ No newline at end of file\n") |
776ae95b8835
patch: merge makerejlines() into write_rej()
Patrick Mezard <pmezard@gmail.com>
parents:
14348
diff
changeset
|
703 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
|
704 |
9393
23c4e772c172
patch: remove the unused, broken reverse() function
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
9392
diff
changeset
|
705 def apply(self, h): |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
706 if not h.complete(): |
4898
bc905a6c0e76
patch.py: fix some incorrect uses of _() for i18n
Bryan O'Sullivan <bos@serpentine.com>
parents:
4897
diff
changeset
|
707 raise PatchError(_("bad hunk #%d %s (%d %d %d %d)") % |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
708 (h.number, h.desc, len(h.a), h.lena, len(h.b), |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
709 h.lenb)) |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
710 |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
711 self.hunks += 1 |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
712 |
5652
e90e72c6b4c7
patch: write rej files for missing targets (issue 853)
Patrick Mezard <pmezard@gmail.com>
parents:
5651
diff
changeset
|
713 if self.missing: |
e90e72c6b4c7
patch: write rej files for missing targets (issue 853)
Patrick Mezard <pmezard@gmail.com>
parents:
5651
diff
changeset
|
714 self.rej.append(h) |
e90e72c6b4c7
patch: write rej files for missing targets (issue 853)
Patrick Mezard <pmezard@gmail.com>
parents:
5651
diff
changeset
|
715 return -1 |
e90e72c6b4c7
patch: write rej files for missing targets (issue 853)
Patrick Mezard <pmezard@gmail.com>
parents:
5651
diff
changeset
|
716 |
14451
c78d41db6f88
patch: refactor file creation/removal detection
Patrick Mezard <pmezard@gmail.com>
parents:
14437
diff
changeset
|
717 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
|
718 if self.copysource: |
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
719 self.ui.warn(_("cannot create %s: destination already " |
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
720 "exists\n" % self.fname)) |
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
721 else: |
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
722 self.ui.warn(_("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
|
723 self.rej.append(h) |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
724 return -1 |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
725 |
9585
ea1935e2020a
patch: handle symlinks without symlinkhunk
Patrick Mezard <pmezard@gmail.com>
parents:
9573
diff
changeset
|
726 if isinstance(h, binhunk): |
14451
c78d41db6f88
patch: refactor file creation/removal detection
Patrick Mezard <pmezard@gmail.com>
parents:
14437
diff
changeset
|
727 if self.remove: |
14348
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
728 self.backend.unlink(self.fname) |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
729 else: |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
730 self.lines[:] = h.new() |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
731 self.offset += len(h.new()) |
14217
71d5287351e9
patchfile: use real Booleans instead of 0/1
Martin Geisler <mg@aragost.com>
parents:
14017
diff
changeset
|
732 self.dirty = True |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
733 return 0 |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
734 |
10127
d8214e944b84
patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents:
10102
diff
changeset
|
735 horig = h |
10128
ea7c392f2b08
patch: drop eol normalization fast-path for 'lf' and 'crlf'
Patrick Mezard <pmezard@gmail.com>
parents:
10127
diff
changeset
|
736 if (self.eolmode in ('crlf', 'lf') |
ea7c392f2b08
patch: drop eol normalization fast-path for 'lf' and 'crlf'
Patrick Mezard <pmezard@gmail.com>
parents:
10127
diff
changeset
|
737 or self.eolmode == 'auto' and self.eol): |
ea7c392f2b08
patch: drop eol normalization fast-path for 'lf' and 'crlf'
Patrick Mezard <pmezard@gmail.com>
parents:
10127
diff
changeset
|
738 # 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
|
739 # 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
|
740 # line-endings. |
10127
d8214e944b84
patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents:
10102
diff
changeset
|
741 h = h.getnormalized() |
d8214e944b84
patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents:
10102
diff
changeset
|
742 |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
743 # 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
|
744 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
|
745 oldstart += self.offset |
9ef3a4a2c6c0
patch: make hunk.fuzzit() compute the fuzzed start locations
Patrick Mezard <patrick@mezard.eu>
parents:
16121
diff
changeset
|
746 orig_start = oldstart |
10135
9a4034b630c4
patch: better handling of sequence of offset patch hunks (issue1941)
Greg Onufer <gonufer@jazzhaiku.com>
parents:
9725
diff
changeset
|
747 # 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
|
748 # 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
|
749 # fast case code |
16122
9ef3a4a2c6c0
patch: make hunk.fuzzit() compute the fuzzed start locations
Patrick Mezard <patrick@mezard.eu>
parents:
16121
diff
changeset
|
750 if (self.skew == 0 and |
9ef3a4a2c6c0
patch: make hunk.fuzzit() compute the fuzzed start locations
Patrick Mezard <patrick@mezard.eu>
parents:
16121
diff
changeset
|
751 diffhelpers.testhunk(old, self.lines, oldstart) == 0): |
14451
c78d41db6f88
patch: refactor file creation/removal detection
Patrick Mezard <pmezard@gmail.com>
parents:
14437
diff
changeset
|
752 if self.remove: |
14348
c1c719103392
patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14347
diff
changeset
|
753 self.backend.unlink(self.fname) |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
754 else: |
16122
9ef3a4a2c6c0
patch: make hunk.fuzzit() compute the fuzzed start locations
Patrick Mezard <patrick@mezard.eu>
parents:
16121
diff
changeset
|
755 self.lines[oldstart:oldstart + len(old)] = new |
9ef3a4a2c6c0
patch: make hunk.fuzzit() compute the fuzzed start locations
Patrick Mezard <patrick@mezard.eu>
parents:
16121
diff
changeset
|
756 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
|
757 self.dirty = True |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
758 return 0 |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
759 |
13700
63307feb59dd
patch: inline patchfile.hashlines()
Patrick Mezard <pmezard@gmail.com>
parents:
13699
diff
changeset
|
760 # 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
|
761 self.hash = {} |
63307feb59dd
patch: inline patchfile.hashlines()
Patrick Mezard <pmezard@gmail.com>
parents:
13699
diff
changeset
|
762 for x, s in enumerate(self.lines): |
63307feb59dd
patch: inline patchfile.hashlines()
Patrick Mezard <pmezard@gmail.com>
parents:
13699
diff
changeset
|
763 self.hash.setdefault(s, []).append(x) |
4897
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 for fuzzlen in xrange(3): |
10282
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
766 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
|
767 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
|
768 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
|
769 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
|
770 if old: |
b0c7525f826d
patch: fix fuzzing of hunks without previous lines (issue3264)
Patrick Mezard <patrick@mezard.eu>
parents:
16122
diff
changeset
|
771 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
|
772 else: |
b0c7525f826d
patch: fix fuzzing of hunks without previous lines (issue3264)
Patrick Mezard <patrick@mezard.eu>
parents:
16122
diff
changeset
|
773 # 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
|
774 # take the skew in account |
b0c7525f826d
patch: fix fuzzing of hunks without previous lines (issue3264)
Patrick Mezard <patrick@mezard.eu>
parents:
16122
diff
changeset
|
775 cand = [oldstart] |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
776 |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
777 for l in cand: |
16123
b0c7525f826d
patch: fix fuzzing of hunks without previous lines (issue3264)
Patrick Mezard <patrick@mezard.eu>
parents:
16122
diff
changeset
|
778 if not old or diffhelpers.testhunk(old, self.lines, l) == 0: |
16121
ccba74472af2
patch: fuzz old and new lines at the same time
Patrick Mezard <patrick@mezard.eu>
parents:
16112
diff
changeset
|
779 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
|
780 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
|
781 self.skew = l - orig_start |
14217
71d5287351e9
patchfile: use real Booleans instead of 0/1
Martin Geisler <mg@aragost.com>
parents:
14017
diff
changeset
|
782 self.dirty = True |
10518
5fe51d348daf
patch, i18n: avoid parameterized messages
Wagner Bruna <wbruna@softwareexpress.com.br>
parents:
10501
diff
changeset
|
783 offset = l - orig_start - fuzzlen |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
784 if fuzzlen: |
10518
5fe51d348daf
patch, i18n: avoid parameterized messages
Wagner Bruna <wbruna@softwareexpress.com.br>
parents:
10501
diff
changeset
|
785 msg = _("Hunk #%d succeeded at %d " |
5fe51d348daf
patch, i18n: avoid parameterized messages
Wagner Bruna <wbruna@softwareexpress.com.br>
parents:
10501
diff
changeset
|
786 "with fuzz %d " |
5fe51d348daf
patch, i18n: avoid parameterized messages
Wagner Bruna <wbruna@softwareexpress.com.br>
parents:
10501
diff
changeset
|
787 "(offset %d lines).\n") |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
788 self.printfile(True) |
10518
5fe51d348daf
patch, i18n: avoid parameterized messages
Wagner Bruna <wbruna@softwareexpress.com.br>
parents:
10501
diff
changeset
|
789 self.ui.warn(msg % |
5fe51d348daf
patch, i18n: avoid parameterized messages
Wagner Bruna <wbruna@softwareexpress.com.br>
parents:
10501
diff
changeset
|
790 (h.number, l + 1, fuzzlen, offset)) |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
791 else: |
10518
5fe51d348daf
patch, i18n: avoid parameterized messages
Wagner Bruna <wbruna@softwareexpress.com.br>
parents:
10501
diff
changeset
|
792 msg = _("Hunk #%d succeeded at %d " |
8090
388bb482024e
patch, i18n: avoid parameterized plural
Wagner Bruna <wbruna@yahoo.com>
parents:
7972
diff
changeset
|
793 "(offset %d lines).\n") |
10518
5fe51d348daf
patch, i18n: avoid parameterized messages
Wagner Bruna <wbruna@softwareexpress.com.br>
parents:
10501
diff
changeset
|
794 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
|
795 return fuzzlen |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
796 self.printfile(True) |
4898
bc905a6c0e76
patch.py: fix some incorrect uses of _() for i18n
Bryan O'Sullivan <bos@serpentine.com>
parents:
4897
diff
changeset
|
797 self.ui.warn(_("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
|
798 self.rej.append(horig) |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
799 return -1 |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
800 |
13701
bc38ff7cb919
patch: move closefile() into patchfile.close()
Patrick Mezard <pmezard@gmail.com>
parents:
13700
diff
changeset
|
801 def close(self): |
bc38ff7cb919
patch: move closefile() into patchfile.close()
Patrick Mezard <pmezard@gmail.com>
parents:
13700
diff
changeset
|
802 if self.dirty: |
14367
468d7d1744b4
patch: set desired mode when patching, not in updatedir()
Patrick Mezard <pmezard@gmail.com>
parents:
14366
diff
changeset
|
803 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
|
804 self.write_rej() |
bc38ff7cb919
patch: move closefile() into patchfile.close()
Patrick Mezard <pmezard@gmail.com>
parents:
13700
diff
changeset
|
805 return len(self.rej) |
bc38ff7cb919
patch: move closefile() into patchfile.close()
Patrick Mezard <pmezard@gmail.com>
parents:
13700
diff
changeset
|
806 |
8778
c5f36402daad
use new style classes
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
8761
diff
changeset
|
807 class hunk(object): |
14451
c78d41db6f88
patch: refactor file creation/removal detection
Patrick Mezard <pmezard@gmail.com>
parents:
14437
diff
changeset
|
808 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
|
809 self.number = num |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
810 self.desc = desc |
10282
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
811 self.hunk = [desc] |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
812 self.a = [] |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
813 self.b = [] |
9682
bd70f645cfb0
patch: initialize all attributes of the hunk class
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
9681
diff
changeset
|
814 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
|
815 self.startb = self.lenb = None |
10127
d8214e944b84
patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents:
10102
diff
changeset
|
816 if lr is not None: |
d8214e944b84
patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents:
10102
diff
changeset
|
817 if context: |
d8214e944b84
patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents:
10102
diff
changeset
|
818 self.read_context_hunk(lr) |
d8214e944b84
patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents:
10102
diff
changeset
|
819 else: |
d8214e944b84
patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents:
10102
diff
changeset
|
820 self.read_unified_hunk(lr) |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
821 |
10127
d8214e944b84
patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents:
10102
diff
changeset
|
822 def getnormalized(self): |
d8214e944b84
patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents:
10102
diff
changeset
|
823 """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
|
824 |
d8214e944b84
patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents:
10102
diff
changeset
|
825 def normalize(lines): |
d8214e944b84
patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents:
10102
diff
changeset
|
826 nlines = [] |
d8214e944b84
patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents:
10102
diff
changeset
|
827 for line in lines: |
d8214e944b84
patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents:
10102
diff
changeset
|
828 if line.endswith('\r\n'): |
d8214e944b84
patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents:
10102
diff
changeset
|
829 line = line[:-2] + '\n' |
d8214e944b84
patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents:
10102
diff
changeset
|
830 nlines.append(line) |
d8214e944b84
patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents:
10102
diff
changeset
|
831 return nlines |
d8214e944b84
patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents:
10102
diff
changeset
|
832 |
d8214e944b84
patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents:
10102
diff
changeset
|
833 # Dummy object, it is rebuilt manually |
14451
c78d41db6f88
patch: refactor file creation/removal detection
Patrick Mezard <pmezard@gmail.com>
parents:
14437
diff
changeset
|
834 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
|
835 nh.number = self.number |
d8214e944b84
patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents:
10102
diff
changeset
|
836 nh.desc = self.desc |
10524
3212afb33116
patch: fix patching with fuzz and eol normalization
Patrick Mezard <pmezard@gmail.com>
parents:
10518
diff
changeset
|
837 nh.hunk = self.hunk |
10127
d8214e944b84
patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents:
10102
diff
changeset
|
838 nh.a = normalize(self.a) |
d8214e944b84
patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents:
10102
diff
changeset
|
839 nh.b = normalize(self.b) |
d8214e944b84
patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents:
10102
diff
changeset
|
840 nh.starta = self.starta |
d8214e944b84
patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents:
10102
diff
changeset
|
841 nh.startb = self.startb |
d8214e944b84
patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents:
10102
diff
changeset
|
842 nh.lena = self.lena |
d8214e944b84
patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents:
10102
diff
changeset
|
843 nh.lenb = self.lenb |
d8214e944b84
patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents:
10102
diff
changeset
|
844 return nh |
d8214e944b84
patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents:
10102
diff
changeset
|
845 |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
846 def read_unified_hunk(self, lr): |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
847 m = unidesc.match(self.desc) |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
848 if not m: |
4898
bc905a6c0e76
patch.py: fix some incorrect uses of _() for i18n
Bryan O'Sullivan <bos@serpentine.com>
parents:
4897
diff
changeset
|
849 raise PatchError(_("bad hunk #%d") % self.number) |
15510
5414b56cfad6
patch: simplify hunk extents parsing
Patrick Mezard <pmezard@gmail.com>
parents:
15462
diff
changeset
|
850 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
|
851 if self.lena is None: |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
852 self.lena = 1 |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
853 else: |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
854 self.lena = int(self.lena) |
8527
f9a80054dd3c
use 'x is None' instead of 'x == None'
Martin Geisler <mg@lazybytes.net>
parents:
8526
diff
changeset
|
855 if self.lenb is None: |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
856 self.lenb = 1 |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
857 else: |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
858 self.lenb = int(self.lenb) |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
859 self.starta = int(self.starta) |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
860 self.startb = int(self.startb) |
16683 | 861 diffhelpers.addlines(lr, self.hunk, self.lena, self.lenb, self.a, |
862 self.b) | |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
863 # 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
|
864 # 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
|
865 while len(self.hunk[-1]) == 0: |
6948
359e93ceee3a
fix double indentation and trailing whitespace
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6884
diff
changeset
|
866 del self.hunk[-1] |
359e93ceee3a
fix double indentation and trailing whitespace
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6884
diff
changeset
|
867 del self.a[-1] |
359e93ceee3a
fix double indentation and trailing whitespace
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6884
diff
changeset
|
868 del self.b[-1] |
359e93ceee3a
fix double indentation and trailing whitespace
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6884
diff
changeset
|
869 self.lena -= 1 |
359e93ceee3a
fix double indentation and trailing whitespace
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6884
diff
changeset
|
870 self.lenb -= 1 |
13699
d3c0e0033f13
patch: fix hunk newlines when parsing hunks, not in iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents:
13395
diff
changeset
|
871 self._fixnewline(lr) |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
872 |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
873 def read_context_hunk(self, lr): |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
874 self.desc = lr.readline() |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
875 m = contextdesc.match(self.desc) |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
876 if not m: |
4898
bc905a6c0e76
patch.py: fix some incorrect uses of _() for i18n
Bryan O'Sullivan <bos@serpentine.com>
parents:
4897
diff
changeset
|
877 raise PatchError(_("bad hunk #%d") % self.number) |
15510
5414b56cfad6
patch: simplify hunk extents parsing
Patrick Mezard <pmezard@gmail.com>
parents:
15462
diff
changeset
|
878 self.starta, aend = m.groups() |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
879 self.starta = int(self.starta) |
8527
f9a80054dd3c
use 'x is None' instead of 'x == None'
Martin Geisler <mg@lazybytes.net>
parents:
8526
diff
changeset
|
880 if aend is None: |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
881 aend = self.starta |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
882 self.lena = int(aend) - self.starta |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
883 if self.starta: |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
884 self.lena += 1 |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
885 for x in xrange(self.lena): |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
886 l = lr.readline() |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
887 if l.startswith('---'): |
12825
61f48581d8ef
Test applying context diffs
Patrick Mezard <pmezard@gmail.com>
parents:
12728
diff
changeset
|
888 # lines addition, old block is empty |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
889 lr.push(l) |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
890 break |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
891 s = l[2:] |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
892 if l.startswith('- ') or l.startswith('! '): |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
893 u = '-' + s |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
894 elif l.startswith(' '): |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
895 u = ' ' + s |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
896 else: |
4898
bc905a6c0e76
patch.py: fix some incorrect uses of _() for i18n
Bryan O'Sullivan <bos@serpentine.com>
parents:
4897
diff
changeset
|
897 raise PatchError(_("bad hunk #%d old text line %d") % |
bc905a6c0e76
patch.py: fix some incorrect uses of _() for i18n
Bryan O'Sullivan <bos@serpentine.com>
parents:
4897
diff
changeset
|
898 (self.number, x)) |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
899 self.a.append(u) |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
900 self.hunk.append(u) |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
901 |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
902 l = lr.readline() |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
903 if l.startswith('\ '): |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
904 s = self.a[-1][:-1] |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
905 self.a[-1] = s |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
906 self.hunk[-1] = s |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
907 l = lr.readline() |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
908 m = contextdesc.match(l) |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
909 if not m: |
4898
bc905a6c0e76
patch.py: fix some incorrect uses of _() for i18n
Bryan O'Sullivan <bos@serpentine.com>
parents:
4897
diff
changeset
|
910 raise PatchError(_("bad hunk #%d") % self.number) |
15510
5414b56cfad6
patch: simplify hunk extents parsing
Patrick Mezard <pmezard@gmail.com>
parents:
15462
diff
changeset
|
911 self.startb, bend = m.groups() |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
912 self.startb = int(self.startb) |
8527
f9a80054dd3c
use 'x is None' instead of 'x == None'
Martin Geisler <mg@lazybytes.net>
parents:
8526
diff
changeset
|
913 if bend is None: |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
914 bend = self.startb |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
915 self.lenb = int(bend) - self.startb |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
916 if self.startb: |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
917 self.lenb += 1 |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
918 hunki = 1 |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
919 for x in xrange(self.lenb): |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
920 l = lr.readline() |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
921 if l.startswith('\ '): |
12825
61f48581d8ef
Test applying context diffs
Patrick Mezard <pmezard@gmail.com>
parents:
12728
diff
changeset
|
922 # 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
|
923 # 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
|
924 # 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
|
925 s = self.b[-1][:-1] |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
926 self.b[-1] = s |
10282
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
927 self.hunk[hunki - 1] = s |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
928 continue |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
929 if not l: |
12825
61f48581d8ef
Test applying context diffs
Patrick Mezard <pmezard@gmail.com>
parents:
12728
diff
changeset
|
930 # 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
|
931 lr.push(l) |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
932 break |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
933 s = l[2:] |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
934 if l.startswith('+ ') or l.startswith('! '): |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
935 u = '+' + s |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
936 elif l.startswith(' '): |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
937 u = ' ' + s |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
938 elif len(self.b) == 0: |
12825
61f48581d8ef
Test applying context diffs
Patrick Mezard <pmezard@gmail.com>
parents:
12728
diff
changeset
|
939 # line deletions, new block is empty |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
940 lr.push(l) |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
941 break |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
942 else: |
4898
bc905a6c0e76
patch.py: fix some incorrect uses of _() for i18n
Bryan O'Sullivan <bos@serpentine.com>
parents:
4897
diff
changeset
|
943 raise PatchError(_("bad hunk #%d old text line %d") % |
bc905a6c0e76
patch.py: fix some incorrect uses of _() for i18n
Bryan O'Sullivan <bos@serpentine.com>
parents:
4897
diff
changeset
|
944 (self.number, x)) |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
945 self.b.append(s) |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
946 while True: |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
947 if hunki >= len(self.hunk): |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
948 h = "" |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
949 else: |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
950 h = self.hunk[hunki] |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
951 hunki += 1 |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
952 if h == u: |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
953 break |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
954 elif h.startswith('-'): |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
955 continue |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
956 else: |
10282
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
957 self.hunk.insert(hunki - 1, u) |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
958 break |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
959 |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
960 if not self.a: |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
961 # 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
|
962 for x in self.hunk: |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
963 if x.startswith('-') or x.startswith(' '): |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
964 self.a.append(x) |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
965 if not self.b: |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
966 # 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
|
967 for x in self.hunk: |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
968 if x.startswith('+') or x.startswith(' '): |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
969 self.b.append(x[1:]) |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
970 # @@ -start,len +start,len @@ |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
971 self.desc = "@@ -%d,%d +%d,%d @@\n" % (self.starta, self.lena, |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
972 self.startb, self.lenb) |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
973 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
|
974 self._fixnewline(lr) |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
975 |
13699
d3c0e0033f13
patch: fix hunk newlines when parsing hunks, not in iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents:
13395
diff
changeset
|
976 def _fixnewline(self, lr): |
d3c0e0033f13
patch: fix hunk newlines when parsing hunks, not in iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents:
13395
diff
changeset
|
977 l = lr.readline() |
d3c0e0033f13
patch: fix hunk newlines when parsing hunks, not in iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents:
13395
diff
changeset
|
978 if l.startswith('\ '): |
d3c0e0033f13
patch: fix hunk newlines when parsing hunks, not in iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents:
13395
diff
changeset
|
979 diffhelpers.fix_newline(self.hunk, self.a, self.b) |
d3c0e0033f13
patch: fix hunk newlines when parsing hunks, not in iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents:
13395
diff
changeset
|
980 else: |
d3c0e0033f13
patch: fix hunk newlines when parsing hunks, not in iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents:
13395
diff
changeset
|
981 lr.push(l) |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
982 |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
983 def complete(self): |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
984 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
|
985 |
16121
ccba74472af2
patch: fuzz old and new lines at the same time
Patrick Mezard <patrick@mezard.eu>
parents:
16112
diff
changeset
|
986 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
|
987 # 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
|
988 # 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
|
989 # 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
|
990 fuzz = min(fuzz, len(old)) |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
991 if fuzz: |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
992 top = 0 |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
993 bot = 0 |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
994 hlen = len(self.hunk) |
10282
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
995 for x in xrange(hlen - 1): |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
996 # the hunk starts with the @@ line, so use x+1 |
10282
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
997 if self.hunk[x + 1][0] == ' ': |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
998 top += 1 |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
999 else: |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1000 break |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1001 if not toponly: |
10282
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
1002 for x in xrange(hlen - 1): |
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
1003 if self.hunk[hlen - bot - 1][0] == ' ': |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1004 bot += 1 |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1005 else: |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1006 break |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1007 |
16124
0e0060bf2f44
patch: fuzz more aggressively to match patch(1) behaviour
Patrick Mezard <patrick@mezard.eu>
parents:
16123
diff
changeset
|
1008 bot = min(fuzz, bot) |
0e0060bf2f44
patch: fuzz more aggressively to match patch(1) behaviour
Patrick Mezard <patrick@mezard.eu>
parents:
16123
diff
changeset
|
1009 top = min(fuzz, top) |
16122
9ef3a4a2c6c0
patch: make hunk.fuzzit() compute the fuzzed start locations
Patrick Mezard <patrick@mezard.eu>
parents:
16121
diff
changeset
|
1010 return old[top:len(old)-bot], new[top:len(new)-bot], top |
9ef3a4a2c6c0
patch: make hunk.fuzzit() compute the fuzzed start locations
Patrick Mezard <patrick@mezard.eu>
parents:
16121
diff
changeset
|
1011 return old, new, 0 |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1012 |
16121
ccba74472af2
patch: fuzz old and new lines at the same time
Patrick Mezard <patrick@mezard.eu>
parents:
16112
diff
changeset
|
1013 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
|
1014 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
|
1015 oldstart = self.starta + top |
9ef3a4a2c6c0
patch: make hunk.fuzzit() compute the fuzzed start locations
Patrick Mezard <patrick@mezard.eu>
parents:
16121
diff
changeset
|
1016 newstart = self.startb + top |
9ef3a4a2c6c0
patch: make hunk.fuzzit() compute the fuzzed start locations
Patrick Mezard <patrick@mezard.eu>
parents:
16121
diff
changeset
|
1017 # 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
|
1018 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
|
1019 oldstart -= 1 |
16650
fcb97d9a26cd
patch: fix segfault against unified diffs which start line is zero
Yuya Nishihara <yuya@tcha.org>
parents:
16524
diff
changeset
|
1020 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
|
1021 newstart -= 1 |
9ef3a4a2c6c0
patch: make hunk.fuzzit() compute the fuzzed start locations
Patrick Mezard <patrick@mezard.eu>
parents:
16121
diff
changeset
|
1022 return old, oldstart, new, newstart |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1023 |
14764
a7d5816087a9
classes: fix class style problems found by b071cd58af50
Thomas Arendsen Hein <thomas@intevation.de>
parents:
14695
diff
changeset
|
1024 class binhunk(object): |
9585
ea1935e2020a
patch: handle symlinks without symlinkhunk
Patrick Mezard <pmezard@gmail.com>
parents:
9573
diff
changeset
|
1025 'A binary patch file. Only understands literals so far.' |
16523
727068417b95
patch: include file name in binary patch error messages
Patrick Mezard <patrick@mezard.eu>
parents:
16522
diff
changeset
|
1026 def __init__(self, lr, fname): |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1027 self.text = None |
9585
ea1935e2020a
patch: handle symlinks without symlinkhunk
Patrick Mezard <pmezard@gmail.com>
parents:
9573
diff
changeset
|
1028 self.hunk = ['GIT binary patch\n'] |
16523
727068417b95
patch: include file name in binary patch error messages
Patrick Mezard <patrick@mezard.eu>
parents:
16522
diff
changeset
|
1029 self._fname = fname |
14384
9d59c596eb9e
patch: construct and parse binary hunks at the same time
Patrick Mezard <pmezard@gmail.com>
parents:
14383
diff
changeset
|
1030 self._read(lr) |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1031 |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1032 def complete(self): |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1033 return self.text is not None |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1034 |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1035 def new(self): |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1036 return [self.text] |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1037 |
14384
9d59c596eb9e
patch: construct and parse binary hunks at the same time
Patrick Mezard <pmezard@gmail.com>
parents:
14383
diff
changeset
|
1038 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
|
1039 def getline(lr, hunk): |
ed6a74312176
patch: be more tolerant with EOLs in binary diffs (issue2870)
Patrick Mezard <patrick@mezard.eu>
parents:
16523
diff
changeset
|
1040 l = lr.readline() |
ed6a74312176
patch: be more tolerant with EOLs in binary diffs (issue2870)
Patrick Mezard <patrick@mezard.eu>
parents:
16523
diff
changeset
|
1041 hunk.append(l) |
ed6a74312176
patch: be more tolerant with EOLs in binary diffs (issue2870)
Patrick Mezard <patrick@mezard.eu>
parents:
16523
diff
changeset
|
1042 return l.rstrip('\r\n') |
ed6a74312176
patch: be more tolerant with EOLs in binary diffs (issue2870)
Patrick Mezard <patrick@mezard.eu>
parents:
16523
diff
changeset
|
1043 |
16567
aef3d0d4631c
patch: clarify binary hunk parsing loop
Patrick Mezard <patrick@mezard.eu>
parents:
16524
diff
changeset
|
1044 while True: |
16524
ed6a74312176
patch: be more tolerant with EOLs in binary diffs (issue2870)
Patrick Mezard <patrick@mezard.eu>
parents:
16523
diff
changeset
|
1045 line = getline(lr, self.hunk) |
16567
aef3d0d4631c
patch: clarify binary hunk parsing loop
Patrick Mezard <patrick@mezard.eu>
parents:
16524
diff
changeset
|
1046 if not line: |
aef3d0d4631c
patch: clarify binary hunk parsing loop
Patrick Mezard <patrick@mezard.eu>
parents:
16524
diff
changeset
|
1047 raise PatchError(_('could not extract "%s" binary data') |
aef3d0d4631c
patch: clarify binary hunk parsing loop
Patrick Mezard <patrick@mezard.eu>
parents:
16524
diff
changeset
|
1048 % self._fname) |
aef3d0d4631c
patch: clarify binary hunk parsing loop
Patrick Mezard <patrick@mezard.eu>
parents:
16524
diff
changeset
|
1049 if line.startswith('literal '): |
aef3d0d4631c
patch: clarify binary hunk parsing loop
Patrick Mezard <patrick@mezard.eu>
parents:
16524
diff
changeset
|
1050 break |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1051 size = int(line[8:].rstrip()) |
3367
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
1052 dec = [] |
16524
ed6a74312176
patch: be more tolerant with EOLs in binary diffs (issue2870)
Patrick Mezard <patrick@mezard.eu>
parents:
16523
diff
changeset
|
1053 line = getline(lr, self.hunk) |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1054 while len(line) > 1: |
3374
fd43ff3b4442
Use line length field when extracting git binary patches
Brendan Cully <brendan@kublai.com>
parents:
3367
diff
changeset
|
1055 l = line[0] |
fd43ff3b4442
Use line length field when extracting git binary patches
Brendan Cully <brendan@kublai.com>
parents:
3367
diff
changeset
|
1056 if l <= 'Z' and l >= 'A': |
fd43ff3b4442
Use line length field when extracting git binary patches
Brendan Cully <brendan@kublai.com>
parents:
3367
diff
changeset
|
1057 l = ord(l) - ord('A') + 1 |
fd43ff3b4442
Use line length field when extracting git binary patches
Brendan Cully <brendan@kublai.com>
parents:
3367
diff
changeset
|
1058 else: |
fd43ff3b4442
Use line length field when extracting git binary patches
Brendan Cully <brendan@kublai.com>
parents:
3367
diff
changeset
|
1059 l = ord(l) - ord('a') + 27 |
16522
a8065323c003
patch: display a nice error for invalid base85 data
Patrick Mezard <patrick@mezard.eu>
parents:
16506
diff
changeset
|
1060 try: |
16524
ed6a74312176
patch: be more tolerant with EOLs in binary diffs (issue2870)
Patrick Mezard <patrick@mezard.eu>
parents:
16523
diff
changeset
|
1061 dec.append(base85.b85decode(line[1:])[:l]) |
16522
a8065323c003
patch: display a nice error for invalid base85 data
Patrick Mezard <patrick@mezard.eu>
parents:
16506
diff
changeset
|
1062 except ValueError, e: |
16523
727068417b95
patch: include file name in binary patch error messages
Patrick Mezard <patrick@mezard.eu>
parents:
16522
diff
changeset
|
1063 raise PatchError(_('could not decode "%s" binary patch: %s') |
727068417b95
patch: include file name in binary patch error messages
Patrick Mezard <patrick@mezard.eu>
parents:
16522
diff
changeset
|
1064 % (self._fname, str(e))) |
16524
ed6a74312176
patch: be more tolerant with EOLs in binary diffs (issue2870)
Patrick Mezard <patrick@mezard.eu>
parents:
16523
diff
changeset
|
1065 line = getline(lr, self.hunk) |
3367
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
1066 text = zlib.decompress(''.join(dec)) |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
1067 if len(text) != size: |
16523
727068417b95
patch: include file name in binary patch error messages
Patrick Mezard <patrick@mezard.eu>
parents:
16522
diff
changeset
|
1068 raise PatchError(_('"%s" length is %d bytes, should be %d') |
727068417b95
patch: include file name in binary patch error messages
Patrick Mezard <patrick@mezard.eu>
parents:
16522
diff
changeset
|
1069 % (self._fname, len(text), size)) |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1070 self.text = text |
3367
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
1071 |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1072 def parsefilename(str): |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1073 # --- filename \t|space stuff |
5851
03f550f9b554
patch: remove CRLF when parsing file names
Patrick Mezard <pmezard@gmail.com>
parents:
5669
diff
changeset
|
1074 s = str[4:].rstrip('\r\n') |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1075 i = s.find('\t') |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1076 if i < 0: |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1077 i = s.find(' ') |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1078 if i < 0: |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1079 return s |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1080 return s[:i] |
2861
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
1081 |
11022
0429d0d49f92
patch: strip paths in leaked git patchmeta objects
Mads Kiilerich <mads@kiilerich.com>
parents:
11021
diff
changeset
|
1082 def pathstrip(path, strip): |
0429d0d49f92
patch: strip paths in leaked git patchmeta objects
Mads Kiilerich <mads@kiilerich.com>
parents:
11021
diff
changeset
|
1083 pathlen = len(path) |
0429d0d49f92
patch: strip paths in leaked git patchmeta objects
Mads Kiilerich <mads@kiilerich.com>
parents:
11021
diff
changeset
|
1084 i = 0 |
0429d0d49f92
patch: strip paths in leaked git patchmeta objects
Mads Kiilerich <mads@kiilerich.com>
parents:
11021
diff
changeset
|
1085 if strip == 0: |
0429d0d49f92
patch: strip paths in leaked git patchmeta objects
Mads Kiilerich <mads@kiilerich.com>
parents:
11021
diff
changeset
|
1086 return '', path.rstrip() |
0429d0d49f92
patch: strip paths in leaked git patchmeta objects
Mads Kiilerich <mads@kiilerich.com>
parents:
11021
diff
changeset
|
1087 count = strip |
0429d0d49f92
patch: strip paths in leaked git patchmeta objects
Mads Kiilerich <mads@kiilerich.com>
parents:
11021
diff
changeset
|
1088 while count > 0: |
0429d0d49f92
patch: strip paths in leaked git patchmeta objects
Mads Kiilerich <mads@kiilerich.com>
parents:
11021
diff
changeset
|
1089 i = path.find('/', i) |
0429d0d49f92
patch: strip paths in leaked git patchmeta objects
Mads Kiilerich <mads@kiilerich.com>
parents:
11021
diff
changeset
|
1090 if i == -1: |
0429d0d49f92
patch: strip paths in leaked git patchmeta objects
Mads Kiilerich <mads@kiilerich.com>
parents:
11021
diff
changeset
|
1091 raise PatchError(_("unable to strip away %d of %d dirs from %s") % |
0429d0d49f92
patch: strip paths in leaked git patchmeta objects
Mads Kiilerich <mads@kiilerich.com>
parents:
11021
diff
changeset
|
1092 (count, strip, path)) |
0429d0d49f92
patch: strip paths in leaked git patchmeta objects
Mads Kiilerich <mads@kiilerich.com>
parents:
11021
diff
changeset
|
1093 i += 1 |
0429d0d49f92
patch: strip paths in leaked git patchmeta objects
Mads Kiilerich <mads@kiilerich.com>
parents:
11021
diff
changeset
|
1094 # consume '//' in the path |
0429d0d49f92
patch: strip paths in leaked git patchmeta objects
Mads Kiilerich <mads@kiilerich.com>
parents:
11021
diff
changeset
|
1095 while i < pathlen - 1 and path[i] == '/': |
0429d0d49f92
patch: strip paths in leaked git patchmeta objects
Mads Kiilerich <mads@kiilerich.com>
parents:
11021
diff
changeset
|
1096 i += 1 |
0429d0d49f92
patch: strip paths in leaked git patchmeta objects
Mads Kiilerich <mads@kiilerich.com>
parents:
11021
diff
changeset
|
1097 count -= 1 |
0429d0d49f92
patch: strip paths in leaked git patchmeta objects
Mads Kiilerich <mads@kiilerich.com>
parents:
11021
diff
changeset
|
1098 return path[:i].lstrip(), path[i:].rstrip() |
0429d0d49f92
patch: strip paths in leaked git patchmeta objects
Mads Kiilerich <mads@kiilerich.com>
parents:
11021
diff
changeset
|
1099 |
14566
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
1100 def makepatchmeta(backend, afile_orig, bfile_orig, hunk, strip): |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1101 nulla = afile_orig == "/dev/null" |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1102 nullb = bfile_orig == "/dev/null" |
14451
c78d41db6f88
patch: refactor file creation/removal detection
Patrick Mezard <pmezard@gmail.com>
parents:
14437
diff
changeset
|
1103 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
|
1104 remove = nullb and hunk.startb == 0 and hunk.lenb == 0 |
6295
bace1990ab12
patch: fix corner case with update + copy patch handling (issue 937)
Patrick Mezard <pmezard@gmail.com>
parents:
6280
diff
changeset
|
1105 abase, afile = pathstrip(afile_orig, strip) |
14351
d54f9bbcc640
patch: add lexists() to backends, use it in selectfile()
Patrick Mezard <pmezard@gmail.com>
parents:
14350
diff
changeset
|
1106 gooda = not nulla and backend.exists(afile) |
6295
bace1990ab12
patch: fix corner case with update + copy patch handling (issue 937)
Patrick Mezard <pmezard@gmail.com>
parents:
6280
diff
changeset
|
1107 bbase, bfile = pathstrip(bfile_orig, strip) |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1108 if afile == bfile: |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1109 goodb = gooda |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1110 else: |
14351
d54f9bbcc640
patch: add lexists() to backends, use it in selectfile()
Patrick Mezard <pmezard@gmail.com>
parents:
14350
diff
changeset
|
1111 goodb = not nullb and backend.exists(bfile) |
14451
c78d41db6f88
patch: refactor file creation/removal detection
Patrick Mezard <pmezard@gmail.com>
parents:
14437
diff
changeset
|
1112 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
|
1113 |
11820
75de514a50f3
patch: fix typo in comment
Martin Geisler <mg@aragost.com>
parents:
11645
diff
changeset
|
1114 # 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
|
1115 # not /dev/null, but afile starts with bfile |
10745
d94832c4a31d
patch: try harder to find the file to patch on file creation (issue2041)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10736
diff
changeset
|
1116 abasedir = afile[:afile.rfind('/') + 1] |
d94832c4a31d
patch: try harder to find the file to patch on file creation (issue2041)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10736
diff
changeset
|
1117 bbasedir = bfile[:bfile.rfind('/') + 1] |
14451
c78d41db6f88
patch: refactor file creation/removal detection
Patrick Mezard <pmezard@gmail.com>
parents:
14437
diff
changeset
|
1118 if (missing and abasedir == bbasedir and afile.startswith(bfile) |
c78d41db6f88
patch: refactor file creation/removal detection
Patrick Mezard <pmezard@gmail.com>
parents:
14437
diff
changeset
|
1119 and hunk.starta == 0 and hunk.lena == 0): |
c78d41db6f88
patch: refactor file creation/removal detection
Patrick Mezard <pmezard@gmail.com>
parents:
14437
diff
changeset
|
1120 create = True |
c78d41db6f88
patch: refactor file creation/removal detection
Patrick Mezard <pmezard@gmail.com>
parents:
14437
diff
changeset
|
1121 missing = False |
9328
648d6a1a1cf2
patch: create file even if source is not /dev/null
Brendan Cully <brendan@kublai.com>
parents:
9248
diff
changeset
|
1122 |
6295
bace1990ab12
patch: fix corner case with update + copy patch handling (issue 937)
Patrick Mezard <pmezard@gmail.com>
parents:
6280
diff
changeset
|
1123 # 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
|
1124 # 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
|
1125 # file should be patched (see original mpatch code). |
bace1990ab12
patch: fix corner case with update + copy patch handling (issue 937)
Patrick Mezard <pmezard@gmail.com>
parents:
6280
diff
changeset
|
1126 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
|
1127 fname = None |
e90e72c6b4c7
patch: write rej files for missing targets (issue 853)
Patrick Mezard <pmezard@gmail.com>
parents:
5651
diff
changeset
|
1128 if not missing: |
e90e72c6b4c7
patch: write rej files for missing targets (issue 853)
Patrick Mezard <pmezard@gmail.com>
parents:
5651
diff
changeset
|
1129 if gooda and goodb: |
6295
bace1990ab12
patch: fix corner case with update + copy patch handling (issue 937)
Patrick Mezard <pmezard@gmail.com>
parents:
6280
diff
changeset
|
1130 fname = isbackup and afile or bfile |
5652
e90e72c6b4c7
patch: write rej files for missing targets (issue 853)
Patrick Mezard <pmezard@gmail.com>
parents:
5651
diff
changeset
|
1131 elif gooda: |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1132 fname = afile |
5760
0145f9afb0e7
Removed tabs and trailing whitespace in python files
Thomas Arendsen Hein <thomas@intevation.de>
parents:
5706
diff
changeset
|
1133 |
5652
e90e72c6b4c7
patch: write rej files for missing targets (issue 853)
Patrick Mezard <pmezard@gmail.com>
parents:
5651
diff
changeset
|
1134 if not fname: |
e90e72c6b4c7
patch: write rej files for missing targets (issue 853)
Patrick Mezard <pmezard@gmail.com>
parents:
5651
diff
changeset
|
1135 if not nullb: |
6295
bace1990ab12
patch: fix corner case with update + copy patch handling (issue 937)
Patrick Mezard <pmezard@gmail.com>
parents:
6280
diff
changeset
|
1136 fname = isbackup and afile or bfile |
5652
e90e72c6b4c7
patch: write rej files for missing targets (issue 853)
Patrick Mezard <pmezard@gmail.com>
parents:
5651
diff
changeset
|
1137 elif not nulla: |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1138 fname = afile |
5652
e90e72c6b4c7
patch: write rej files for missing targets (issue 853)
Patrick Mezard <pmezard@gmail.com>
parents:
5651
diff
changeset
|
1139 else: |
e90e72c6b4c7
patch: write rej files for missing targets (issue 853)
Patrick Mezard <pmezard@gmail.com>
parents:
5651
diff
changeset
|
1140 raise PatchError(_("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
|
1141 |
14566
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
1142 gp = patchmeta(fname) |
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
1143 if create: |
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
1144 gp.op = 'ADD' |
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
1145 elif remove: |
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
1146 gp.op = 'DELETE' |
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
1147 return gp |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1148 |
7152
f0055cec8446
patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents:
7151
diff
changeset
|
1149 def scangitpatch(lr, firstline): |
7186
f77c8d8331ca
clean up trailing spaces, leading spaces in C
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
7153
diff
changeset
|
1150 """ |
7152
f0055cec8446
patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents:
7151
diff
changeset
|
1151 Git patches can emit: |
f0055cec8446
patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents:
7151
diff
changeset
|
1152 - rename a to b |
f0055cec8446
patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents:
7151
diff
changeset
|
1153 - change b |
f0055cec8446
patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents:
7151
diff
changeset
|
1154 - copy a to c |
f0055cec8446
patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents:
7151
diff
changeset
|
1155 - change c |
7186
f77c8d8331ca
clean up trailing spaces, leading spaces in C
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
7153
diff
changeset
|
1156 |
7152
f0055cec8446
patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents:
7151
diff
changeset
|
1157 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
|
1158 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
|
1159 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
|
1160 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
|
1161 perform the copies ahead of time. |
f0055cec8446
patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents:
7151
diff
changeset
|
1162 """ |
f0055cec8446
patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents:
7151
diff
changeset
|
1163 pos = 0 |
f0055cec8446
patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents:
7151
diff
changeset
|
1164 try: |
f0055cec8446
patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents:
7151
diff
changeset
|
1165 pos = lr.fp.tell() |
f0055cec8446
patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents:
7151
diff
changeset
|
1166 fp = lr.fp |
f0055cec8446
patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents:
7151
diff
changeset
|
1167 except IOError: |
f0055cec8446
patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents:
7151
diff
changeset
|
1168 fp = cStringIO.StringIO(lr.fp.read()) |
14418
0174d1f79280
patch: remove EOL support from linereader class
Patrick Mezard <pmezard@gmail.com>
parents:
14402
diff
changeset
|
1169 gitlr = linereader(fp) |
7152
f0055cec8446
patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents:
7151
diff
changeset
|
1170 gitlr.push(firstline) |
12669
b0fa39c68370
patch: remove unused flags from readgitpatch()
Patrick Mezard <pmezard@gmail.com>
parents:
12645
diff
changeset
|
1171 gitpatches = readgitpatch(gitlr) |
7152
f0055cec8446
patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents:
7151
diff
changeset
|
1172 fp.seek(pos) |
12669
b0fa39c68370
patch: remove unused flags from readgitpatch()
Patrick Mezard <pmezard@gmail.com>
parents:
12645
diff
changeset
|
1173 return gitpatches |
7152
f0055cec8446
patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents:
7151
diff
changeset
|
1174 |
14240
28762bb767dc
patch: remove unused ui arg to iterhunks
Idan Kamara <idankk86@gmail.com>
parents:
14234
diff
changeset
|
1175 def iterhunks(fp): |
5650
5d3e2f918d65
patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents:
5649
diff
changeset
|
1176 """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
|
1177 - ("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
|
1178 - ("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
|
1179 "file" event. |
5d3e2f918d65
patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents:
5649
diff
changeset
|
1180 - ("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
|
1181 maps filenames to gitpatch records. Unique event. |
5d3e2f918d65
patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents:
5649
diff
changeset
|
1182 """ |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1183 afile = "" |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1184 bfile = "" |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1185 state = None |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1186 hunknum = 0 |
14017
19a7b48446e3
patch: remove redundant variable in iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents:
13971
diff
changeset
|
1187 emitfile = newfile = False |
14388
37c997d21752
patch: stop handling hunkless git blocks out of stream
Patrick Mezard <pmezard@gmail.com>
parents:
14387
diff
changeset
|
1188 gitpatches = None |
2861
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
1189 |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1190 # our states |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1191 BFILE = 1 |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1192 context = None |
10128
ea7c392f2b08
patch: drop eol normalization fast-path for 'lf' and 'crlf'
Patrick Mezard <pmezard@gmail.com>
parents:
10127
diff
changeset
|
1193 lr = linereader(fp) |
2861
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
1194 |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1195 while True: |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1196 x = lr.readline() |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1197 if not x: |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1198 break |
14383
1bd52cb12a55
patch: refactor iterhunks() regular and binary files emission
Patrick Mezard <pmezard@gmail.com>
parents:
14382
diff
changeset
|
1199 if state == BFILE and ( |
1bd52cb12a55
patch: refactor iterhunks() regular and binary files emission
Patrick Mezard <pmezard@gmail.com>
parents:
14382
diff
changeset
|
1200 (not context and x[0] == '@') |
1bd52cb12a55
patch: refactor iterhunks() regular and binary files emission
Patrick Mezard <pmezard@gmail.com>
parents:
14382
diff
changeset
|
1201 or (context is not False and x.startswith('***************')) |
1bd52cb12a55
patch: refactor iterhunks() regular and binary files emission
Patrick Mezard <pmezard@gmail.com>
parents:
14382
diff
changeset
|
1202 or x.startswith('GIT binary patch')): |
14388
37c997d21752
patch: stop handling hunkless git blocks out of stream
Patrick Mezard <pmezard@gmail.com>
parents:
14387
diff
changeset
|
1203 gp = None |
14534
ecc79816d31e
patch: fix patchmeta/hunk synchronization in iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents:
14533
diff
changeset
|
1204 if (gitpatches and |
16506
fc4e0fecf403
patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents:
16475
diff
changeset
|
1205 gitpatches[-1].ispatching(afile, bfile)): |
fc4e0fecf403
patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents:
16475
diff
changeset
|
1206 gp = gitpatches.pop() |
14383
1bd52cb12a55
patch: refactor iterhunks() regular and binary files emission
Patrick Mezard <pmezard@gmail.com>
parents:
14382
diff
changeset
|
1207 if x.startswith('GIT binary patch'): |
16523
727068417b95
patch: include file name in binary patch error messages
Patrick Mezard <patrick@mezard.eu>
parents:
16522
diff
changeset
|
1208 h = binhunk(lr, gp.path) |
14383
1bd52cb12a55
patch: refactor iterhunks() regular and binary files emission
Patrick Mezard <pmezard@gmail.com>
parents:
14382
diff
changeset
|
1209 else: |
1bd52cb12a55
patch: refactor iterhunks() regular and binary files emission
Patrick Mezard <pmezard@gmail.com>
parents:
14382
diff
changeset
|
1210 if context is None and x.startswith('***************'): |
1bd52cb12a55
patch: refactor iterhunks() regular and binary files emission
Patrick Mezard <pmezard@gmail.com>
parents:
14382
diff
changeset
|
1211 context = True |
14451
c78d41db6f88
patch: refactor file creation/removal detection
Patrick Mezard <pmezard@gmail.com>
parents:
14437
diff
changeset
|
1212 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
|
1213 hunknum += 1 |
5650
5d3e2f918d65
patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents:
5649
diff
changeset
|
1214 if emitfile: |
5d3e2f918d65
patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents:
5649
diff
changeset
|
1215 emitfile = False |
14566
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
1216 yield 'file', (afile, bfile, h, gp and gp.copy() or None) |
13699
d3c0e0033f13
patch: fix hunk newlines when parsing hunks, not in iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents:
13395
diff
changeset
|
1217 yield 'hunk', h |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1218 elif x.startswith('diff --git'): |
16524
ed6a74312176
patch: be more tolerant with EOLs in binary diffs (issue2870)
Patrick Mezard <patrick@mezard.eu>
parents:
16523
diff
changeset
|
1219 m = gitre.match(x.rstrip(' \r\n')) |
14387 | 1220 if not m: |
1221 continue | |
16506
fc4e0fecf403
patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents:
16475
diff
changeset
|
1222 if gitpatches is None: |
14387 | 1223 # scan whole input for git metadata |
16506
fc4e0fecf403
patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents:
16475
diff
changeset
|
1224 gitpatches = scangitpatch(lr, x) |
fc4e0fecf403
patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents:
16475
diff
changeset
|
1225 yield 'git', [g.copy() for g in gitpatches |
fc4e0fecf403
patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents:
16475
diff
changeset
|
1226 if g.op in ('COPY', 'RENAME')] |
14388
37c997d21752
patch: stop handling hunkless git blocks out of stream
Patrick Mezard <pmezard@gmail.com>
parents:
14387
diff
changeset
|
1227 gitpatches.reverse() |
14387 | 1228 afile = 'a/' + m.group(1) |
1229 bfile = 'b/' + m.group(2) | |
16506
fc4e0fecf403
patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents:
16475
diff
changeset
|
1230 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
|
1231 gp = gitpatches.pop() |
14566
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
1232 yield 'file', ('a/' + gp.path, 'b/' + gp.path, None, gp.copy()) |
16506
fc4e0fecf403
patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents:
16475
diff
changeset
|
1233 if not gitpatches: |
fc4e0fecf403
patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents:
16475
diff
changeset
|
1234 raise PatchError(_('failed to synchronize metadata for "%s"') |
fc4e0fecf403
patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents:
16475
diff
changeset
|
1235 % afile[2:]) |
fc4e0fecf403
patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents:
16475
diff
changeset
|
1236 gp = gitpatches[-1] |
14387 | 1237 newfile = True |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1238 elif x.startswith('---'): |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1239 # check for a unified diff |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1240 l2 = lr.readline() |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1241 if not l2.startswith('+++'): |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1242 lr.push(l2) |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1243 continue |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1244 newfile = True |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1245 context = False |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1246 afile = parsefilename(x) |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1247 bfile = parsefilename(l2) |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1248 elif x.startswith('***'): |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1249 # check for a context diff |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1250 l2 = lr.readline() |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1251 if not l2.startswith('---'): |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1252 lr.push(l2) |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1253 continue |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1254 l3 = lr.readline() |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1255 lr.push(l3) |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1256 if not l3.startswith("***************"): |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1257 lr.push(l2) |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1258 continue |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1259 newfile = True |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1260 context = True |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1261 afile = parsefilename(x) |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1262 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
|
1263 |
14017
19a7b48446e3
patch: remove redundant variable in iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents:
13971
diff
changeset
|
1264 if newfile: |
19a7b48446e3
patch: remove redundant variable in iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents:
13971
diff
changeset
|
1265 newfile = False |
5650
5d3e2f918d65
patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents:
5649
diff
changeset
|
1266 emitfile = True |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1267 state = BFILE |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1268 hunknum = 0 |
5650
5d3e2f918d65
patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents:
5649
diff
changeset
|
1269 |
14388
37c997d21752
patch: stop handling hunkless git blocks out of stream
Patrick Mezard <pmezard@gmail.com>
parents:
14387
diff
changeset
|
1270 while gitpatches: |
16506
fc4e0fecf403
patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents:
16475
diff
changeset
|
1271 gp = gitpatches.pop() |
14566
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
1272 yield 'file', ('a/' + gp.path, '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
|
1273 |
14565
3cacc232f27f
patch: stop updating changed files set in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14564
diff
changeset
|
1274 def applydiff(ui, fp, backend, store, strip=1, eolmode='strict'): |
10966
91c58cf54eee
patch: refactor applydiff to allow for mempatching
Augie Fackler <durin42@gmail.com>
parents:
10965
diff
changeset
|
1275 """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
|
1276 |
14565
3cacc232f27f
patch: stop updating changed files set in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14564
diff
changeset
|
1277 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
|
1278 there was any fuzz. |
8810
ac92775b3b80
Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents:
8778
diff
changeset
|
1279 |
10101
155fe35534d3
patch: propagate eolmode down to patchfile
Martin Geisler <mg@lazybytes.net>
parents:
9725
diff
changeset
|
1280 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
|
1281 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
|
1282 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
|
1283 """ |
14565
3cacc232f27f
patch: stop updating changed files set in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14564
diff
changeset
|
1284 return _applydiff(ui, fp, patchfile, backend, store, strip=strip, |
12916
cfedc529e4a1
patch: remove unused applydiff() sourcefile argument
Patrick Mezard <pmezard@gmail.com>
parents:
12915
diff
changeset
|
1285 eolmode=eolmode) |
10966
91c58cf54eee
patch: refactor applydiff to allow for mempatching
Augie Fackler <durin42@gmail.com>
parents:
10965
diff
changeset
|
1286 |
14565
3cacc232f27f
patch: stop updating changed files set in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14564
diff
changeset
|
1287 def _applydiff(ui, fp, patcher, backend, store, strip=1, |
14452
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
1288 eolmode='strict'): |
14389
909ac6b9636b
patch: stop modifying gitpatch objects
Patrick Mezard <pmezard@gmail.com>
parents:
14388
diff
changeset
|
1289 |
909ac6b9636b
patch: stop modifying gitpatch objects
Patrick Mezard <pmezard@gmail.com>
parents:
14388
diff
changeset
|
1290 def pstrip(p): |
909ac6b9636b
patch: stop modifying gitpatch objects
Patrick Mezard <pmezard@gmail.com>
parents:
14388
diff
changeset
|
1291 return pathstrip(p, strip - 1)[1] |
909ac6b9636b
patch: stop modifying gitpatch objects
Patrick Mezard <pmezard@gmail.com>
parents:
14388
diff
changeset
|
1292 |
5650
5d3e2f918d65
patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents:
5649
diff
changeset
|
1293 rejects = 0 |
5d3e2f918d65
patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents:
5649
diff
changeset
|
1294 err = 0 |
5d3e2f918d65
patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents:
5649
diff
changeset
|
1295 current_file = None |
5d3e2f918d65
patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents:
5649
diff
changeset
|
1296 |
14240
28762bb767dc
patch: remove unused ui arg to iterhunks
Idan Kamara <idankk86@gmail.com>
parents:
14234
diff
changeset
|
1297 for state, values in iterhunks(fp): |
5650
5d3e2f918d65
patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents:
5649
diff
changeset
|
1298 if state == 'hunk': |
5d3e2f918d65
patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents:
5649
diff
changeset
|
1299 if not current_file: |
5d3e2f918d65
patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents:
5649
diff
changeset
|
1300 continue |
11021
c47a1cfad572
patch: minor cleanup of _applydiff
Mads Kiilerich <mads@kiilerich.com>
parents:
11020
diff
changeset
|
1301 ret = current_file.apply(values) |
14565
3cacc232f27f
patch: stop updating changed files set in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14564
diff
changeset
|
1302 if ret > 0: |
3cacc232f27f
patch: stop updating changed files set in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14564
diff
changeset
|
1303 err = 1 |
5650
5d3e2f918d65
patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents:
5649
diff
changeset
|
1304 elif state == 'file': |
13701
bc38ff7cb919
patch: move closefile() into patchfile.close()
Patrick Mezard <pmezard@gmail.com>
parents:
13700
diff
changeset
|
1305 if current_file: |
bc38ff7cb919
patch: move closefile() into patchfile.close()
Patrick Mezard <pmezard@gmail.com>
parents:
13700
diff
changeset
|
1306 rejects += current_file.close() |
14388
37c997d21752
patch: stop handling hunkless git blocks out of stream
Patrick Mezard <pmezard@gmail.com>
parents:
14387
diff
changeset
|
1307 current_file = None |
37c997d21752
patch: stop handling hunkless git blocks out of stream
Patrick Mezard <pmezard@gmail.com>
parents:
14387
diff
changeset
|
1308 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
|
1309 if gp: |
14566
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
1310 gp.path = pstrip(gp.path) |
14452
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
1311 if gp.oldpath: |
14566
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
1312 gp.oldpath = pstrip(gp.oldpath) |
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
1313 else: |
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
1314 gp = makepatchmeta(backend, afile, bfile, first_hunk, strip) |
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
1315 if gp.op == 'RENAME': |
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
1316 backend.unlink(gp.oldpath) |
14388
37c997d21752
patch: stop handling hunkless git blocks out of stream
Patrick Mezard <pmezard@gmail.com>
parents:
14387
diff
changeset
|
1317 if not first_hunk: |
14566
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
1318 if gp.op == 'DELETE': |
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
1319 backend.unlink(gp.path) |
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
1320 continue |
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
1321 data, mode = None, None |
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
1322 if gp.op in ('RENAME', 'COPY'): |
14609
f53dc0787424
patch: extend filtestore to store an optional copy source
Patrick Mezard <pmezard@gmail.com>
parents:
14566
diff
changeset
|
1323 data, mode = store.getfile(gp.oldpath)[:2] |
14566
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
1324 if gp.mode: |
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
1325 mode = gp.mode |
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
1326 if gp.op == 'ADD': |
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
1327 # 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
|
1328 # must be created |
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
1329 data = '' |
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
1330 if data or mode: |
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
1331 if (gp.op in ('ADD', 'RENAME', 'COPY') |
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
1332 and backend.exists(gp.path)): |
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
1333 raise PatchError(_("cannot create %s: destination " |
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
1334 "already exists") % gp.path) |
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
1335 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
|
1336 continue |
5650
5d3e2f918d65
patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents:
5649
diff
changeset
|
1337 try: |
14566
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
1338 current_file = patcher(ui, gp, backend, store, |
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
1339 eolmode=eolmode) |
14218
202ff575d49b
patch: fix clash between local variable and exception instance
Martin Geisler <mg@aragost.com>
parents:
14217
diff
changeset
|
1340 except PatchError, inst: |
202ff575d49b
patch: fix clash between local variable and exception instance
Martin Geisler <mg@aragost.com>
parents:
14217
diff
changeset
|
1341 ui.warn(str(inst) + '\n') |
11021
c47a1cfad572
patch: minor cleanup of _applydiff
Mads Kiilerich <mads@kiilerich.com>
parents:
11020
diff
changeset
|
1342 current_file = None |
5650
5d3e2f918d65
patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents:
5649
diff
changeset
|
1343 rejects += 1 |
5d3e2f918d65
patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents:
5649
diff
changeset
|
1344 continue |
5d3e2f918d65
patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents:
5649
diff
changeset
|
1345 elif state == 'git': |
11021
c47a1cfad572
patch: minor cleanup of _applydiff
Mads Kiilerich <mads@kiilerich.com>
parents:
11020
diff
changeset
|
1346 for gp in values: |
14452
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
1347 path = pstrip(gp.oldpath) |
16813
6d42c797ca6e
patch: keep patching after missing copy source (issue3480)
Patrick Mezard <patrick@mezard.eu>
parents:
16650
diff
changeset
|
1348 try: |
6d42c797ca6e
patch: keep patching after missing copy source (issue3480)
Patrick Mezard <patrick@mezard.eu>
parents:
16650
diff
changeset
|
1349 data, mode = backend.getfile(path) |
6d42c797ca6e
patch: keep patching after missing copy source (issue3480)
Patrick Mezard <patrick@mezard.eu>
parents:
16650
diff
changeset
|
1350 except IOError, e: |
6d42c797ca6e
patch: keep patching after missing copy source (issue3480)
Patrick Mezard <patrick@mezard.eu>
parents:
16650
diff
changeset
|
1351 if e.errno != errno.ENOENT: |
6d42c797ca6e
patch: keep patching after missing copy source (issue3480)
Patrick Mezard <patrick@mezard.eu>
parents:
16650
diff
changeset
|
1352 raise |
6d42c797ca6e
patch: keep patching after missing copy source (issue3480)
Patrick Mezard <patrick@mezard.eu>
parents:
16650
diff
changeset
|
1353 # 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
|
1354 # 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
|
1355 # 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
|
1356 # process. |
6d42c797ca6e
patch: keep patching after missing copy source (issue3480)
Patrick Mezard <patrick@mezard.eu>
parents:
16650
diff
changeset
|
1357 else: |
6d42c797ca6e
patch: keep patching after missing copy source (issue3480)
Patrick Mezard <patrick@mezard.eu>
parents:
16650
diff
changeset
|
1358 store.setfile(path, data, mode) |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1359 else: |
5650
5d3e2f918d65
patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents:
5649
diff
changeset
|
1360 raise util.Abort(_('unsupported parser state: %s') % state) |
5649
a583117b536a
patch: move NoHunk detection up with parsing code
Patrick Mezard <pmezard@gmail.com>
parents:
5581
diff
changeset
|
1361 |
13701
bc38ff7cb919
patch: move closefile() into patchfile.close()
Patrick Mezard <pmezard@gmail.com>
parents:
13700
diff
changeset
|
1362 if current_file: |
bc38ff7cb919
patch: move closefile() into patchfile.close()
Patrick Mezard <pmezard@gmail.com>
parents:
13700
diff
changeset
|
1363 rejects += current_file.close() |
5650
5d3e2f918d65
patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents:
5649
diff
changeset
|
1364 |
4897
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1365 if rejects: |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1366 return -1 |
4574925db5c0
Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4778
diff
changeset
|
1367 return err |
2874
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
1368 |
14382
2d16f15da7bd
patch: remove patch.patch() cwd argument
Patrick Mezard <pmezard@gmail.com>
parents:
14381
diff
changeset
|
1369 def _externalpatch(ui, repo, patcher, patchname, strip, files, |
14381
d4192500586a
patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents:
14370
diff
changeset
|
1370 similarity): |
7151
b5bc5293021c
patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents:
7150
diff
changeset
|
1371 """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
|
1372 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
|
1373 |
b5bc5293021c
patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents:
7150
diff
changeset
|
1374 fuzz = False |
12673
9ad16d1bce4b
patch: simplify externalpatch() arguments
Patrick Mezard <pmezard@gmail.com>
parents:
12671
diff
changeset
|
1375 args = [] |
14382
2d16f15da7bd
patch: remove patch.patch() cwd argument
Patrick Mezard <pmezard@gmail.com>
parents:
14381
diff
changeset
|
1376 cwd = repo.root |
7151
b5bc5293021c
patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents:
7150
diff
changeset
|
1377 if cwd: |
b5bc5293021c
patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents:
7150
diff
changeset
|
1378 args.append('-d %s' % util.shellquote(cwd)) |
b5bc5293021c
patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents:
7150
diff
changeset
|
1379 fp = util.popen('%s %s -p%d < %s' % (patcher, ' '.join(args), strip, |
b5bc5293021c
patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents:
7150
diff
changeset
|
1380 util.shellquote(patchname))) |
14381
d4192500586a
patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents:
14370
diff
changeset
|
1381 try: |
d4192500586a
patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents:
14370
diff
changeset
|
1382 for line in fp: |
d4192500586a
patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents:
14370
diff
changeset
|
1383 line = line.rstrip() |
d4192500586a
patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents:
14370
diff
changeset
|
1384 ui.note(line + '\n') |
d4192500586a
patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents:
14370
diff
changeset
|
1385 if line.startswith('patching file '): |
d4192500586a
patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents:
14370
diff
changeset
|
1386 pf = util.parsepatchoutput(line) |
d4192500586a
patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents:
14370
diff
changeset
|
1387 printed_file = False |
14564
65f4512e40e4
patch: turn patch() touched files dict into a set
Patrick Mezard <pmezard@gmail.com>
parents:
14535
diff
changeset
|
1388 files.add(pf) |
14381
d4192500586a
patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents:
14370
diff
changeset
|
1389 elif line.find('with fuzz') >= 0: |
d4192500586a
patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents:
14370
diff
changeset
|
1390 fuzz = True |
d4192500586a
patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents:
14370
diff
changeset
|
1391 if not printed_file: |
d4192500586a
patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents:
14370
diff
changeset
|
1392 ui.warn(pf + '\n') |
d4192500586a
patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents:
14370
diff
changeset
|
1393 printed_file = True |
d4192500586a
patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents:
14370
diff
changeset
|
1394 ui.warn(line + '\n') |
d4192500586a
patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents:
14370
diff
changeset
|
1395 elif line.find('saving rejects to file') >= 0: |
d4192500586a
patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents:
14370
diff
changeset
|
1396 ui.warn(line + '\n') |
d4192500586a
patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents:
14370
diff
changeset
|
1397 elif line.find('FAILED') >= 0: |
d4192500586a
patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents:
14370
diff
changeset
|
1398 if not printed_file: |
d4192500586a
patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents:
14370
diff
changeset
|
1399 ui.warn(pf + '\n') |
d4192500586a
patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents:
14370
diff
changeset
|
1400 printed_file = True |
d4192500586a
patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents:
14370
diff
changeset
|
1401 ui.warn(line + '\n') |
d4192500586a
patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents:
14370
diff
changeset
|
1402 finally: |
d4192500586a
patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents:
14370
diff
changeset
|
1403 if files: |
d4192500586a
patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents:
14370
diff
changeset
|
1404 cfiles = list(files) |
d4192500586a
patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents:
14370
diff
changeset
|
1405 cwd = repo.getcwd() |
d4192500586a
patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents:
14370
diff
changeset
|
1406 if cwd: |
d4192500586a
patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents:
14370
diff
changeset
|
1407 cfiles = [util.pathto(repo.root, cwd, f) |
14695
e4d3370fa234
patch: fix typo in variable name
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
14658
diff
changeset
|
1408 for f in cfiles] |
14381
d4192500586a
patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents:
14370
diff
changeset
|
1409 scmutil.addremove(repo, cfiles, similarity=similarity) |
7151
b5bc5293021c
patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents:
7150
diff
changeset
|
1410 code = fp.close() |
b5bc5293021c
patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents:
7150
diff
changeset
|
1411 if code: |
b5bc5293021c
patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents:
7150
diff
changeset
|
1412 raise PatchError(_("patch command failed: %s") % |
14234
600e64004eb5
rename explain_exit to explainexit
Adrian Buehlmann <adrian@cadifra.com>
parents:
14231
diff
changeset
|
1413 util.explainexit(code)[0]) |
7151
b5bc5293021c
patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents:
7150
diff
changeset
|
1414 return fuzz |
b5bc5293021c
patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents:
7150
diff
changeset
|
1415 |
14611
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
1416 def patchbackend(ui, backend, patchobj, strip, files=None, eolmode='strict'): |
9683
5c8651e2f5e0
patch: don't use mutable object as default argument
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
9682
diff
changeset
|
1417 if files is None: |
14564
65f4512e40e4
patch: turn patch() touched files dict into a set
Patrick Mezard <pmezard@gmail.com>
parents:
14535
diff
changeset
|
1418 files = set() |
8810
ac92775b3b80
Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents:
8778
diff
changeset
|
1419 if eolmode is None: |
ac92775b3b80
Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents:
8778
diff
changeset
|
1420 eolmode = ui.config('patch', 'eol', 'strict') |
10101
155fe35534d3
patch: propagate eolmode down to patchfile
Martin Geisler <mg@lazybytes.net>
parents:
9725
diff
changeset
|
1421 if eolmode.lower() not in eolmodes: |
12067
a4fbbe0fbc38
Lowercase error messages
Martin Geisler <mg@lazybytes.net>
parents:
11645
diff
changeset
|
1422 raise util.Abort(_('unsupported line endings type: %s') % eolmode) |
10101
155fe35534d3
patch: propagate eolmode down to patchfile
Martin Geisler <mg@lazybytes.net>
parents:
9725
diff
changeset
|
1423 eolmode = eolmode.lower() |
8843
eb7b247a98ea
kill trailing whitespace
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8817
diff
changeset
|
1424 |
14452
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
1425 store = filestore() |
7151
b5bc5293021c
patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents:
7150
diff
changeset
|
1426 try: |
9031
3b76321aa0de
compat: use open() instead of file() everywhere
Alejandro Santos <alejolp@alejolp.com>
parents:
9029
diff
changeset
|
1427 fp = open(patchobj, 'rb') |
7151
b5bc5293021c
patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents:
7150
diff
changeset
|
1428 except TypeError: |
b5bc5293021c
patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents:
7150
diff
changeset
|
1429 fp = patchobj |
b5bc5293021c
patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents:
7150
diff
changeset
|
1430 try: |
14565
3cacc232f27f
patch: stop updating changed files set in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14564
diff
changeset
|
1431 ret = applydiff(ui, fp, backend, store, strip=strip, |
14452
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
1432 eolmode=eolmode) |
7151
b5bc5293021c
patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents:
7150
diff
changeset
|
1433 finally: |
10203
6e26e3c2083f
patch: explicitely close input patch files when leaving
Patrick Mezard <pmezard@gmail.com>
parents:
10135
diff
changeset
|
1434 if fp != patchobj: |
6e26e3c2083f
patch: explicitely close input patch files when leaving
Patrick Mezard <pmezard@gmail.com>
parents:
10135
diff
changeset
|
1435 fp.close() |
14564
65f4512e40e4
patch: turn patch() touched files dict into a set
Patrick Mezard <pmezard@gmail.com>
parents:
14535
diff
changeset
|
1436 files.update(backend.close()) |
14452
ee574cfd0c32
patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents:
14451
diff
changeset
|
1437 store.close() |
7151
b5bc5293021c
patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents:
7150
diff
changeset
|
1438 if ret < 0: |
12674
aa2fe1f52ff4
patch: always raise PatchError with a message, simplify handling
Patrick Mezard <pmezard@gmail.com>
parents:
12673
diff
changeset
|
1439 raise PatchError(_('patch failed to apply')) |
7151
b5bc5293021c
patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents:
7150
diff
changeset
|
1440 return ret > 0 |
b5bc5293021c
patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents:
7150
diff
changeset
|
1441 |
14611
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
1442 def internalpatch(ui, repo, patchobj, strip, files=None, eolmode='strict', |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
1443 similarity=0): |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
1444 """use builtin patch to apply <patchobj> to the working directory. |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
1445 returns whether patch was applied with fuzz factor.""" |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
1446 backend = workingbackend(ui, repo, similarity) |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
1447 return patchbackend(ui, backend, patchobj, strip, files, eolmode) |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
1448 |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
1449 def patchrepo(ui, repo, ctx, store, patchobj, strip, files=None, |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
1450 eolmode='strict'): |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
1451 backend = repobackend(ui, repo, ctx, store) |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
1452 return patchbackend(ui, backend, patchobj, strip, files, eolmode) |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
1453 |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
1454 def makememctx(repo, parents, text, user, date, branch, files, store, |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
1455 editor=None): |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
1456 def getfilectx(repo, memctx, path): |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
1457 data, (islink, isexec), copied = store.getfile(path) |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
1458 return context.memfilectx(path, data, islink=islink, isexec=isexec, |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
1459 copied=copied) |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
1460 extra = {} |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
1461 if branch: |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
1462 extra['branch'] = encoding.fromlocal(branch) |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
1463 ctx = context.memctx(repo, parents, text, files, getfilectx, user, |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
1464 date, extra) |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
1465 if editor: |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
1466 ctx._text = editor(repo, ctx, []) |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
1467 return ctx |
adbf5e7df96d
import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents:
14609
diff
changeset
|
1468 |
14382
2d16f15da7bd
patch: remove patch.patch() cwd argument
Patrick Mezard <pmezard@gmail.com>
parents:
14381
diff
changeset
|
1469 def patch(ui, repo, patchname, strip=1, files=None, eolmode='strict', |
14260
00a881581400
patch: make patch()/internalpatch() always update the dirstate
Patrick Mezard <pmezard@gmail.com>
parents:
14259
diff
changeset
|
1470 similarity=0): |
8810
ac92775b3b80
Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents:
8778
diff
changeset
|
1471 """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
|
1472 |
ac92775b3b80
Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents:
8778
diff
changeset
|
1473 '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
|
1474 - '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
|
1475 - '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
|
1476 - '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
|
1477 - 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
|
1478 '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
|
1479 |
ac92775b3b80
Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents:
8778
diff
changeset
|
1480 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
|
1481 """ |
7151
b5bc5293021c
patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents:
7150
diff
changeset
|
1482 patcher = ui.config('ui', 'patch') |
9683
5c8651e2f5e0
patch: don't use mutable object as default argument
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
9682
diff
changeset
|
1483 if files is None: |
14564
65f4512e40e4
patch: turn patch() touched files dict into a set
Patrick Mezard <pmezard@gmail.com>
parents:
14535
diff
changeset
|
1484 files = set() |
7151
b5bc5293021c
patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents:
7150
diff
changeset
|
1485 try: |
b5bc5293021c
patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents:
7150
diff
changeset
|
1486 if patcher: |
14381
d4192500586a
patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents:
14370
diff
changeset
|
1487 return _externalpatch(ui, repo, patcher, patchname, strip, |
14382
2d16f15da7bd
patch: remove patch.patch() cwd argument
Patrick Mezard <pmezard@gmail.com>
parents:
14381
diff
changeset
|
1488 files, similarity) |
14370
17cea10c343e
patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents:
14369
diff
changeset
|
1489 return internalpatch(ui, repo, patchname, strip, files, eolmode, |
14260
00a881581400
patch: make patch()/internalpatch() always update the dirstate
Patrick Mezard <pmezard@gmail.com>
parents:
14259
diff
changeset
|
1490 similarity) |
7151
b5bc5293021c
patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents:
7150
diff
changeset
|
1491 except PatchError, err: |
12674
aa2fe1f52ff4
patch: always raise PatchError with a message, simplify handling
Patrick Mezard <pmezard@gmail.com>
parents:
12673
diff
changeset
|
1492 raise util.Abort(str(err)) |
7151
b5bc5293021c
patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents:
7150
diff
changeset
|
1493 |
14351
d54f9bbcc640
patch: add lexists() to backends, use it in selectfile()
Patrick Mezard <pmezard@gmail.com>
parents:
14350
diff
changeset
|
1494 def changedfiles(ui, repo, patchpath, strip=1): |
d54f9bbcc640
patch: add lexists() to backends, use it in selectfile()
Patrick Mezard <pmezard@gmail.com>
parents:
14350
diff
changeset
|
1495 backend = fsbackend(ui, repo.root) |
14255
576256a81cb6
patch: introduce changedfiles
Idan Kamara <idankk86@gmail.com>
parents:
14240
diff
changeset
|
1496 fp = open(patchpath, 'rb') |
576256a81cb6
patch: introduce changedfiles
Idan Kamara <idankk86@gmail.com>
parents:
14240
diff
changeset
|
1497 try: |
576256a81cb6
patch: introduce changedfiles
Idan Kamara <idankk86@gmail.com>
parents:
14240
diff
changeset
|
1498 changed = set() |
576256a81cb6
patch: introduce changedfiles
Idan Kamara <idankk86@gmail.com>
parents:
14240
diff
changeset
|
1499 for state, values in iterhunks(fp): |
14389
909ac6b9636b
patch: stop modifying gitpatch objects
Patrick Mezard <pmezard@gmail.com>
parents:
14388
diff
changeset
|
1500 if state == 'file': |
14388
37c997d21752
patch: stop handling hunkless git blocks out of stream
Patrick Mezard <pmezard@gmail.com>
parents:
14387
diff
changeset
|
1501 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
|
1502 if gp: |
14566
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
1503 gp.path = pathstrip(gp.path, strip - 1)[1] |
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
1504 if gp.oldpath: |
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
1505 gp.oldpath = pathstrip(gp.oldpath, strip - 1)[1] |
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
1506 else: |
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
1507 gp = makepatchmeta(backend, afile, bfile, first_hunk, strip) |
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
1508 changed.add(gp.path) |
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
1509 if gp.op == 'RENAME': |
d0c2cc11e611
patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents:
14565
diff
changeset
|
1510 changed.add(gp.oldpath) |
14389
909ac6b9636b
patch: stop modifying gitpatch objects
Patrick Mezard <pmezard@gmail.com>
parents:
14388
diff
changeset
|
1511 elif state not in ('hunk', 'git'): |
14255
576256a81cb6
patch: introduce changedfiles
Idan Kamara <idankk86@gmail.com>
parents:
14240
diff
changeset
|
1512 raise util.Abort(_('unsupported parser state: %s') % state) |
576256a81cb6
patch: introduce changedfiles
Idan Kamara <idankk86@gmail.com>
parents:
14240
diff
changeset
|
1513 return changed |
576256a81cb6
patch: introduce changedfiles
Idan Kamara <idankk86@gmail.com>
parents:
14240
diff
changeset
|
1514 finally: |
576256a81cb6
patch: introduce changedfiles
Idan Kamara <idankk86@gmail.com>
parents:
14240
diff
changeset
|
1515 fp.close() |
576256a81cb6
patch: introduce changedfiles
Idan Kamara <idankk86@gmail.com>
parents:
14240
diff
changeset
|
1516 |
5033
1b07668b8cc3
patch: remove unused parameter from b85diff
Bryan O'Sullivan <bos@serpentine.com>
parents:
4965
diff
changeset
|
1517 def b85diff(to, tn): |
3367
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
1518 '''print base85-encoded binary diff''' |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
1519 def gitindex(text): |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
1520 if not text: |
12144
be9c4131a8f4
clone, patch, convert: use hex(nullid) instead of '0'*40
Martin Geisler <mg@lazybytes.net>
parents:
12070
diff
changeset
|
1521 return hex(nullid) |
3367
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
1522 l = len(text) |
6470
ac0bcd951c2c
python 2.6 compatibility: compatibility wrappers for hash functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6467
diff
changeset
|
1523 s = util.sha1('blob %d\0' % l) |
3367
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
1524 s.update(text) |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
1525 return s.hexdigest() |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
1526 |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
1527 def fmtline(line): |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
1528 l = len(line) |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
1529 if l <= 26: |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
1530 l = chr(ord('A') + l - 1) |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
1531 else: |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
1532 l = chr(l - 26 + ord('a') - 1) |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
1533 return '%c%s\n' % (l, base85.b85encode(line, True)) |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
1534 |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
1535 def chunk(text, csize=52): |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
1536 l = len(text) |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
1537 i = 0 |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
1538 while i < l: |
10282
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
1539 yield text[i:i + csize] |
3367
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
1540 i += csize |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
1541 |
4105
ed46895aa38c
git binary patches: use hashes to detect identical files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4092
diff
changeset
|
1542 tohash = gitindex(to) |
ed46895aa38c
git binary patches: use hashes to detect identical files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4092
diff
changeset
|
1543 tnhash = gitindex(tn) |
ed46895aa38c
git binary patches: use hashes to detect identical files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4092
diff
changeset
|
1544 if tohash == tnhash: |
4106
797dbdd4d7e1
git binary patches: don't print the header for identical files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4105
diff
changeset
|
1545 return "" |
797dbdd4d7e1
git binary patches: don't print the header for identical files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4105
diff
changeset
|
1546 |
3367
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
1547 # TODO: deltas |
4106
797dbdd4d7e1
git binary patches: don't print the header for identical files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4105
diff
changeset
|
1548 ret = ['index %s..%s\nGIT binary patch\nliteral %s\n' % |
797dbdd4d7e1
git binary patches: don't print the header for identical files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4105
diff
changeset
|
1549 (tohash, tnhash, len(tn))] |
797dbdd4d7e1
git binary patches: don't print the header for identical files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4105
diff
changeset
|
1550 for l in chunk(zlib.compress(tn)): |
797dbdd4d7e1
git binary patches: don't print the header for identical files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4105
diff
changeset
|
1551 ret.append(fmtline(l)) |
797dbdd4d7e1
git binary patches: don't print the header for identical files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4105
diff
changeset
|
1552 ret.append('\n') |
797dbdd4d7e1
git binary patches: don't print the header for identical files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4105
diff
changeset
|
1553 return ''.join(ret) |
3367
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
1554 |
10189
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1555 class GitDiffRequired(Exception): |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1556 pass |
7198
df79ee9b6278
patch: extract local function addmodehdr
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
7186
diff
changeset
|
1557 |
15528
a84698badf0b
annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents:
15510
diff
changeset
|
1558 def diffopts(ui, opts=None, untrusted=False, section='diff'): |
10615
3bb438ce4458
patch/diff: move diff related code next to each other
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10611
diff
changeset
|
1559 def get(key, name=None, getter=ui.configbool): |
3bb438ce4458
patch/diff: move diff related code next to each other
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10611
diff
changeset
|
1560 return ((opts and opts.get(key)) or |
15528
a84698badf0b
annotate: support diff whitespace filtering flags (issue3030)
Patrick Mezard <pmezard@gmail.com>
parents:
15510
diff
changeset
|
1561 getter(section, name or key, None, untrusted=untrusted)) |
10615
3bb438ce4458
patch/diff: move diff related code next to each other
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10611
diff
changeset
|
1562 return mdiff.diffopts( |
3bb438ce4458
patch/diff: move diff related code next to each other
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10611
diff
changeset
|
1563 text=opts and opts.get('text'), |
3bb438ce4458
patch/diff: move diff related code next to each other
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10611
diff
changeset
|
1564 git=get('git'), |
3bb438ce4458
patch/diff: move diff related code next to each other
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10611
diff
changeset
|
1565 nodates=get('nodates'), |
3bb438ce4458
patch/diff: move diff related code next to each other
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10611
diff
changeset
|
1566 showfunc=get('show_function', 'showfunc'), |
3bb438ce4458
patch/diff: move diff related code next to each other
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10611
diff
changeset
|
1567 ignorews=get('ignore_all_space', 'ignorews'), |
3bb438ce4458
patch/diff: move diff related code next to each other
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10611
diff
changeset
|
1568 ignorewsamount=get('ignore_space_change', 'ignorewsamount'), |
3bb438ce4458
patch/diff: move diff related code next to each other
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10611
diff
changeset
|
1569 ignoreblanklines=get('ignore_blank_lines', 'ignoreblanklines'), |
3bb438ce4458
patch/diff: move diff related code next to each other
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10611
diff
changeset
|
1570 context=get('unified', getter=ui.config)) |
3bb438ce4458
patch/diff: move diff related code next to each other
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10611
diff
changeset
|
1571 |
10189
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1572 def diff(repo, node1=None, node2=None, match=None, changes=None, opts=None, |
12167
d2c5b0927c28
diff: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents:
12144
diff
changeset
|
1573 losedatafn=None, prefix=''): |
7308
b6f5490effbf
patch: turn patch.diff() into a generator
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
7267
diff
changeset
|
1574 '''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
|
1575 working directory. |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
1576 |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
1577 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
|
1578 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
|
1579 |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1580 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
|
1581 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
|
1582 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
|
1583 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
|
1584 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
|
1585 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
|
1586 necessary. |
12167
d2c5b0927c28
diff: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents:
12144
diff
changeset
|
1587 |
d2c5b0927c28
diff: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents:
12144
diff
changeset
|
1588 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
|
1589 display (used for subrepos). |
10189
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1590 ''' |
2874
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
1591 |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
1592 if opts is None: |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
1593 opts = mdiff.defaultopts |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
1594 |
9725
3f522d2fa633
diff: add --inverse option
Yannick Gingras <ygingras@ygingras.net>
parents:
9712
diff
changeset
|
1595 if not node1 and not node2: |
13878
a8d13ee0ce68
misc: replace .parents()[0] with p1()
Matt Mackall <mpm@selenic.com>
parents:
13751
diff
changeset
|
1596 node1 = repo.dirstate.p1() |
2934
2f190e998eb3
Teach mq about git patches
Brendan Cully <brendan@kublai.com>
parents:
2933
diff
changeset
|
1597 |
9123
360f61c2919f
Make patch.diff filelog cache LRU of 20 files. Fixes issue1738.
Brendan Cully <brendan@kublai.com>
parents:
8891
diff
changeset
|
1598 def lrugetfilectx(): |
360f61c2919f
Make patch.diff filelog cache LRU of 20 files. Fixes issue1738.
Brendan Cully <brendan@kublai.com>
parents:
8891
diff
changeset
|
1599 cache = {} |
16834
cafd8a8fb713
util: subclass deque for Python 2.4 backwards compatibility
Bryan O'Sullivan <bryano@fb.com>
parents:
16828
diff
changeset
|
1600 order = util.deque() |
9123
360f61c2919f
Make patch.diff filelog cache LRU of 20 files. Fixes issue1738.
Brendan Cully <brendan@kublai.com>
parents:
8891
diff
changeset
|
1601 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
|
1602 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
|
1603 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
|
1604 if len(cache) > 20: |
16803
107a3270a24a
cleanup: use the deque type where appropriate
Bryan O'Sullivan <bryano@fb.com>
parents:
16705
diff
changeset
|
1605 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
|
1606 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
|
1607 else: |
360f61c2919f
Make patch.diff filelog cache LRU of 20 files. Fixes issue1738.
Brendan Cully <brendan@kublai.com>
parents:
8891
diff
changeset
|
1608 order.remove(f) |
360f61c2919f
Make patch.diff filelog cache LRU of 20 files. Fixes issue1738.
Brendan Cully <brendan@kublai.com>
parents:
8891
diff
changeset
|
1609 order.append(f) |
360f61c2919f
Make patch.diff filelog cache LRU of 20 files. Fixes issue1738.
Brendan Cully <brendan@kublai.com>
parents:
8891
diff
changeset
|
1610 return fctx |
360f61c2919f
Make patch.diff filelog cache LRU of 20 files. Fixes issue1738.
Brendan Cully <brendan@kublai.com>
parents:
8891
diff
changeset
|
1611 return getfilectx |
360f61c2919f
Make patch.diff filelog cache LRU of 20 files. Fixes issue1738.
Brendan Cully <brendan@kublai.com>
parents:
8891
diff
changeset
|
1612 getfilectx = lrugetfilectx() |
2934
2f190e998eb3
Teach mq about git patches
Brendan Cully <brendan@kublai.com>
parents:
2933
diff
changeset
|
1613 |
6747
f6c00b17387c
use repo[changeid] to get a changectx
Matt Mackall <mpm@selenic.com>
parents:
6743
diff
changeset
|
1614 ctx1 = repo[node1] |
7090
7b5c063b0b94
diff: pass contexts to status
Matt Mackall <mpm@selenic.com>
parents:
6953
diff
changeset
|
1615 ctx2 = repo[node2] |
2874
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
1616 |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
1617 if not changes: |
7090
7b5c063b0b94
diff: pass contexts to status
Matt Mackall <mpm@selenic.com>
parents:
6953
diff
changeset
|
1618 changes = repo.status(ctx1, ctx2, match=match) |
6760
4faaa0535ea7
status: clean up all users for unknown files
Matt Mackall <mpm@selenic.com>
parents:
6758
diff
changeset
|
1619 modified, added, removed = changes[:3] |
2874
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
1620 |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
1621 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
|
1622 return [] |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1623 |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1624 revs = None |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1625 if not repo.ui.quiet: |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1626 hexfunc = repo.ui.debugflag and hex or short |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1627 revs = [hexfunc(node) for node in [node1, node2] if node] |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1628 |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1629 copy = {} |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1630 if opts.git or opts.upgrade: |
15774
0bd17a4bed88
copies: split the copies api for "normal" and merge cases (API)
Matt Mackall <mpm@selenic.com>
parents:
15591
diff
changeset
|
1631 copy = copies.pathcopies(ctx1, ctx2) |
10189
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1632 |
17299
e51d4aedace9
check-code: indent 4 spaces in py files
Mads Kiilerich <mads@kiilerich.com>
parents:
16834
diff
changeset
|
1633 def difffn(opts, losedata): |
e51d4aedace9
check-code: indent 4 spaces in py files
Mads Kiilerich <mads@kiilerich.com>
parents:
16834
diff
changeset
|
1634 return trydiff(repo, revs, ctx1, ctx2, modified, added, removed, |
e51d4aedace9
check-code: indent 4 spaces in py files
Mads Kiilerich <mads@kiilerich.com>
parents:
16834
diff
changeset
|
1635 copy, getfilectx, opts, losedata, prefix) |
10189
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1636 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
|
1637 try: |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1638 def losedata(fn): |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1639 if not losedatafn or not losedatafn(fn=fn): |
16687
e34106fa0dc3
cleanup: "raise SomeException()" -> "raise SomeException"
Brodie Rao <brodie@sf.io>
parents:
16686
diff
changeset
|
1640 raise GitDiffRequired |
10189
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1641 # 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
|
1642 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
|
1643 except GitDiffRequired: |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1644 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
|
1645 else: |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1646 return difffn(opts, None) |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1647 |
10818
d14d45fae927
diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents:
10751
diff
changeset
|
1648 def difflabel(func, *args, **kw): |
d14d45fae927
diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents:
10751
diff
changeset
|
1649 '''yields 2-tuples of (output, label) based on the output of func()''' |
15201
2c4fdee4d1a8
diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents:
15159
diff
changeset
|
1650 headprefixes = [('diff', 'diff.diffline'), |
2c4fdee4d1a8
diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents:
15159
diff
changeset
|
1651 ('copy', 'diff.extended'), |
2c4fdee4d1a8
diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents:
15159
diff
changeset
|
1652 ('rename', 'diff.extended'), |
2c4fdee4d1a8
diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents:
15159
diff
changeset
|
1653 ('old', 'diff.extended'), |
2c4fdee4d1a8
diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents:
15159
diff
changeset
|
1654 ('new', 'diff.extended'), |
2c4fdee4d1a8
diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents:
15159
diff
changeset
|
1655 ('deleted', 'diff.extended'), |
2c4fdee4d1a8
diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents:
15159
diff
changeset
|
1656 ('---', 'diff.file_a'), |
2c4fdee4d1a8
diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents:
15159
diff
changeset
|
1657 ('+++', 'diff.file_b')] |
2c4fdee4d1a8
diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents:
15159
diff
changeset
|
1658 textprefixes = [('@', 'diff.hunk'), |
2c4fdee4d1a8
diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents:
15159
diff
changeset
|
1659 ('-', 'diff.deleted'), |
2c4fdee4d1a8
diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents:
15159
diff
changeset
|
1660 ('+', 'diff.inserted')] |
2c4fdee4d1a8
diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents:
15159
diff
changeset
|
1661 head = False |
10818
d14d45fae927
diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents:
10751
diff
changeset
|
1662 for chunk in func(*args, **kw): |
d14d45fae927
diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents:
10751
diff
changeset
|
1663 lines = chunk.split('\n') |
d14d45fae927
diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents:
10751
diff
changeset
|
1664 for i, line in enumerate(lines): |
d14d45fae927
diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents:
10751
diff
changeset
|
1665 if i != 0: |
d14d45fae927
diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents:
10751
diff
changeset
|
1666 yield ('\n', '') |
15201
2c4fdee4d1a8
diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents:
15159
diff
changeset
|
1667 if head: |
2c4fdee4d1a8
diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents:
15159
diff
changeset
|
1668 if line.startswith('@'): |
2c4fdee4d1a8
diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents:
15159
diff
changeset
|
1669 head = False |
2c4fdee4d1a8
diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents:
15159
diff
changeset
|
1670 else: |
16686
67964cda8701
cleanup: "not x in y" -> "x not in y"
Brodie Rao <brodie@sf.io>
parents:
16683
diff
changeset
|
1671 if line and line[0] not in ' +-@\\': |
15201
2c4fdee4d1a8
diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents:
15159
diff
changeset
|
1672 head = True |
10818
d14d45fae927
diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents:
10751
diff
changeset
|
1673 stripline = line |
15201
2c4fdee4d1a8
diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents:
15159
diff
changeset
|
1674 if not head and line and line[0] in '+-': |
10818
d14d45fae927
diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents:
10751
diff
changeset
|
1675 # highlight trailing whitespace, but only in changed lines |
d14d45fae927
diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents:
10751
diff
changeset
|
1676 stripline = line.rstrip() |
15201
2c4fdee4d1a8
diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents:
15159
diff
changeset
|
1677 prefixes = textprefixes |
2c4fdee4d1a8
diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents:
15159
diff
changeset
|
1678 if head: |
2c4fdee4d1a8
diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents:
15159
diff
changeset
|
1679 prefixes = headprefixes |
10818
d14d45fae927
diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents:
10751
diff
changeset
|
1680 for prefix, label in prefixes: |
d14d45fae927
diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents:
10751
diff
changeset
|
1681 if stripline.startswith(prefix): |
d14d45fae927
diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents:
10751
diff
changeset
|
1682 yield (stripline, label) |
d14d45fae927
diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents:
10751
diff
changeset
|
1683 break |
d14d45fae927
diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents:
10751
diff
changeset
|
1684 else: |
d14d45fae927
diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents:
10751
diff
changeset
|
1685 yield (line, '') |
d14d45fae927
diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents:
10751
diff
changeset
|
1686 if line != stripline: |
d14d45fae927
diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents:
10751
diff
changeset
|
1687 yield (line[len(stripline):], 'diff.trailingwhitespace') |
d14d45fae927
diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents:
10751
diff
changeset
|
1688 |
d14d45fae927
diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents:
10751
diff
changeset
|
1689 def diffui(*args, **kw): |
d14d45fae927
diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents:
10751
diff
changeset
|
1690 '''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
|
1691 return difflabel(diff, *args, **kw) |
d14d45fae927
diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents:
10751
diff
changeset
|
1692 |
d14d45fae927
diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents:
10751
diff
changeset
|
1693 |
10189
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1694 def _addmodehdr(header, omode, nmode): |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1695 if omode != nmode: |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1696 header.append('old mode %s\n' % omode) |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1697 header.append('new mode %s\n' % nmode) |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1698 |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1699 def trydiff(repo, revs, ctx1, ctx2, modified, added, removed, |
12167
d2c5b0927c28
diff: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents:
12144
diff
changeset
|
1700 copy, getfilectx, opts, losedatafn, prefix): |
d2c5b0927c28
diff: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents:
12144
diff
changeset
|
1701 |
d2c5b0927c28
diff: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents:
12144
diff
changeset
|
1702 def join(f): |
d2c5b0927c28
diff: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents:
12144
diff
changeset
|
1703 return os.path.join(prefix, f) |
2874
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
1704 |
7090
7b5c063b0b94
diff: pass contexts to status
Matt Mackall <mpm@selenic.com>
parents:
6953
diff
changeset
|
1705 date1 = util.datestr(ctx1.date()) |
7b5c063b0b94
diff: pass contexts to status
Matt Mackall <mpm@selenic.com>
parents:
6953
diff
changeset
|
1706 man1 = ctx1.manifest() |
3967
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
1707 |
10189
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1708 gone = set() |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1709 gitmode = {'l': '120000', 'x': '100755', '': '100644'} |
2874
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
1710 |
10466
d1f209bb9564
patch: separate reverse copy data (issue1959)
Wagner Bruna <wbruna@softwareexpress.com.br>
parents:
10384
diff
changeset
|
1711 copyto = dict([(v, k) for k, v in copy.items()]) |
d1f209bb9564
patch: separate reverse copy data (issue1959)
Wagner Bruna <wbruna@softwareexpress.com.br>
parents:
10384
diff
changeset
|
1712 |
2907 | 1713 if opts.git: |
10189
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1714 revs = None |
3996
c190df14338c
exec: add execfunc to simplify exec flag support on non-exec filesystems
Matt Mackall <mpm@selenic.com>
parents:
3970
diff
changeset
|
1715 |
8209
a1a5a57efe90
replace util.sort with sorted built-in
Matt Mackall <mpm@selenic.com>
parents:
8090
diff
changeset
|
1716 for f in sorted(modified + added + removed): |
2874
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
1717 to = None |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
1718 tn = None |
2907 | 1719 dodiff = True |
3329
319358e6bd96
Don't generate git diff header for empty diffs
Brendan Cully <brendan@kublai.com>
parents:
3231
diff
changeset
|
1720 header = [] |
3967
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
1721 if f in man1: |
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
1722 to = getfilectx(f, ctx1).data() |
2874
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
1723 if f not in removed: |
3967
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
1724 tn = getfilectx(f, ctx2).data() |
5482
e5eedd74e70f
Use both the from and to name in mdiff.unidiff.
Dustin Sallings <dustin@spy.net>
parents:
5481
diff
changeset
|
1725 a, b = f, f |
10189
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1726 if opts.git or losedatafn: |
2907 | 1727 if f in added: |
6743 | 1728 mode = gitmode[ctx2.flags(f)] |
10466
d1f209bb9564
patch: separate reverse copy data (issue1959)
Wagner Bruna <wbruna@softwareexpress.com.br>
parents:
10384
diff
changeset
|
1729 if f in copy or f in copyto: |
10189
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1730 if opts.git: |
10466
d1f209bb9564
patch: separate reverse copy data (issue1959)
Wagner Bruna <wbruna@softwareexpress.com.br>
parents:
10384
diff
changeset
|
1731 if f in copy: |
d1f209bb9564
patch: separate reverse copy data (issue1959)
Wagner Bruna <wbruna@softwareexpress.com.br>
parents:
10384
diff
changeset
|
1732 a = copy[f] |
d1f209bb9564
patch: separate reverse copy data (issue1959)
Wagner Bruna <wbruna@softwareexpress.com.br>
parents:
10384
diff
changeset
|
1733 else: |
d1f209bb9564
patch: separate reverse copy data (issue1959)
Wagner Bruna <wbruna@softwareexpress.com.br>
parents:
10384
diff
changeset
|
1734 a = copyto[f] |
10189
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1735 omode = gitmode[man1.flags(a)] |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1736 _addmodehdr(header, omode, mode) |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1737 if a in removed and a not in gone: |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1738 op = 'rename' |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1739 gone.add(a) |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1740 else: |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1741 op = 'copy' |
12167
d2c5b0927c28
diff: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents:
12144
diff
changeset
|
1742 header.append('%s from %s\n' % (op, join(a))) |
d2c5b0927c28
diff: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents:
12144
diff
changeset
|
1743 header.append('%s to %s\n' % (op, join(f))) |
10189
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1744 to = getfilectx(a, ctx1).data() |
3702
70c3ee224c08
Don't generate git patches that rename a file to multiple destinations
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3701
diff
changeset
|
1745 else: |
10189
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1746 losedatafn(f) |
2907 | 1747 else: |
10189
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1748 if opts.git: |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1749 header.append('new file mode %s\n' % mode) |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1750 elif ctx2.flags(f): |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1751 losedatafn(f) |
12576
1c9bb7e00f71
patch: test and document a bit binary to regular file upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
12575
diff
changeset
|
1752 # In theory, if tn was copied or renamed we should check |
1c9bb7e00f71
patch: test and document a bit binary to regular file upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
12575
diff
changeset
|
1753 # if the source is binary too but the copy record already |
1c9bb7e00f71
patch: test and document a bit binary to regular file upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
12575
diff
changeset
|
1754 # forces git mode. |
4092
4ced663bebf0
git patches: handle renames of binary files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3900
diff
changeset
|
1755 if util.binary(tn): |
10189
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1756 if opts.git: |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1757 dodiff = 'binary' |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1758 else: |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1759 losedatafn(f) |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1760 if not opts.git and not tn: |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1761 # regular diffs cannot represent new empty file |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1762 losedatafn(f) |
2907 | 1763 elif f in removed: |
10189
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1764 if opts.git: |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1765 # have we already reported a copy above? |
10467
16c68fd720ab
patch: remove useless copy, cleanup
Patrick Mezard <pmezard@gmail.com>
parents:
10466
diff
changeset
|
1766 if ((f in copy and copy[f] in added |
16c68fd720ab
patch: remove useless copy, cleanup
Patrick Mezard <pmezard@gmail.com>
parents:
10466
diff
changeset
|
1767 and copyto[copy[f]] == f) or |
16c68fd720ab
patch: remove useless copy, cleanup
Patrick Mezard <pmezard@gmail.com>
parents:
10466
diff
changeset
|
1768 (f in copyto and copyto[f] in added |
16c68fd720ab
patch: remove useless copy, cleanup
Patrick Mezard <pmezard@gmail.com>
parents:
10466
diff
changeset
|
1769 and copy[copyto[f]] == f)): |
10189
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1770 dodiff = False |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1771 else: |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1772 header.append('deleted file mode %s\n' % |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1773 gitmode[man1.flags(f)]) |
12575
9b3913baba0c
patch: upgrade to git patch when removing binary file
Patrick Mezard <pmezard@gmail.com>
parents:
12574
diff
changeset
|
1774 elif not to or util.binary(to): |
10189
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1775 # regular diffs cannot represent empty file deletion |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1776 losedatafn(f) |
2907 | 1777 else: |
10189
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1778 oflag = man1.flags(f) |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1779 nflag = ctx2.flags(f) |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1780 binary = util.binary(to) or util.binary(tn) |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1781 if opts.git: |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1782 _addmodehdr(header, gitmode[oflag], gitmode[nflag]) |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1783 if binary: |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1784 dodiff = 'binary' |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1785 elif binary or nflag != oflag: |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1786 losedatafn(f) |
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1787 if opts.git: |
12167
d2c5b0927c28
diff: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents:
12144
diff
changeset
|
1788 header.insert(0, mdiff.diffline(revs, join(a), join(b), opts)) |
10189
e451e599fbcf
patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents:
10151
diff
changeset
|
1789 |
4106
797dbdd4d7e1
git binary patches: don't print the header for identical files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4105
diff
changeset
|
1790 if dodiff: |
797dbdd4d7e1
git binary patches: don't print the header for identical files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4105
diff
changeset
|
1791 if dodiff == 'binary': |
5033
1b07668b8cc3
patch: remove unused parameter from b85diff
Bryan O'Sullivan <bos@serpentine.com>
parents:
4965
diff
changeset
|
1792 text = b85diff(to, tn) |
4106
797dbdd4d7e1
git binary patches: don't print the header for identical files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4105
diff
changeset
|
1793 else: |
4108 | 1794 text = mdiff.unidiff(to, date1, |
1795 # ctx2 date may be dynamic | |
1796 tn, util.datestr(ctx2.date()), | |
12167
d2c5b0927c28
diff: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents:
12144
diff
changeset
|
1797 join(a), join(b), revs, opts=opts) |
7308
b6f5490effbf
patch: turn patch.diff() into a generator
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
7267
diff
changeset
|
1798 if header and (text or len(header) > 1): |
b6f5490effbf
patch: turn patch.diff() into a generator
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
7267
diff
changeset
|
1799 yield ''.join(header) |
b6f5490effbf
patch: turn patch.diff() into a generator
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
7267
diff
changeset
|
1800 if text: |
b6f5490effbf
patch: turn patch.diff() into a generator
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
7267
diff
changeset
|
1801 yield text |
2874
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
1802 |
14401
7bb7be1c1385
patch: add diffstatsum helper
Matt Mackall <mpm@selenic.com>
parents:
14400
diff
changeset
|
1803 def diffstatsum(stats): |
14437
cbe13e6bdc34
patch: restore the previous output of 'diff --stat'
Steven Brown <StevenGBrown@gmail.com>
parents:
14435
diff
changeset
|
1804 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
|
1805 for f, a, r, b in stats: |
7bb7be1c1385
patch: add diffstatsum helper
Matt Mackall <mpm@selenic.com>
parents:
14400
diff
changeset
|
1806 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
|
1807 maxtotal = max(maxtotal, a + r) |
14401
7bb7be1c1385
patch: add diffstatsum helper
Matt Mackall <mpm@selenic.com>
parents:
14400
diff
changeset
|
1808 addtotal += a |
7bb7be1c1385
patch: add diffstatsum helper
Matt Mackall <mpm@selenic.com>
parents:
14400
diff
changeset
|
1809 removetotal += r |
7bb7be1c1385
patch: add diffstatsum helper
Matt Mackall <mpm@selenic.com>
parents:
14400
diff
changeset
|
1810 binary = binary or b |
7bb7be1c1385
patch: add diffstatsum helper
Matt Mackall <mpm@selenic.com>
parents:
14400
diff
changeset
|
1811 |
14437
cbe13e6bdc34
patch: restore the previous output of 'diff --stat'
Steven Brown <StevenGBrown@gmail.com>
parents:
14435
diff
changeset
|
1812 return maxfile, maxtotal, addtotal, removetotal, binary |
14401
7bb7be1c1385
patch: add diffstatsum helper
Matt Mackall <mpm@selenic.com>
parents:
14400
diff
changeset
|
1813 |
7547
4949729ee9ee
python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7521
diff
changeset
|
1814 def diffstatdata(lines): |
13395
104c9ed93fc5
diffstat: fix parsing of filenames with spaces
Gastón Kleiman <gaston.kleiman@gmail.com>
parents:
13112
diff
changeset
|
1815 diffre = re.compile('^diff .*-r [a-z0-9]+\s(.*)$') |
104c9ed93fc5
diffstat: fix parsing of filenames with spaces
Gastón Kleiman <gaston.kleiman@gmail.com>
parents:
13112
diff
changeset
|
1816 |
14400
cd1ca2556cac
diffstatdata: no longer a generator
Matt Mackall <mpm@selenic.com>
parents:
14392
diff
changeset
|
1817 results = [] |
15363
628a4a9e411d
diffstat: be more picky when marking file as 'binary' (issue2816)
Patrick Mezard <pmezard@gmail.com>
parents:
15201
diff
changeset
|
1818 filename, adds, removes, isbinary = None, 0, 0, False |
14400
cd1ca2556cac
diffstatdata: no longer a generator
Matt Mackall <mpm@selenic.com>
parents:
14392
diff
changeset
|
1819 |
cd1ca2556cac
diffstatdata: no longer a generator
Matt Mackall <mpm@selenic.com>
parents:
14392
diff
changeset
|
1820 def addresult(): |
cd1ca2556cac
diffstatdata: no longer a generator
Matt Mackall <mpm@selenic.com>
parents:
14392
diff
changeset
|
1821 if filename: |
cd1ca2556cac
diffstatdata: no longer a generator
Matt Mackall <mpm@selenic.com>
parents:
14392
diff
changeset
|
1822 results.append((filename, adds, removes, isbinary)) |
cd1ca2556cac
diffstatdata: no longer a generator
Matt Mackall <mpm@selenic.com>
parents:
14392
diff
changeset
|
1823 |
7547
4949729ee9ee
python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7521
diff
changeset
|
1824 for line in lines: |
4949729ee9ee
python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7521
diff
changeset
|
1825 if line.startswith('diff'): |
14400
cd1ca2556cac
diffstatdata: no longer a generator
Matt Mackall <mpm@selenic.com>
parents:
14392
diff
changeset
|
1826 addresult() |
7547
4949729ee9ee
python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7521
diff
changeset
|
1827 # set numbers to 0 anyway when starting new file |
15363
628a4a9e411d
diffstat: be more picky when marking file as 'binary' (issue2816)
Patrick Mezard <pmezard@gmail.com>
parents:
15201
diff
changeset
|
1828 adds, removes, isbinary = 0, 0, False |
7547
4949729ee9ee
python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7521
diff
changeset
|
1829 if line.startswith('diff --git'): |
4949729ee9ee
python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7521
diff
changeset
|
1830 filename = gitre.search(line).group(1) |
13395
104c9ed93fc5
diffstat: fix parsing of filenames with spaces
Gastón Kleiman <gaston.kleiman@gmail.com>
parents:
13112
diff
changeset
|
1831 elif line.startswith('diff -r'): |
8761
0289f384e1e5
Generally replace "file name" with "filename" in help and comments.
timeless <timeless@gmail.com>
parents:
8632
diff
changeset
|
1832 # 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
|
1833 filename = diffre.search(line).group(1) |
15971
089ee59a8658
patch: a little bit more robust line counting on diff --stat (issue3183)
Jesus Espino Garcia <jesus.espino@kaleidos.net>
parents:
15774
diff
changeset
|
1834 elif line.startswith('+') and not line.startswith('+++ '): |
7547
4949729ee9ee
python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7521
diff
changeset
|
1835 adds += 1 |
15971
089ee59a8658
patch: a little bit more robust line counting on diff --stat (issue3183)
Jesus Espino Garcia <jesus.espino@kaleidos.net>
parents:
15774
diff
changeset
|
1836 elif line.startswith('-') and not line.startswith('--- '): |
7547
4949729ee9ee
python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7521
diff
changeset
|
1837 removes += 1 |
15363
628a4a9e411d
diffstat: be more picky when marking file as 'binary' (issue2816)
Patrick Mezard <pmezard@gmail.com>
parents:
15201
diff
changeset
|
1838 elif (line.startswith('GIT binary patch') or |
628a4a9e411d
diffstat: be more picky when marking file as 'binary' (issue2816)
Patrick Mezard <pmezard@gmail.com>
parents:
15201
diff
changeset
|
1839 line.startswith('Binary file')): |
628a4a9e411d
diffstat: be more picky when marking file as 'binary' (issue2816)
Patrick Mezard <pmezard@gmail.com>
parents:
15201
diff
changeset
|
1840 isbinary = True |
14400
cd1ca2556cac
diffstatdata: no longer a generator
Matt Mackall <mpm@selenic.com>
parents:
14392
diff
changeset
|
1841 addresult() |
cd1ca2556cac
diffstatdata: no longer a generator
Matt Mackall <mpm@selenic.com>
parents:
14392
diff
changeset
|
1842 return results |
7547
4949729ee9ee
python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7521
diff
changeset
|
1843 |
9642
7d17794f08a9
diffstat: with --git, mark binary files with Bin
Brodie Rao <me+hg@dackz.net>
parents:
9639
diff
changeset
|
1844 def diffstat(lines, width=80, git=False): |
7547
4949729ee9ee
python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7521
diff
changeset
|
1845 output = [] |
14402
f03f08240c32
patch: use diffstatsum in diffstat
Matt Mackall <mpm@selenic.com>
parents:
14401
diff
changeset
|
1846 stats = diffstatdata(lines) |
14437
cbe13e6bdc34
patch: restore the previous output of 'diff --stat'
Steven Brown <StevenGBrown@gmail.com>
parents:
14435
diff
changeset
|
1847 maxname, maxtotal, totaladds, totalremoves, hasbinary = diffstatsum(stats) |
7547
4949729ee9ee
python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7521
diff
changeset
|
1848 |
4949729ee9ee
python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7521
diff
changeset
|
1849 countwidth = len(str(maxtotal)) |
9642
7d17794f08a9
diffstat: with --git, mark binary files with Bin
Brodie Rao <me+hg@dackz.net>
parents:
9639
diff
changeset
|
1850 if hasbinary and countwidth < 3: |
7d17794f08a9
diffstat: with --git, mark binary files with Bin
Brodie Rao <me+hg@dackz.net>
parents:
9639
diff
changeset
|
1851 countwidth = 3 |
9330
be2a13153372
diffstat: scale adds/removes proportionally to graph width
Brodie Rao <me+hg@dackz.net>
parents:
9328
diff
changeset
|
1852 graphwidth = width - countwidth - maxname - 6 |
7547
4949729ee9ee
python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7521
diff
changeset
|
1853 if graphwidth < 10: |
4949729ee9ee
python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7521
diff
changeset
|
1854 graphwidth = 10 |
4949729ee9ee
python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7521
diff
changeset
|
1855 |
9330
be2a13153372
diffstat: scale adds/removes proportionally to graph width
Brodie Rao <me+hg@dackz.net>
parents:
9328
diff
changeset
|
1856 def scale(i): |
be2a13153372
diffstat: scale adds/removes proportionally to graph width
Brodie Rao <me+hg@dackz.net>
parents:
9328
diff
changeset
|
1857 if maxtotal <= graphwidth: |
be2a13153372
diffstat: scale adds/removes proportionally to graph width
Brodie Rao <me+hg@dackz.net>
parents:
9328
diff
changeset
|
1858 return i |
be2a13153372
diffstat: scale adds/removes proportionally to graph width
Brodie Rao <me+hg@dackz.net>
parents:
9328
diff
changeset
|
1859 # 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
|
1860 # 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
|
1861 # 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
|
1862 return max(i * graphwidth // maxtotal, int(bool(i))) |
7547
4949729ee9ee
python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7521
diff
changeset
|
1863 |
14402
f03f08240c32
patch: use diffstatsum in diffstat
Matt Mackall <mpm@selenic.com>
parents:
14401
diff
changeset
|
1864 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
|
1865 if isbinary: |
9642
7d17794f08a9
diffstat: with --git, mark binary files with Bin
Brodie Rao <me+hg@dackz.net>
parents:
9639
diff
changeset
|
1866 count = 'Bin' |
7d17794f08a9
diffstat: with --git, mark binary files with Bin
Brodie Rao <me+hg@dackz.net>
parents:
9639
diff
changeset
|
1867 else: |
7d17794f08a9
diffstat: with --git, mark binary files with Bin
Brodie Rao <me+hg@dackz.net>
parents:
9639
diff
changeset
|
1868 count = adds + removes |
9330
be2a13153372
diffstat: scale adds/removes proportionally to graph width
Brodie Rao <me+hg@dackz.net>
parents:
9328
diff
changeset
|
1869 pluses = '+' * scale(adds) |
be2a13153372
diffstat: scale adds/removes proportionally to graph width
Brodie Rao <me+hg@dackz.net>
parents:
9328
diff
changeset
|
1870 minuses = '-' * scale(removes) |
11611
4f5a6df2af92
i18n: use encoding.colwidth() for correct column width
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
11377
diff
changeset
|
1871 output.append(' %s%s | %*s %s%s\n' % |
14402
f03f08240c32
patch: use diffstatsum in diffstat
Matt Mackall <mpm@selenic.com>
parents:
14401
diff
changeset
|
1872 (filename, ' ' * (maxname - encoding.colwidth(filename)), |
f03f08240c32
patch: use diffstatsum in diffstat
Matt Mackall <mpm@selenic.com>
parents:
14401
diff
changeset
|
1873 countwidth, count, pluses, minuses)) |
7547
4949729ee9ee
python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7521
diff
changeset
|
1874 |
4949729ee9ee
python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7521
diff
changeset
|
1875 if stats: |
16683 | 1876 output.append(_(' %d files changed, %d insertions(+), ' |
1877 '%d deletions(-)\n') | |
7860
162fd31bbd93
diffstat: use width 80 by default and avoid division by zero
Matt Mackall <mpm@selenic.com>
parents:
7783
diff
changeset
|
1878 % (len(stats), totaladds, totalremoves)) |
7547
4949729ee9ee
python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7521
diff
changeset
|
1879 |
4949729ee9ee
python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7521
diff
changeset
|
1880 return ''.join(output) |
10818
d14d45fae927
diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents:
10751
diff
changeset
|
1881 |
d14d45fae927
diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents:
10751
diff
changeset
|
1882 def diffstatui(*args, **kw): |
d14d45fae927
diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents:
10751
diff
changeset
|
1883 '''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
|
1884 ui.write() |
d14d45fae927
diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents:
10751
diff
changeset
|
1885 ''' |
d14d45fae927
diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents:
10751
diff
changeset
|
1886 |
d14d45fae927
diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents:
10751
diff
changeset
|
1887 for line in diffstat(*args, **kw).splitlines(): |
d14d45fae927
diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents:
10751
diff
changeset
|
1888 if line and line[-1] in '+-': |
d14d45fae927
diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents:
10751
diff
changeset
|
1889 name, graph = line.rsplit(' ', 1) |
d14d45fae927
diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents:
10751
diff
changeset
|
1890 yield (name + ' ', '') |
d14d45fae927
diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents:
10751
diff
changeset
|
1891 m = re.search(r'\++', graph) |
d14d45fae927
diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents:
10751
diff
changeset
|
1892 if m: |
d14d45fae927
diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents:
10751
diff
changeset
|
1893 yield (m.group(0), 'diffstat.inserted') |
d14d45fae927
diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents:
10751
diff
changeset
|
1894 m = re.search(r'-+', graph) |
d14d45fae927
diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents:
10751
diff
changeset
|
1895 if m: |
d14d45fae927
diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents:
10751
diff
changeset
|
1896 yield (m.group(0), 'diffstat.deleted') |
d14d45fae927
diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents:
10751
diff
changeset
|
1897 else: |
d14d45fae927
diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents:
10751
diff
changeset
|
1898 yield (line, '') |
d14d45fae927
diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents:
10751
diff
changeset
|
1899 yield ('\n', '') |