annotate mercurial/patch.py @ 24500:7b0a20cd8c95

run-tests: explicitly handle unicode when writing xunit file The xunit writer was passing a str to a minidom API. An implicit .decode('ascii') was performed somewhere, causing UnicodeDecodeError if test output contained non-ascii sequences. This patch converts test output to utf-8 before passing it to minidom. We use the "replace" strategy to ensure invalid utf-8 sequences get munged into �.
author Gregory Szorc <gregory.szorc@gmail.com>
date Sun, 29 Mar 2015 10:41:23 -0700
parents f5f4dc115fb2
children a7f8e3584ef3
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 10203
diff changeset
7 # GNU General Public License version 2 or any later version.
2861
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
8
24269
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
9 import cStringIO, email, os, errno, re, posixpath, copy
14452
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
10 import tempfile, zlib, shutil
19810
c80feeb715d1 python2.4: fix imports of sub-packages of the email package
Augie Fackler <raf@durin42.com>
parents: 19789
diff changeset
11 # On python2.4 you have to import these by name or they fail to
c80feeb715d1 python2.4: fix imports of sub-packages of the email package
Augie Fackler <raf@durin42.com>
parents: 19789
diff changeset
12 # load. This was not a problem on Python 2.7.
c80feeb715d1 python2.4: fix imports of sub-packages of the email package
Augie Fackler <raf@durin42.com>
parents: 19789
diff changeset
13 import email.Generator
c80feeb715d1 python2.4: fix imports of sub-packages of the email package
Augie Fackler <raf@durin42.com>
parents: 19789
diff changeset
14 import email.Parser
10965
7faef79a89c7 patch: move mercurial-specific imports after stdlib imports
Augie Fackler <durin42@gmail.com>
parents: 10905
diff changeset
15
3891
6b4127c7d52a Simplify i18n imports
Matt Mackall <mpm@selenic.com>
parents: 3877
diff changeset
16 from i18n import _
19875
c172660eee01 patch: Fix nullid for binary git diffs (issue4054)
Johan Bjork <jbjoerk@gmail.com>
parents: 19513
diff changeset
17 from node import hex, short
24341
616c01b69898 record: change interface of the filtering function
Laurent Charignon <lcharignon@fb.com>
parents: 24306
diff changeset
18 import cStringIO
14611
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
19 import base85, mdiff, scmutil, util, diffhelpers, copies, encoding, error
24390
72d7d390ef5d patch._applydiff: resolve prefix with respect to the cwd
Siddharth Agarwal <sid0@fb.com>
parents: 24385
diff changeset
20 import pathutil
2866
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
21
7199
dd891d0d97a3 patch: consolidate two different regexes for parsing of git diffs
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7198
diff changeset
22 gitre = re.compile('diff --git a/(.*) b/(.*)')
22460
c343557a8442 patch: enable diff.tab markup for the color extension
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 22296
diff changeset
23 tabsplitter = re.compile(r'(\t+|[^\t]+)')
7199
dd891d0d97a3 patch: consolidate two different regexes for parsing of git diffs
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7198
diff changeset
24
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
25 class PatchError(Exception):
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
26 pass
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
27
2933
439fd013360d Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents: 2922
diff changeset
28
439fd013360d Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents: 2922
diff changeset
29 # public functions
439fd013360d Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents: 2922
diff changeset
30
10384
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
31 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
32 '''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
33 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
34 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
35 # continuation
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
36 return True
10883
196908117c27 patch: don't look for headers in diff lines
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 10748
diff changeset
37 if line[0] in (' ', '-', '+'):
196908117c27 patch: don't look for headers in diff lines
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 10748
diff changeset
38 # 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
39 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
40 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
41 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
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 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
44 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
45
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
46 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
47 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
48
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
49 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
50 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
51 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
52 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
53 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
54 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 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
56
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
57 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
58
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
59 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
60 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
61
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
62 def 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
63 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
64 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
65 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
66 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
67 cur = []
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 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
70
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
71 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
72 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
73 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
74
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
75 def 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
76 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
77 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
78 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
79 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
80 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
81 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
82
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
83 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
84 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
85 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
86
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
87 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
88 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
89 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
90 else:
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
91 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
92 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
93 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
94 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
95 continue
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
96 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
97
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
98 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
99 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
100
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
101 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
102 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
103 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
104 cur = []
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
105 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
106 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
107 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
108
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
109 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
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 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
112 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
113
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
114 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
115 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
116
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
117 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
118 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
119 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
120
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
121 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
122 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
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 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
125 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
126 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
127 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
128 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
129
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
130 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
131 cur = []
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 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
134
14966
0588fb0e2e8d patch: use safehasattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 14832
diff changeset
135 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
136 # 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
137 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
138
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
139 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
140 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
141 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
142 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
143 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
144 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
145 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
146 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
147 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
148 # 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
149 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
150 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
151 # 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
152 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
153 # 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
154
832f35386067 import: import each patch in a file or stream as a separate change
Brendan Cully <brendan@kublai.com>
parents: 10282
diff changeset
155 # 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
156 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
157
2866
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
158 def extract(ui, fileobj):
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
159 '''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
160
4263
47ba52121433 Add import --exact.
Brendan Cully <brendan@kublai.com>
parents: 4232
diff changeset
161 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
162
11645
88b89ace643b patch: fix extract() docstring, it returns branch as well
Dan Drake <drake@kaist.edu>
parents: 11611
diff changeset
163 return tuple (filename, message, user, date, branch, node, p1, p2).
4263
47ba52121433 Add import --exact.
Brendan Cully <brendan@kublai.com>
parents: 4232
diff changeset
164 Any item in the returned tuple can be None. If filename is None,
47ba52121433 Add import --exact.
Brendan Cully <brendan@kublai.com>
parents: 4232
diff changeset
165 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
166
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
167 # 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
168 # (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
169 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
170 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
171 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
172 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
173
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
174 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
175 tmpfp = os.fdopen(fd, 'w')
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
176 try:
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
177 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
178
4777
5ee5cbfceff3 patch.extract: do not prepend subject if the description already starts with it
Brendan Cully <brendan@kublai.com>
parents: 4659
diff changeset
179 subject = msg['Subject']
2866
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
180 user = msg['From']
9573
b8352a3617f3 patch: do not swallow header-like patch first line (issue1859)
Patrick Mezard <pmezard@gmail.com>
parents: 9243
diff changeset
181 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
182 # 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
183 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
184
2866
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
185 # 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
186 date = None
4263
47ba52121433 Add import --exact.
Brendan Cully <brendan@kublai.com>
parents: 4232
diff changeset
187 nodeid = None
4443
eff2eefdb65a Add ability to parse branch information to hg import
Eric Hopper <hopper@omnifarious.org>
parents: 4436
diff changeset
188 branch = None
4263
47ba52121433 Add import --exact.
Brendan Cully <brendan@kublai.com>
parents: 4232
diff changeset
189 parents = []
2866
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
190
4777
5ee5cbfceff3 patch.extract: do not prepend subject if the description already starts with it
Brendan Cully <brendan@kublai.com>
parents: 4659
diff changeset
191 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
192 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
193 pend = subject.find(']')
4208
bd9b84b9a84b Make [PATCH] removal slightly more robust
Brendan Cully <brendan@kublai.com>
parents: 4201
diff changeset
194 if pend >= 0:
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
195 subject = subject[pend + 1:].lstrip()
15158
7ce7177e029a patch: correctly handle non-tabular Subject: line
Steffen Daode Nurpmeso <sdaoden@googlemail.com>
parents: 15086
diff changeset
196 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
197 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
198 if user:
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
199 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
200 diffs_seen = 0
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
201 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
202 message = ''
2866
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
203 for part in msg.walk():
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
204 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
205 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
206 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
207 continue
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
208 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
209 m = diffre.search(payload)
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
210 if m:
4220
1253703853a8 git-send-email compatibility: stop reading changelog after ^---$
Brendan Cully <brendan@kublai.com>
parents: 4208
diff changeset
211 hgpatch = False
12645
d7452292f9d3 import: don't strip '#' lines from patch descriptions (issue 2417)
Mads Kiilerich <mads@kiilerich.com>
parents: 12577
diff changeset
212 hgpatchheader = False
4220
1253703853a8 git-send-email compatibility: stop reading changelog after ^---$
Brendan Cully <brendan@kublai.com>
parents: 4208
diff changeset
213 ignoretext = False
1253703853a8 git-send-email compatibility: stop reading changelog after ^---$
Brendan Cully <brendan@kublai.com>
parents: 4208
diff changeset
214
9467
4c041f1ee1b4 do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents: 9393
diff changeset
215 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
216 diffs_seen += 1
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
217 cfp = cStringIO.StringIO()
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
218 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
219 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
220 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
221 hgpatch = True
12645
d7452292f9d3 import: don't strip '#' lines from patch descriptions (issue 2417)
Mads Kiilerich <mads@kiilerich.com>
parents: 12577
diff changeset
222 hgpatchheader = True
2866
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
223 # drop earlier commit message content
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
224 cfp.seek(0)
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
225 cfp.truncate()
4778
e321f16f4eac patch.extract: fix test-import breakage introduced in the previous changeset
Brendan Cully <brendan@kublai.com>
parents: 4777
diff changeset
226 subject = None
12645
d7452292f9d3 import: don't strip '#' lines from patch descriptions (issue 2417)
Mads Kiilerich <mads@kiilerich.com>
parents: 12577
diff changeset
227 elif hgpatchheader:
2866
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
228 if line.startswith('# User '):
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
229 user = line[7:]
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
230 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
231 elif line.startswith("# Date "):
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
232 date = line[7:]
4443
eff2eefdb65a Add ability to parse branch information to hg import
Eric Hopper <hopper@omnifarious.org>
parents: 4436
diff changeset
233 elif line.startswith("# Branch "):
eff2eefdb65a Add ability to parse branch information to hg import
Eric Hopper <hopper@omnifarious.org>
parents: 4436
diff changeset
234 branch = line[9:]
4263
47ba52121433 Add import --exact.
Brendan Cully <brendan@kublai.com>
parents: 4232
diff changeset
235 elif line.startswith("# Node ID "):
47ba52121433 Add import --exact.
Brendan Cully <brendan@kublai.com>
parents: 4232
diff changeset
236 nodeid = line[10:]
47ba52121433 Add import --exact.
Brendan Cully <brendan@kublai.com>
parents: 4232
diff changeset
237 elif line.startswith("# Parent "):
16475
1f75c1decdeb patch: be more tolerant with "Parent" header (issue3356)
Patrick Mezard <patrick@mezard.eu>
parents: 16358
diff changeset
238 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
239 elif not line.startswith("# "):
d7452292f9d3 import: don't strip '#' lines from patch descriptions (issue 2417)
Mads Kiilerich <mads@kiilerich.com>
parents: 12577
diff changeset
240 hgpatchheader = False
19513
9e8298a324ac import: cut commit messages at --- unconditionally (issue2148)
Matt Mackall <mpm@selenic.com>
parents: 19155
diff changeset
241 elif line == '---':
4220
1253703853a8 git-send-email compatibility: stop reading changelog after ^---$
Brendan Cully <brendan@kublai.com>
parents: 4208
diff changeset
242 ignoretext = True
12645
d7452292f9d3 import: don't strip '#' lines from patch descriptions (issue 2417)
Mads Kiilerich <mads@kiilerich.com>
parents: 12577
diff changeset
243 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
244 cfp.write(line)
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
245 cfp.write('\n')
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
246 message = cfp.getvalue()
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
247 if tmpfp:
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
248 tmpfp.write(payload)
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
249 if not payload.endswith('\n'):
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
250 tmpfp.write('\n')
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
251 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
252 message += '\n' + payload
16705
c2d9ef43ff6c check-code: ignore naked excepts with a "re-raise" comment
Brodie Rao <brodie@sf.io>
parents: 16687
diff changeset
253 except: # re-raises
2866
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
254 tmpfp.close()
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
255 os.unlink(tmpname)
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
256 raise
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
257
4777
5ee5cbfceff3 patch.extract: do not prepend subject if the description already starts with it
Brendan Cully <brendan@kublai.com>
parents: 4659
diff changeset
258 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
259 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
260 tmpfp.close()
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
261 if not diffs_seen:
2893e51407a4 commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2865
diff changeset
262 os.unlink(tmpname)
4443
eff2eefdb65a Add ability to parse branch information to hg import
Eric Hopper <hopper@omnifarious.org>
parents: 4436
diff changeset
263 return None, message, user, date, branch, None, None, None
24306
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24269
diff changeset
264
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24269
diff changeset
265 if parents:
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24269
diff changeset
266 p1 = parents.pop(0)
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24269
diff changeset
267 else:
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24269
diff changeset
268 p1 = None
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24269
diff changeset
269
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24269
diff changeset
270 if parents:
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24269
diff changeset
271 p2 = parents.pop(0)
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24269
diff changeset
272 else:
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24269
diff changeset
273 p2 = None
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24269
diff changeset
274
4443
eff2eefdb65a Add ability to parse branch information to hg import
Eric Hopper <hopper@omnifarious.org>
parents: 4436
diff changeset
275 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
276
8778
c5f36402daad use new style classes
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8761
diff changeset
277 class patchmeta(object):
7148
7d84e5b00e29 patch: extract and rename gitpatch into patchmeta, document
Patrick Mezard <pmezard@gmail.com>
parents: 7147
diff changeset
278 """Patched file metadata
7d84e5b00e29 patch: extract and rename gitpatch into patchmeta, document
Patrick Mezard <pmezard@gmail.com>
parents: 7147
diff changeset
279
7d84e5b00e29 patch: extract and rename gitpatch into patchmeta, document
Patrick Mezard <pmezard@gmail.com>
parents: 7147
diff changeset
280 '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
281 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
282 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
283 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
284 '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
285 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
286 """
7d84e5b00e29 patch: extract and rename gitpatch into patchmeta, document
Patrick Mezard <pmezard@gmail.com>
parents: 7147
diff changeset
287 def __init__(self, path):
7d84e5b00e29 patch: extract and rename gitpatch into patchmeta, document
Patrick Mezard <pmezard@gmail.com>
parents: 7147
diff changeset
288 self.path = path
7d84e5b00e29 patch: extract and rename gitpatch into patchmeta, document
Patrick Mezard <pmezard@gmail.com>
parents: 7147
diff changeset
289 self.oldpath = None
7d84e5b00e29 patch: extract and rename gitpatch into patchmeta, document
Patrick Mezard <pmezard@gmail.com>
parents: 7147
diff changeset
290 self.mode = None
7d84e5b00e29 patch: extract and rename gitpatch into patchmeta, document
Patrick Mezard <pmezard@gmail.com>
parents: 7147
diff changeset
291 self.op = 'MODIFY'
7d84e5b00e29 patch: extract and rename gitpatch into patchmeta, document
Patrick Mezard <pmezard@gmail.com>
parents: 7147
diff changeset
292 self.binary = False
7d84e5b00e29 patch: extract and rename gitpatch into patchmeta, document
Patrick Mezard <pmezard@gmail.com>
parents: 7147
diff changeset
293
7149
01a056c54385 patch: patchmeta gives (islink, isexec) tuple instead of int mode
Patrick Mezard <pmezard@gmail.com>
parents: 7148
diff changeset
294 def setmode(self, mode):
01a056c54385 patch: patchmeta gives (islink, isexec) tuple instead of int mode
Patrick Mezard <pmezard@gmail.com>
parents: 7148
diff changeset
295 islink = mode & 020000
01a056c54385 patch: patchmeta gives (islink, isexec) tuple instead of int mode
Patrick Mezard <pmezard@gmail.com>
parents: 7148
diff changeset
296 isexec = mode & 0100
01a056c54385 patch: patchmeta gives (islink, isexec) tuple instead of int mode
Patrick Mezard <pmezard@gmail.com>
parents: 7148
diff changeset
297 self.mode = (islink, isexec)
01a056c54385 patch: patchmeta gives (islink, isexec) tuple instead of int mode
Patrick Mezard <pmezard@gmail.com>
parents: 7148
diff changeset
298
14566
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
299 def copy(self):
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
300 other = patchmeta(self.path)
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
301 other.oldpath = self.oldpath
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
302 other.mode = self.mode
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
303 other.op = self.op
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
304 other.binary = self.binary
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
305 return other
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
306
16506
fc4e0fecf403 patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents: 16475
diff changeset
307 def _ispatchinga(self, afile):
fc4e0fecf403 patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents: 16475
diff changeset
308 if afile == '/dev/null':
fc4e0fecf403 patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents: 16475
diff changeset
309 return self.op == 'ADD'
fc4e0fecf403 patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents: 16475
diff changeset
310 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
311
fc4e0fecf403 patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents: 16475
diff changeset
312 def _ispatchingb(self, bfile):
fc4e0fecf403 patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents: 16475
diff changeset
313 if bfile == '/dev/null':
fc4e0fecf403 patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents: 16475
diff changeset
314 return self.op == 'DELETE'
fc4e0fecf403 patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents: 16475
diff changeset
315 return bfile == 'b/' + self.path
fc4e0fecf403 patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents: 16475
diff changeset
316
fc4e0fecf403 patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents: 16475
diff changeset
317 def ispatching(self, afile, bfile):
fc4e0fecf403 patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents: 16475
diff changeset
318 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
319
11018
17cf756ba25d patch: descriptive patchmeta.__repr__ to help debugging
Mads Kiilerich <mads@kiilerich.com>
parents: 10966
diff changeset
320 def __repr__(self):
17cf756ba25d patch: descriptive patchmeta.__repr__ to help debugging
Mads Kiilerich <mads@kiilerich.com>
parents: 10966
diff changeset
321 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
322
7152
f0055cec8446 patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 7151
diff changeset
323 def readgitpatch(lr):
2861
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
324 """extract git-style metadata about patches from <patchname>"""
3223
53e843840349 Whitespace/Tab cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3199
diff changeset
325
2861
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
326 # Filter patch for git information
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 gitpatches = []
7152
f0055cec8446 patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 7151
diff changeset
329 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
330 line = line.rstrip(' \r\n')
18830
6b827d84d286 patch: match 'diff --git a/' instead of 'diff --git'
Sean Farley <sean.michael.farley@gmail.com>
parents: 18824
diff changeset
331 if line.startswith('diff --git a/'):
2861
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
332 m = gitre.match(line)
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
333 if m:
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
334 if gp:
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
335 gitpatches.append(gp)
9392
039bce1b505f patch: readgitpatch: remove unused variable 'src'
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9331
diff changeset
336 dst = m.group(2)
7148
7d84e5b00e29 patch: extract and rename gitpatch into patchmeta, document
Patrick Mezard <pmezard@gmail.com>
parents: 7147
diff changeset
337 gp = patchmeta(dst)
2861
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
338 elif gp:
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
339 if line.startswith('--- '):
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
340 gitpatches.append(gp)
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
341 gp = None
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
342 continue
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
343 if line.startswith('rename from '):
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
344 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
345 gp.oldpath = line[12:]
2861
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
346 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
347 gp.path = line[10:]
2861
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
348 elif line.startswith('copy from '):
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
349 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
350 gp.oldpath = line[10:]
2861
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
351 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
352 gp.path = line[8:]
2861
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
353 elif line.startswith('deleted file'):
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
354 gp.op = 'DELETE'
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
355 elif line.startswith('new file mode '):
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
356 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
357 gp.setmode(int(line[-6:], 8))
2861
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
358 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
359 gp.setmode(int(line[-6:], 8))
3367
7f486971d263 Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents: 3329
diff changeset
360 elif line.startswith('GIT binary patch'):
7f486971d263 Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents: 3329
diff changeset
361 gp.binary = True
2861
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
362 if gp:
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
363 gitpatches.append(gp)
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
364
12669
b0fa39c68370 patch: remove unused flags from readgitpatch()
Patrick Mezard <pmezard@gmail.com>
parents: 12645
diff changeset
365 return gitpatches
2861
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
366
8891
5fe8dc75aa4a patch: use new style class in linereader
Simon Heimberg <simohe@besonet.ch>
parents: 8843
diff changeset
367 class linereader(object):
8810
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
368 # 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
369 def __init__(self, fp):
8810
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
370 self.fp = fp
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
371 self.buf = []
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
372
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
373 def push(self, line):
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
374 if line is not None:
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
375 self.buf.append(line)
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
376
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
377 def readline(self):
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
378 if self.buf:
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
379 l = self.buf[0]
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
380 del self.buf[0]
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
381 return l
14418
0174d1f79280 patch: remove EOL support from linereader class
Patrick Mezard <pmezard@gmail.com>
parents: 14402
diff changeset
382 return self.fp.readline()
8810
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
383
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
384 def __iter__(self):
14494
1ffeeb91c55d check-code: flag 0/1 used as constant Boolean expression
Martin Geisler <mg@lazybytes.net>
parents: 14453
diff changeset
385 while True:
8810
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
386 l = self.readline()
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
387 if not l:
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
388 break
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
389 yield l
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
390
14348
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
391 class abstractbackend(object):
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
392 def __init__(self, ui):
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
393 self.ui = ui
14348
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
394
14391
1e64e1e12195 patch: unify backend file access interface
Patrick Mezard <pmezard@gmail.com>
parents: 14390
diff changeset
395 def getfile(self, fname):
1e64e1e12195 patch: unify backend file access interface
Patrick Mezard <pmezard@gmail.com>
parents: 14390
diff changeset
396 """Return target file data and flags as a (data, (islink,
22296
650b5b6e75ed convert: use None value for missing files instead of overloading IOError
Mads Kiilerich <madski@unity3d.com>
parents: 21833
diff changeset
397 isexec)) tuple. Data is None if file is missing/deleted.
14348
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
398 """
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
399 raise NotImplementedError
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
400
14452
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
401 def setfile(self, fname, data, mode, copysource):
14391
1e64e1e12195 patch: unify backend file access interface
Patrick Mezard <pmezard@gmail.com>
parents: 14390
diff changeset
402 """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
403 (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
404 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
405 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
406 """
14348
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
407 raise NotImplementedError
5652
e90e72c6b4c7 patch: write rej files for missing targets (issue 853)
Patrick Mezard <pmezard@gmail.com>
parents: 5651
diff changeset
408
14348
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
409 def unlink(self, fname):
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
410 """Unlink target file."""
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
411 raise NotImplementedError
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
412
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
413 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
414 """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
415 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
416 files.
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
417 """
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
418 pass
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
419
14351
d54f9bbcc640 patch: add lexists() to backends, use it in selectfile()
Patrick Mezard <pmezard@gmail.com>
parents: 14350
diff changeset
420 def exists(self, fname):
d54f9bbcc640 patch: add lexists() to backends, use it in selectfile()
Patrick Mezard <pmezard@gmail.com>
parents: 14350
diff changeset
421 raise NotImplementedError
d54f9bbcc640 patch: add lexists() to backends, use it in selectfile()
Patrick Mezard <pmezard@gmail.com>
parents: 14350
diff changeset
422
14348
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
423 class fsbackend(abstractbackend):
14350
00da6624e167 patch: move copyfile() into backends, abstract basedir
Patrick Mezard <pmezard@gmail.com>
parents: 14349
diff changeset
424 def __init__(self, ui, basedir):
14348
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
425 super(fsbackend, self).__init__(ui)
14350
00da6624e167 patch: move copyfile() into backends, abstract basedir
Patrick Mezard <pmezard@gmail.com>
parents: 14349
diff changeset
426 self.opener = scmutil.opener(basedir)
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
427
14366
992a7e398ddd patch: stop changing current directory before patching
Patrick Mezard <pmezard@gmail.com>
parents: 14352
diff changeset
428 def _join(self, f):
992a7e398ddd patch: stop changing current directory before patching
Patrick Mezard <pmezard@gmail.com>
parents: 14352
diff changeset
429 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
430
14391
1e64e1e12195 patch: unify backend file access interface
Patrick Mezard <pmezard@gmail.com>
parents: 14390
diff changeset
431 def getfile(self, fname):
21717
2a095d3442e0 patch: replace functions in fsbackend to use vfs
Chinmay Joshi <c@chinmayjoshi.com>
parents: 21553
diff changeset
432 if self.opener.islink(fname):
2a095d3442e0 patch: replace functions in fsbackend to use vfs
Chinmay Joshi <c@chinmayjoshi.com>
parents: 21553
diff changeset
433 return (self.opener.readlink(fname), (True, False))
2a095d3442e0 patch: replace functions in fsbackend to use vfs
Chinmay Joshi <c@chinmayjoshi.com>
parents: 21553
diff changeset
434
14531
b88368a3ade4 patch: remove redundant islink() call
Patrick Mezard <pmezard@gmail.com>
parents: 14494
diff changeset
435 isexec = False
7392
564326a6ef9c patch: isolate patchfile filesystem calls into methods
Patrick Mezard <pmezard@gmail.com>
parents: 7391
diff changeset
436 try:
21717
2a095d3442e0 patch: replace functions in fsbackend to use vfs
Chinmay Joshi <c@chinmayjoshi.com>
parents: 21553
diff changeset
437 isexec = self.opener.lstat(fname).st_mode & 0100 != 0
14391
1e64e1e12195 patch: unify backend file access interface
Patrick Mezard <pmezard@gmail.com>
parents: 14390
diff changeset
438 except OSError, e:
1e64e1e12195 patch: unify backend file access interface
Patrick Mezard <pmezard@gmail.com>
parents: 14390
diff changeset
439 if e.errno != errno.ENOENT:
1e64e1e12195 patch: unify backend file access interface
Patrick Mezard <pmezard@gmail.com>
parents: 14390
diff changeset
440 raise
22296
650b5b6e75ed convert: use None value for missing files instead of overloading IOError
Mads Kiilerich <madski@unity3d.com>
parents: 21833
diff changeset
441 try:
650b5b6e75ed convert: use None value for missing files instead of overloading IOError
Mads Kiilerich <madski@unity3d.com>
parents: 21833
diff changeset
442 return (self.opener.read(fname), (False, isexec))
650b5b6e75ed convert: use None value for missing files instead of overloading IOError
Mads Kiilerich <madski@unity3d.com>
parents: 21833
diff changeset
443 except IOError, e:
650b5b6e75ed convert: use None value for missing files instead of overloading IOError
Mads Kiilerich <madski@unity3d.com>
parents: 21833
diff changeset
444 if e.errno != errno.ENOENT:
650b5b6e75ed convert: use None value for missing files instead of overloading IOError
Mads Kiilerich <madski@unity3d.com>
parents: 21833
diff changeset
445 raise
650b5b6e75ed convert: use None value for missing files instead of overloading IOError
Mads Kiilerich <madski@unity3d.com>
parents: 21833
diff changeset
446 return None, None
7392
564326a6ef9c patch: isolate patchfile filesystem calls into methods
Patrick Mezard <pmezard@gmail.com>
parents: 7391
diff changeset
447
14452
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
448 def setfile(self, fname, data, mode, copysource):
14391
1e64e1e12195 patch: unify backend file access interface
Patrick Mezard <pmezard@gmail.com>
parents: 14390
diff changeset
449 islink, isexec = mode
1e64e1e12195 patch: unify backend file access interface
Patrick Mezard <pmezard@gmail.com>
parents: 14390
diff changeset
450 if data is None:
21717
2a095d3442e0 patch: replace functions in fsbackend to use vfs
Chinmay Joshi <c@chinmayjoshi.com>
parents: 21553
diff changeset
451 self.opener.setflags(fname, islink, isexec)
14390
ce77c275bec3 patch: merge backend setmode() into writelines()
Patrick Mezard <pmezard@gmail.com>
parents: 14389
diff changeset
452 return
14391
1e64e1e12195 patch: unify backend file access interface
Patrick Mezard <pmezard@gmail.com>
parents: 14390
diff changeset
453 if islink:
1e64e1e12195 patch: unify backend file access interface
Patrick Mezard <pmezard@gmail.com>
parents: 14390
diff changeset
454 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
455 else:
14391
1e64e1e12195 patch: unify backend file access interface
Patrick Mezard <pmezard@gmail.com>
parents: 14390
diff changeset
456 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
457 if isexec:
21717
2a095d3442e0 patch: replace functions in fsbackend to use vfs
Chinmay Joshi <c@chinmayjoshi.com>
parents: 21553
diff changeset
458 self.opener.setflags(fname, False, True)
7392
564326a6ef9c patch: isolate patchfile filesystem calls into methods
Patrick Mezard <pmezard@gmail.com>
parents: 7391
diff changeset
459
564326a6ef9c patch: isolate patchfile filesystem calls into methods
Patrick Mezard <pmezard@gmail.com>
parents: 7391
diff changeset
460 def unlink(self, fname):
21717
2a095d3442e0 patch: replace functions in fsbackend to use vfs
Chinmay Joshi <c@chinmayjoshi.com>
parents: 21553
diff changeset
461 self.opener.unlinkpath(fname, ignoremissing=True)
7392
564326a6ef9c patch: isolate patchfile filesystem calls into methods
Patrick Mezard <pmezard@gmail.com>
parents: 7391
diff changeset
462
14348
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
463 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
464 fname = fname + ".rej"
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
465 self.ui.warn(
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
466 _("%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
467 (failed, total, fname))
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
468 fp = self.opener(fname, 'w')
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
469 fp.writelines(lines)
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
470 fp.close()
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
471
14351
d54f9bbcc640 patch: add lexists() to backends, use it in selectfile()
Patrick Mezard <pmezard@gmail.com>
parents: 14350
diff changeset
472 def exists(self, fname):
21717
2a095d3442e0 patch: replace functions in fsbackend to use vfs
Chinmay Joshi <c@chinmayjoshi.com>
parents: 21553
diff changeset
473 return self.opener.lexists(fname)
14351
d54f9bbcc640 patch: add lexists() to backends, use it in selectfile()
Patrick Mezard <pmezard@gmail.com>
parents: 14350
diff changeset
474
14370
17cea10c343e patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14369
diff changeset
475 class workingbackend(fsbackend):
17cea10c343e patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14369
diff changeset
476 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
477 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
478 self.repo = repo
17cea10c343e patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14369
diff changeset
479 self.similarity = similarity
17cea10c343e patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14369
diff changeset
480 self.removed = set()
17cea10c343e patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14369
diff changeset
481 self.changed = set()
17cea10c343e patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14369
diff changeset
482 self.copied = []
17cea10c343e patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14369
diff changeset
483
14453
ea3d548132cc patch: do not patch unknown files (issue752)
Patrick Mezard <pmezard@gmail.com>
parents: 14452
diff changeset
484 def _checkknown(self, fname):
ea3d548132cc patch: do not patch unknown files (issue752)
Patrick Mezard <pmezard@gmail.com>
parents: 14452
diff changeset
485 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
486 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
487
14452
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
488 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
489 self._checkknown(fname)
14452
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
490 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
491 if copysource is not None:
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
492 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
493 self.changed.add(fname)
17cea10c343e patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14369
diff changeset
494
17cea10c343e patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14369
diff changeset
495 def unlink(self, fname):
14453
ea3d548132cc patch: do not patch unknown files (issue752)
Patrick Mezard <pmezard@gmail.com>
parents: 14452
diff changeset
496 self._checkknown(fname)
14370
17cea10c343e patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14369
diff changeset
497 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
498 self.removed.add(fname)
17cea10c343e patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14369
diff changeset
499 self.changed.add(fname)
17cea10c343e patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14369
diff changeset
500
17cea10c343e patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14369
diff changeset
501 def close(self):
17cea10c343e patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14369
diff changeset
502 wctx = self.repo[None]
19155
0b3689a08df5 patch: use scmutil.marktouched instead of scmutil.addremove
Siddharth Agarwal <sid0@fb.com>
parents: 18830
diff changeset
503 changed = set(self.changed)
14370
17cea10c343e patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14369
diff changeset
504 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
505 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
506 if self.removed:
14435
5f6090e559fa context: make forget work like commands.forget
Matt Mackall <mpm@selenic.com>
parents: 14418
diff changeset
507 wctx.forget(sorted(self.removed))
16112
d7829b2ecf32 import: handle git renames and --similarity (issue3187)
Patrick Mezard <patrick@mezard.eu>
parents: 15971
diff changeset
508 for f in self.removed:
d7829b2ecf32 import: handle git renames and --similarity (issue3187)
Patrick Mezard <patrick@mezard.eu>
parents: 15971
diff changeset
509 if f not in self.repo.dirstate:
d7829b2ecf32 import: handle git renames and --similarity (issue3187)
Patrick Mezard <patrick@mezard.eu>
parents: 15971
diff changeset
510 # 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
511 # dirstate, it was probably marked added then
d7829b2ecf32 import: handle git renames and --similarity (issue3187)
Patrick Mezard <patrick@mezard.eu>
parents: 15971
diff changeset
512 # deleted, and should not be considered by
19155
0b3689a08df5 patch: use scmutil.marktouched instead of scmutil.addremove
Siddharth Agarwal <sid0@fb.com>
parents: 18830
diff changeset
513 # marktouched().
0b3689a08df5 patch: use scmutil.marktouched instead of scmutil.addremove
Siddharth Agarwal <sid0@fb.com>
parents: 18830
diff changeset
514 changed.discard(f)
0b3689a08df5 patch: use scmutil.marktouched instead of scmutil.addremove
Siddharth Agarwal <sid0@fb.com>
parents: 18830
diff changeset
515 if changed:
0b3689a08df5 patch: use scmutil.marktouched instead of scmutil.addremove
Siddharth Agarwal <sid0@fb.com>
parents: 18830
diff changeset
516 scmutil.marktouched(self.repo, changed, self.similarity)
14370
17cea10c343e patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14369
diff changeset
517 return sorted(self.changed)
17cea10c343e patch: add a workingbackend dirstate layer on top of fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14369
diff changeset
518
14452
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
519 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
520 def __init__(self, maxsize=None):
14452
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
521 self.opener = None
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
522 self.files = {}
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
523 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
524 self.maxsize = maxsize
7ddf9a607b75 patch: make filestore store data in memory and fallback to fs
Patrick Mezard <pmezard@gmail.com>
parents: 14611
diff changeset
525 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
526 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
527 self.size = 0
7ddf9a607b75 patch: make filestore store data in memory and fallback to fs
Patrick Mezard <pmezard@gmail.com>
parents: 14611
diff changeset
528 self.data = {}
14452
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
529
14609
f53dc0787424 patch: extend filtestore to store an optional copy source
Patrick Mezard <pmezard@gmail.com>
parents: 14566
diff changeset
530 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
531 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
532 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
533 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
534 else:
7ddf9a607b75 patch: make filestore store data in memory and fallback to fs
Patrick Mezard <pmezard@gmail.com>
parents: 14611
diff changeset
535 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
536 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
537 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
538 # 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
539 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
540 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
541 self.created += 1
7ddf9a607b75 patch: make filestore store data in memory and fallback to fs
Patrick Mezard <pmezard@gmail.com>
parents: 14611
diff changeset
542 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
543
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
544 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
545 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
546 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
547 if not self.opener or fname not in self.files:
22296
650b5b6e75ed convert: use None value for missing files instead of overloading IOError
Mads Kiilerich <madski@unity3d.com>
parents: 21833
diff changeset
548 return None, None, None
14609
f53dc0787424 patch: extend filtestore to store an optional copy source
Patrick Mezard <pmezard@gmail.com>
parents: 14566
diff changeset
549 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
550 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
551
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
552 def close(self):
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
553 if self.opener:
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
554 shutil.rmtree(self.opener.base)
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
555
14611
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
556 class repobackend(abstractbackend):
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
557 def __init__(self, ui, repo, ctx, store):
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
558 super(repobackend, self).__init__(ui)
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
559 self.repo = repo
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
560 self.ctx = ctx
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
561 self.store = store
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
562 self.changed = set()
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
563 self.removed = set()
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
564 self.copied = {}
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
565
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
566 def _checkknown(self, fname):
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
567 if fname not in self.ctx:
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
568 raise PatchError(_('cannot patch %s: file is not tracked') % fname)
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
569
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
570 def getfile(self, fname):
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
571 try:
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
572 fctx = self.ctx[fname]
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
573 except error.LookupError:
22296
650b5b6e75ed convert: use None value for missing files instead of overloading IOError
Mads Kiilerich <madski@unity3d.com>
parents: 21833
diff changeset
574 return None, None
14611
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
575 flags = fctx.flags()
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
576 return fctx.data(), ('l' in flags, 'x' in flags)
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
577
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
578 def setfile(self, fname, data, mode, copysource):
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
579 if copysource:
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
580 self._checkknown(copysource)
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
581 if data is None:
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
582 data = self.ctx[fname].data()
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
583 self.store.setfile(fname, data, mode, copysource)
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
584 self.changed.add(fname)
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
585 if copysource:
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
586 self.copied[fname] = copysource
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
587
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
588 def unlink(self, fname):
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
589 self._checkknown(fname)
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
590 self.removed.add(fname)
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
591
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
592 def exists(self, fname):
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
593 return fname in self.ctx
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
594
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
595 def close(self):
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
596 return self.changed | self.removed
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
597
14348
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
598 # @@ -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
599 unidesc = re.compile('@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@')
5414b56cfad6 patch: simplify hunk extents parsing
Patrick Mezard <pmezard@gmail.com>
parents: 15462
diff changeset
600 contextdesc = re.compile('(?:---|\*\*\*) (\d+)(?:,(\d+))? (?:---|\*\*\*)')
14348
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
601 eolmodes = ['strict', 'crlf', 'lf', 'auto']
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
602
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
603 class patchfile(object):
14566
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
604 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
605 self.fname = gp.path
14348
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
606 self.eolmode = eolmode
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
607 self.eol = None
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
608 self.backend = backend
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
609 self.ui = ui
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
610 self.lines = []
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
611 self.exists = False
14452
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
612 self.missing = True
14566
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
613 self.mode = gp.mode
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
614 self.copysource = gp.oldpath
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
615 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
616 self.remove = gp.op == 'DELETE'
22296
650b5b6e75ed convert: use None value for missing files instead of overloading IOError
Mads Kiilerich <madski@unity3d.com>
parents: 21833
diff changeset
617 if self.copysource is None:
650b5b6e75ed convert: use None value for missing files instead of overloading IOError
Mads Kiilerich <madski@unity3d.com>
parents: 21833
diff changeset
618 data, mode = backend.getfile(self.fname)
650b5b6e75ed convert: use None value for missing files instead of overloading IOError
Mads Kiilerich <madski@unity3d.com>
parents: 21833
diff changeset
619 else:
650b5b6e75ed convert: use None value for missing files instead of overloading IOError
Mads Kiilerich <madski@unity3d.com>
parents: 21833
diff changeset
620 data, mode = store.getfile(self.copysource)[:2]
650b5b6e75ed convert: use None value for missing files instead of overloading IOError
Mads Kiilerich <madski@unity3d.com>
parents: 21833
diff changeset
621 if data is not None:
650b5b6e75ed convert: use None value for missing files instead of overloading IOError
Mads Kiilerich <madski@unity3d.com>
parents: 21833
diff changeset
622 self.exists = self.copysource is None or backend.exists(self.fname)
14452
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
623 self.missing = False
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
624 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
625 self.lines = mdiff.splitnewlines(data)
14452
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
626 if self.mode is None:
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
627 self.mode = mode
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
628 if self.lines:
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
629 # Normalize line endings
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
630 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
631 self.eol = '\r\n'
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
632 elif self.lines[0].endswith('\n'):
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
633 self.eol = '\n'
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
634 if eolmode != 'strict':
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
635 nlines = []
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
636 for l in self.lines:
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
637 if l.endswith('\r\n'):
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
638 l = l[:-2] + '\n'
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
639 nlines.append(l)
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
640 self.lines = nlines
22296
650b5b6e75ed convert: use None value for missing files instead of overloading IOError
Mads Kiilerich <madski@unity3d.com>
parents: 21833
diff changeset
641 else:
14566
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
642 if self.create:
14452
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
643 self.missing = False
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
644 if self.mode is None:
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
645 self.mode = (False, False)
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
646 if self.missing:
17299
e51d4aedace9 check-code: indent 4 spaces in py files
Mads Kiilerich <mads@kiilerich.com>
parents: 16834
diff changeset
647 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
648
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
649 self.hash = {}
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
650 self.dirty = 0
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
651 self.offset = 0
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
652 self.skew = 0
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
653 self.rej = []
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
654 self.fileprinted = False
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
655 self.printfile(False)
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
656 self.hunks = 0
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
657
14367
468d7d1744b4 patch: set desired mode when patching, not in updatedir()
Patrick Mezard <pmezard@gmail.com>
parents: 14366
diff changeset
658 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
659 if self.eolmode == 'auto':
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
660 eol = self.eol
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
661 elif self.eolmode == 'crlf':
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
662 eol = '\r\n'
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
663 else:
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
664 eol = '\n'
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
665
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
666 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
667 rawlines = []
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
668 for l in lines:
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
669 if l and l[-1] == '\n':
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
670 l = l[:-1] + eol
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
671 rawlines.append(l)
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
672 lines = rawlines
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
673
14452
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
674 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
675
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
676 def printfile(self, warn):
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
677 if self.fileprinted:
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
678 return
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
679 if warn or self.ui.verbose:
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
680 self.fileprinted = True
4898
bc905a6c0e76 patch.py: fix some incorrect uses of _() for i18n
Bryan O'Sullivan <bos@serpentine.com>
parents: 4897
diff changeset
681 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
682 if warn:
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
683 self.ui.warn(s)
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
684 else:
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
685 self.ui.note(s)
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
686
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
687
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
688 def findlines(self, l, linenum):
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
689 # 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
690 # 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
691 # from linenum
5143
d4fa6bafc43a Remove trailing spaces, fix indentation
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5116
diff changeset
692
9681
ac3a68cb16eb patch: simplify logic
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9642
diff changeset
693 cand = self.hash.get(l, [])
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
694 if len(cand) > 1:
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
695 # 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
696 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
697 return cand
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
698
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
699 def write_rej(self):
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
700 # 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
701 # 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
702 # 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
703 # without having to type the filename.
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
704 if not self.rej:
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
705 return
14349
776ae95b8835 patch: merge makerejlines() into write_rej()
Patrick Mezard <pmezard@gmail.com>
parents: 14348
diff changeset
706 base = os.path.basename(self.fname)
776ae95b8835 patch: merge makerejlines() into write_rej()
Patrick Mezard <pmezard@gmail.com>
parents: 14348
diff changeset
707 lines = ["--- %s\n+++ %s\n" % (base, base)]
776ae95b8835 patch: merge makerejlines() into write_rej()
Patrick Mezard <pmezard@gmail.com>
parents: 14348
diff changeset
708 for x in self.rej:
776ae95b8835 patch: merge makerejlines() into write_rej()
Patrick Mezard <pmezard@gmail.com>
parents: 14348
diff changeset
709 for l in x.hunk:
776ae95b8835 patch: merge makerejlines() into write_rej()
Patrick Mezard <pmezard@gmail.com>
parents: 14348
diff changeset
710 lines.append(l)
776ae95b8835 patch: merge makerejlines() into write_rej()
Patrick Mezard <pmezard@gmail.com>
parents: 14348
diff changeset
711 if l[-1] != '\n':
776ae95b8835 patch: merge makerejlines() into write_rej()
Patrick Mezard <pmezard@gmail.com>
parents: 14348
diff changeset
712 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
713 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
714
9393
23c4e772c172 patch: remove the unused, broken reverse() function
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9392
diff changeset
715 def apply(self, h):
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
716 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
717 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
718 (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
719 h.lenb))
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
720
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
721 self.hunks += 1
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
722
5652
e90e72c6b4c7 patch: write rej files for missing targets (issue 853)
Patrick Mezard <pmezard@gmail.com>
parents: 5651
diff changeset
723 if self.missing:
e90e72c6b4c7 patch: write rej files for missing targets (issue 853)
Patrick Mezard <pmezard@gmail.com>
parents: 5651
diff changeset
724 self.rej.append(h)
e90e72c6b4c7 patch: write rej files for missing targets (issue 853)
Patrick Mezard <pmezard@gmail.com>
parents: 5651
diff changeset
725 return -1
e90e72c6b4c7 patch: write rej files for missing targets (issue 853)
Patrick Mezard <pmezard@gmail.com>
parents: 5651
diff changeset
726
14451
c78d41db6f88 patch: refactor file creation/removal detection
Patrick Mezard <pmezard@gmail.com>
parents: 14437
diff changeset
727 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
728 if self.copysource:
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
729 self.ui.warn(_("cannot create %s: destination already "
20869
9658a79968c6 i18n: fix "% inside _()" problems
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20137
diff changeset
730 "exists\n") % self.fname)
14452
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
731 else:
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
732 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
733 self.rej.append(h)
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
734 return -1
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
735
9585
ea1935e2020a patch: handle symlinks without symlinkhunk
Patrick Mezard <pmezard@gmail.com>
parents: 9573
diff changeset
736 if isinstance(h, binhunk):
14451
c78d41db6f88 patch: refactor file creation/removal detection
Patrick Mezard <pmezard@gmail.com>
parents: 14437
diff changeset
737 if self.remove:
14348
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
738 self.backend.unlink(self.fname)
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
739 else:
20137
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
740 l = h.new(self.lines)
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
741 self.lines[:] = l
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
742 self.offset += len(l)
14217
71d5287351e9 patchfile: use real Booleans instead of 0/1
Martin Geisler <mg@aragost.com>
parents: 14017
diff changeset
743 self.dirty = True
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
744 return 0
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
745
10127
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
746 horig = h
10128
ea7c392f2b08 patch: drop eol normalization fast-path for 'lf' and 'crlf'
Patrick Mezard <pmezard@gmail.com>
parents: 10127
diff changeset
747 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
748 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
749 # 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
750 # 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
751 # line-endings.
10127
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
752 h = h.getnormalized()
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
753
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
754 # 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
755 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
756 oldstart += self.offset
9ef3a4a2c6c0 patch: make hunk.fuzzit() compute the fuzzed start locations
Patrick Mezard <patrick@mezard.eu>
parents: 16121
diff changeset
757 orig_start = oldstart
10135
9a4034b630c4 patch: better handling of sequence of offset patch hunks (issue1941)
Greg Onufer <gonufer@jazzhaiku.com>
parents: 9725
diff changeset
758 # 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
759 # 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
760 # fast case code
16122
9ef3a4a2c6c0 patch: make hunk.fuzzit() compute the fuzzed start locations
Patrick Mezard <patrick@mezard.eu>
parents: 16121
diff changeset
761 if (self.skew == 0 and
9ef3a4a2c6c0 patch: make hunk.fuzzit() compute the fuzzed start locations
Patrick Mezard <patrick@mezard.eu>
parents: 16121
diff changeset
762 diffhelpers.testhunk(old, self.lines, oldstart) == 0):
14451
c78d41db6f88 patch: refactor file creation/removal detection
Patrick Mezard <pmezard@gmail.com>
parents: 14437
diff changeset
763 if self.remove:
14348
c1c719103392 patch: extract fs access from patchfile into fsbackend
Patrick Mezard <pmezard@gmail.com>
parents: 14347
diff changeset
764 self.backend.unlink(self.fname)
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
765 else:
16122
9ef3a4a2c6c0 patch: make hunk.fuzzit() compute the fuzzed start locations
Patrick Mezard <patrick@mezard.eu>
parents: 16121
diff changeset
766 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
767 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
768 self.dirty = True
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
769 return 0
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
770
13700
63307feb59dd patch: inline patchfile.hashlines()
Patrick Mezard <pmezard@gmail.com>
parents: 13699
diff changeset
771 # 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
772 self.hash = {}
63307feb59dd patch: inline patchfile.hashlines()
Patrick Mezard <pmezard@gmail.com>
parents: 13699
diff changeset
773 for x, s in enumerate(self.lines):
63307feb59dd patch: inline patchfile.hashlines()
Patrick Mezard <pmezard@gmail.com>
parents: 13699
diff changeset
774 self.hash.setdefault(s, []).append(x)
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
775
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
776 for fuzzlen in xrange(3):
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
777 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
778 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
779 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
780 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
781 if old:
b0c7525f826d patch: fix fuzzing of hunks without previous lines (issue3264)
Patrick Mezard <patrick@mezard.eu>
parents: 16122
diff changeset
782 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
783 else:
b0c7525f826d patch: fix fuzzing of hunks without previous lines (issue3264)
Patrick Mezard <patrick@mezard.eu>
parents: 16122
diff changeset
784 # 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
785 # take the skew in account
b0c7525f826d patch: fix fuzzing of hunks without previous lines (issue3264)
Patrick Mezard <patrick@mezard.eu>
parents: 16122
diff changeset
786 cand = [oldstart]
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
787
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
788 for l in cand:
16123
b0c7525f826d patch: fix fuzzing of hunks without previous lines (issue3264)
Patrick Mezard <patrick@mezard.eu>
parents: 16122
diff changeset
789 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
790 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
791 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
792 self.skew = l - orig_start
14217
71d5287351e9 patchfile: use real Booleans instead of 0/1
Martin Geisler <mg@aragost.com>
parents: 14017
diff changeset
793 self.dirty = True
10518
5fe51d348daf patch, i18n: avoid parameterized messages
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 10501
diff changeset
794 offset = l - orig_start - fuzzlen
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
795 if fuzzlen:
10518
5fe51d348daf patch, i18n: avoid parameterized messages
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 10501
diff changeset
796 msg = _("Hunk #%d succeeded at %d "
5fe51d348daf patch, i18n: avoid parameterized messages
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 10501
diff changeset
797 "with fuzz %d "
5fe51d348daf patch, i18n: avoid parameterized messages
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 10501
diff changeset
798 "(offset %d lines).\n")
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
799 self.printfile(True)
10518
5fe51d348daf patch, i18n: avoid parameterized messages
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 10501
diff changeset
800 self.ui.warn(msg %
5fe51d348daf patch, i18n: avoid parameterized messages
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 10501
diff changeset
801 (h.number, l + 1, fuzzlen, offset))
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
802 else:
10518
5fe51d348daf patch, i18n: avoid parameterized messages
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 10501
diff changeset
803 msg = _("Hunk #%d succeeded at %d "
8090
388bb482024e patch, i18n: avoid parameterized plural
Wagner Bruna <wbruna@yahoo.com>
parents: 7972
diff changeset
804 "(offset %d lines).\n")
10518
5fe51d348daf patch, i18n: avoid parameterized messages
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 10501
diff changeset
805 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
806 return fuzzlen
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
807 self.printfile(True)
4898
bc905a6c0e76 patch.py: fix some incorrect uses of _() for i18n
Bryan O'Sullivan <bos@serpentine.com>
parents: 4897
diff changeset
808 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
809 self.rej.append(horig)
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
810 return -1
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
811
13701
bc38ff7cb919 patch: move closefile() into patchfile.close()
Patrick Mezard <pmezard@gmail.com>
parents: 13700
diff changeset
812 def close(self):
bc38ff7cb919 patch: move closefile() into patchfile.close()
Patrick Mezard <pmezard@gmail.com>
parents: 13700
diff changeset
813 if self.dirty:
14367
468d7d1744b4 patch: set desired mode when patching, not in updatedir()
Patrick Mezard <pmezard@gmail.com>
parents: 14366
diff changeset
814 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
815 self.write_rej()
bc38ff7cb919 patch: move closefile() into patchfile.close()
Patrick Mezard <pmezard@gmail.com>
parents: 13700
diff changeset
816 return len(self.rej)
bc38ff7cb919 patch: move closefile() into patchfile.close()
Patrick Mezard <pmezard@gmail.com>
parents: 13700
diff changeset
817
24261
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
818 class header(object):
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
819 """patch header
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
820 """
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
821 diffgit_re = re.compile('diff --git a/(.*) b/(.*)$')
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
822 diff_re = re.compile('diff -r .* (.*)$')
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
823 allhunks_re = re.compile('(?:index|deleted file) ')
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
824 pretty_re = re.compile('(?:new file|deleted file) ')
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
825 special_re = re.compile('(?:index|new|deleted|copy|rename) ')
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
826
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
827 def __init__(self, header):
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
828 self.header = header
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
829 self.hunks = []
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
830
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
831 def binary(self):
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
832 return util.any(h.startswith('index ') for h in self.header)
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
833
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
834 def pretty(self, fp):
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
835 for h in self.header:
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
836 if h.startswith('index '):
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
837 fp.write(_('this modifies a binary file (all or nothing)\n'))
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
838 break
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
839 if self.pretty_re.match(h):
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
840 fp.write(h)
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
841 if self.binary():
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
842 fp.write(_('this is a binary file\n'))
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
843 break
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
844 if h.startswith('---'):
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
845 fp.write(_('%d hunks, %d lines changed\n') %
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
846 (len(self.hunks),
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
847 sum([max(h.added, h.removed) for h in self.hunks])))
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
848 break
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
849 fp.write(h)
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
850
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
851 def write(self, fp):
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
852 fp.write(''.join(self.header))
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
853
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
854 def allhunks(self):
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
855 return util.any(self.allhunks_re.match(h) for h in self.header)
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
856
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
857 def files(self):
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
858 match = self.diffgit_re.match(self.header[0])
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
859 if match:
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
860 fromfile, tofile = match.groups()
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
861 if fromfile == tofile:
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
862 return [fromfile]
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
863 return [fromfile, tofile]
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
864 else:
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
865 return self.diff_re.match(self.header[0]).groups()
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
866
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
867 def filename(self):
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
868 return self.files()[-1]
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
869
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
870 def __repr__(self):
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
871 return '<header %s>' % (' '.join(map(repr, self.files())))
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
872
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
873 def special(self):
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
874 return util.any(self.special_re.match(h) for h in self.header)
20aac24e2114 record: move header class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24260
diff changeset
875
24263
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
876 class recordhunk(object):
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
877 """patch hunk
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
878
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
879 XXX shouldn't we merge this with the other hunk class?
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
880 """
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
881 maxcontext = 3
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
882
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
883 def __init__(self, header, fromline, toline, proc, before, hunk, after):
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
884 def trimcontext(number, lines):
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
885 delta = len(lines) - self.maxcontext
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
886 if False and delta > 0:
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
887 return number + delta, lines[:self.maxcontext]
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
888 return number, lines
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
889
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
890 self.header = header
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
891 self.fromline, self.before = trimcontext(fromline, before)
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
892 self.toline, self.after = trimcontext(toline, after)
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
893 self.proc = proc
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
894 self.hunk = hunk
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
895 self.added, self.removed = self.countchanges(self.hunk)
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
896
24346
31edcea517c1 record: add comparison methods for recordhunk class
Laurent Charignon <lcharignon@fb.com>
parents: 24341
diff changeset
897 def __eq__(self, v):
31edcea517c1 record: add comparison methods for recordhunk class
Laurent Charignon <lcharignon@fb.com>
parents: 24341
diff changeset
898 if not isinstance(v, recordhunk):
31edcea517c1 record: add comparison methods for recordhunk class
Laurent Charignon <lcharignon@fb.com>
parents: 24341
diff changeset
899 return False
31edcea517c1 record: add comparison methods for recordhunk class
Laurent Charignon <lcharignon@fb.com>
parents: 24341
diff changeset
900
31edcea517c1 record: add comparison methods for recordhunk class
Laurent Charignon <lcharignon@fb.com>
parents: 24341
diff changeset
901 return ((v.hunk == self.hunk) and
31edcea517c1 record: add comparison methods for recordhunk class
Laurent Charignon <lcharignon@fb.com>
parents: 24341
diff changeset
902 (v.proc == self.proc) and
31edcea517c1 record: add comparison methods for recordhunk class
Laurent Charignon <lcharignon@fb.com>
parents: 24341
diff changeset
903 (self.fromline == v.fromline) and
31edcea517c1 record: add comparison methods for recordhunk class
Laurent Charignon <lcharignon@fb.com>
parents: 24341
diff changeset
904 (self.header.files() == v.header.files()))
31edcea517c1 record: add comparison methods for recordhunk class
Laurent Charignon <lcharignon@fb.com>
parents: 24341
diff changeset
905
31edcea517c1 record: add comparison methods for recordhunk class
Laurent Charignon <lcharignon@fb.com>
parents: 24341
diff changeset
906 def __hash__(self):
31edcea517c1 record: add comparison methods for recordhunk class
Laurent Charignon <lcharignon@fb.com>
parents: 24341
diff changeset
907 return hash((tuple(self.hunk),
31edcea517c1 record: add comparison methods for recordhunk class
Laurent Charignon <lcharignon@fb.com>
parents: 24341
diff changeset
908 tuple(self.header.files()),
31edcea517c1 record: add comparison methods for recordhunk class
Laurent Charignon <lcharignon@fb.com>
parents: 24341
diff changeset
909 self.fromline,
31edcea517c1 record: add comparison methods for recordhunk class
Laurent Charignon <lcharignon@fb.com>
parents: 24341
diff changeset
910 self.proc))
31edcea517c1 record: add comparison methods for recordhunk class
Laurent Charignon <lcharignon@fb.com>
parents: 24341
diff changeset
911
24263
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
912 def countchanges(self, hunk):
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
913 """hunk -> (n+,n-)"""
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
914 add = len([h for h in hunk if h[0] == '+'])
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
915 rem = len([h for h in hunk if h[0] == '-'])
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
916 return add, rem
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
917
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
918 def write(self, fp):
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
919 delta = len(self.before) + len(self.after)
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
920 if self.after and self.after[-1] == '\\ No newline at end of file\n':
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
921 delta -= 1
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
922 fromlen = delta + self.removed
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
923 tolen = delta + self.added
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
924 fp.write('@@ -%d,%d +%d,%d @@%s\n' %
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
925 (self.fromline, fromlen, self.toline, tolen,
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
926 self.proc and (' ' + self.proc)))
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
927 fp.write(''.join(self.before + self.hunk + self.after))
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
928
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
929 pretty = write
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
930
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
931 def filename(self):
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
932 return self.header.filename()
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
933
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
934 def __repr__(self):
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
935 return '<hunk %r@%d>' % (self.filename(), self.fromline)
a45d1c51109e record: move hunk class from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24261
diff changeset
936
24269
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
937 def filterpatch(ui, headers):
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
938 """Interactively filter patch chunks into applied-only chunks"""
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
939
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
940 def prompt(skipfile, skipall, query, chunk):
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
941 """prompt query, and process base inputs
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
942
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
943 - y/n for the rest of file
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
944 - y/n for the rest
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
945 - ? (help)
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
946 - q (quit)
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
947
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
948 Return True/False and possibly updated skipfile and skipall.
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
949 """
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
950 newpatches = None
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
951 if skipall is not None:
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
952 return skipall, skipfile, skipall, newpatches
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
953 if skipfile is not None:
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
954 return skipfile, skipfile, skipall, newpatches
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
955 while True:
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
956 resps = _('[Ynesfdaq?]'
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
957 '$$ &Yes, record this change'
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
958 '$$ &No, skip this change'
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
959 '$$ &Edit this change manually'
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
960 '$$ &Skip remaining changes to this file'
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
961 '$$ Record remaining changes to this &file'
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
962 '$$ &Done, skip remaining changes and files'
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
963 '$$ Record &all changes to all remaining files'
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
964 '$$ &Quit, recording no changes'
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
965 '$$ &? (display help)')
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
966 r = ui.promptchoice("%s %s" % (query, resps))
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
967 ui.write("\n")
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
968 if r == 8: # ?
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
969 for c, t in ui.extractchoices(resps)[1]:
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
970 ui.write('%s - %s\n' % (c, t.lower()))
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
971 continue
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
972 elif r == 0: # yes
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
973 ret = True
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
974 elif r == 1: # no
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
975 ret = False
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
976 elif r == 2: # Edit patch
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
977 if chunk is None:
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
978 ui.write(_('cannot edit patch for whole file'))
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
979 ui.write("\n")
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
980 continue
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
981 if chunk.header.binary():
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
982 ui.write(_('cannot edit patch for binary file'))
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
983 ui.write("\n")
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
984 continue
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
985 # Patch comment based on the Git one (based on comment at end of
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
986 # http://mercurial.selenic.com/wiki/RecordExtension)
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
987 phelp = '---' + _("""
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
988 To remove '-' lines, make them ' ' lines (context).
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
989 To remove '+' lines, delete them.
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
990 Lines starting with # will be removed from the patch.
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
991
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
992 If the patch applies cleanly, the edited hunk will immediately be
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
993 added to the record list. If it does not apply cleanly, a rejects
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
994 file will be generated: you can use that when you try again. If
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
995 all lines of the hunk are removed, then the edit is aborted and
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
996 the hunk is left unchanged.
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
997 """)
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
998 (patchfd, patchfn) = tempfile.mkstemp(prefix="hg-editor-",
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
999 suffix=".diff", text=True)
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1000 ncpatchfp = None
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1001 try:
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1002 # Write the initial patch
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1003 f = os.fdopen(patchfd, "w")
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1004 chunk.header.write(f)
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1005 chunk.write(f)
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1006 f.write('\n'.join(['# ' + i for i in phelp.splitlines()]))
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1007 f.close()
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1008 # Start the editor and wait for it to complete
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1009 editor = ui.geteditor()
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1010 ui.system("%s \"%s\"" % (editor, patchfn),
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1011 environ={'HGUSER': ui.username()},
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1012 onerr=util.Abort, errprefix=_("edit failed"))
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1013 # Remove comment lines
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1014 patchfp = open(patchfn)
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1015 ncpatchfp = cStringIO.StringIO()
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1016 for line in patchfp:
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1017 if not line.startswith('#'):
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1018 ncpatchfp.write(line)
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1019 patchfp.close()
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1020 ncpatchfp.seek(0)
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1021 newpatches = parsepatch(ncpatchfp)
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1022 finally:
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1023 os.unlink(patchfn)
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1024 del ncpatchfp
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1025 # Signal that the chunk shouldn't be applied as-is, but
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1026 # provide the new patch to be used instead.
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1027 ret = False
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1028 elif r == 3: # Skip
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1029 ret = skipfile = False
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1030 elif r == 4: # file (Record remaining)
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1031 ret = skipfile = True
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1032 elif r == 5: # done, skip remaining
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1033 ret = skipall = False
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1034 elif r == 6: # all
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1035 ret = skipall = True
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1036 elif r == 7: # quit
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1037 raise util.Abort(_('user quit'))
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1038 return ret, skipfile, skipall, newpatches
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1039
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1040 seen = set()
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1041 applied = {} # 'filename' -> [] of chunks
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1042 skipfile, skipall = None, None
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1043 pos, total = 1, sum(len(h.hunks) for h in headers)
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1044 for h in headers:
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1045 pos += len(h.hunks)
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1046 skipfile = None
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1047 fixoffset = 0
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1048 hdr = ''.join(h.header)
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1049 if hdr in seen:
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1050 continue
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1051 seen.add(hdr)
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1052 if skipall is None:
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1053 h.pretty(ui)
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1054 msg = (_('examine changes to %s?') %
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1055 _(' and ').join("'%s'" % f for f in h.files()))
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1056 r, skipfile, skipall, np = prompt(skipfile, skipall, msg, None)
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1057 if not r:
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1058 continue
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1059 applied[h.filename()] = [h]
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1060 if h.allhunks():
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1061 applied[h.filename()] += h.hunks
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1062 continue
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1063 for i, chunk in enumerate(h.hunks):
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1064 if skipfile is None and skipall is None:
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1065 chunk.pretty(ui)
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1066 if total == 1:
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1067 msg = _("record this change to '%s'?") % chunk.filename()
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1068 else:
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1069 idx = pos - len(h.hunks) + i
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1070 msg = _("record change %d/%d to '%s'?") % (idx, total,
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1071 chunk.filename())
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1072 r, skipfile, skipall, newpatches = prompt(skipfile,
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1073 skipall, msg, chunk)
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1074 if r:
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1075 if fixoffset:
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1076 chunk = copy.copy(chunk)
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1077 chunk.toline += fixoffset
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1078 applied[chunk.filename()].append(chunk)
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1079 elif newpatches is not None:
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1080 for newpatch in newpatches:
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1081 for newhunk in newpatch.hunks:
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1082 if fixoffset:
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1083 newhunk.toline += fixoffset
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1084 applied[newhunk.filename()].append(newhunk)
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1085 else:
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1086 fixoffset += chunk.removed - chunk.added
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1087 return sum([h for h in applied.itervalues()
9a745ced79a9 record: move filterpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24268
diff changeset
1088 if h[0].special() or len(h) > 1], [])
8778
c5f36402daad use new style classes
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8761
diff changeset
1089 class hunk(object):
14451
c78d41db6f88 patch: refactor file creation/removal detection
Patrick Mezard <pmezard@gmail.com>
parents: 14437
diff changeset
1090 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
1091 self.number = num
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1092 self.desc = desc
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
1093 self.hunk = [desc]
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1094 self.a = []
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1095 self.b = []
9682
bd70f645cfb0 patch: initialize all attributes of the hunk class
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9681
diff changeset
1096 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
1097 self.startb = self.lenb = None
10127
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
1098 if lr is not None:
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
1099 if context:
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
1100 self.read_context_hunk(lr)
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
1101 else:
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
1102 self.read_unified_hunk(lr)
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1103
10127
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
1104 def getnormalized(self):
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
1105 """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
1106
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
1107 def normalize(lines):
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
1108 nlines = []
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
1109 for line in lines:
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
1110 if line.endswith('\r\n'):
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
1111 line = line[:-2] + '\n'
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
1112 nlines.append(line)
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
1113 return nlines
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
1114
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
1115 # Dummy object, it is rebuilt manually
14451
c78d41db6f88 patch: refactor file creation/removal detection
Patrick Mezard <pmezard@gmail.com>
parents: 14437
diff changeset
1116 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
1117 nh.number = self.number
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
1118 nh.desc = self.desc
10524
3212afb33116 patch: fix patching with fuzz and eol normalization
Patrick Mezard <pmezard@gmail.com>
parents: 10518
diff changeset
1119 nh.hunk = self.hunk
10127
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
1120 nh.a = normalize(self.a)
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
1121 nh.b = normalize(self.b)
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
1122 nh.starta = self.starta
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
1123 nh.startb = self.startb
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
1124 nh.lena = self.lena
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
1125 nh.lenb = self.lenb
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
1126 return nh
d8214e944b84 patch: fix eolmode=auto with new files
Patrick Mezard <pmezard@gmail.com>
parents: 10102
diff changeset
1127
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1128 def read_unified_hunk(self, lr):
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1129 m = unidesc.match(self.desc)
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1130 if not m:
4898
bc905a6c0e76 patch.py: fix some incorrect uses of _() for i18n
Bryan O'Sullivan <bos@serpentine.com>
parents: 4897
diff changeset
1131 raise PatchError(_("bad hunk #%d") % self.number)
15510
5414b56cfad6 patch: simplify hunk extents parsing
Patrick Mezard <pmezard@gmail.com>
parents: 15462
diff changeset
1132 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
1133 if self.lena is None:
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1134 self.lena = 1
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1135 else:
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1136 self.lena = int(self.lena)
8527
f9a80054dd3c use 'x is None' instead of 'x == None'
Martin Geisler <mg@lazybytes.net>
parents: 8526
diff changeset
1137 if self.lenb is None:
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1138 self.lenb = 1
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1139 else:
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1140 self.lenb = int(self.lenb)
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1141 self.starta = int(self.starta)
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1142 self.startb = int(self.startb)
16683
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16662
diff changeset
1143 diffhelpers.addlines(lr, self.hunk, self.lena, self.lenb, self.a,
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16662
diff changeset
1144 self.b)
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1145 # 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
1146 # 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
1147 while len(self.hunk[-1]) == 0:
6948
359e93ceee3a fix double indentation and trailing whitespace
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6884
diff changeset
1148 del self.hunk[-1]
359e93ceee3a fix double indentation and trailing whitespace
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6884
diff changeset
1149 del self.a[-1]
359e93ceee3a fix double indentation and trailing whitespace
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6884
diff changeset
1150 del self.b[-1]
359e93ceee3a fix double indentation and trailing whitespace
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6884
diff changeset
1151 self.lena -= 1
359e93ceee3a fix double indentation and trailing whitespace
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6884
diff changeset
1152 self.lenb -= 1
13699
d3c0e0033f13 patch: fix hunk newlines when parsing hunks, not in iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 13395
diff changeset
1153 self._fixnewline(lr)
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1154
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1155 def read_context_hunk(self, lr):
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1156 self.desc = lr.readline()
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1157 m = contextdesc.match(self.desc)
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1158 if not m:
4898
bc905a6c0e76 patch.py: fix some incorrect uses of _() for i18n
Bryan O'Sullivan <bos@serpentine.com>
parents: 4897
diff changeset
1159 raise PatchError(_("bad hunk #%d") % self.number)
15510
5414b56cfad6 patch: simplify hunk extents parsing
Patrick Mezard <pmezard@gmail.com>
parents: 15462
diff changeset
1160 self.starta, aend = m.groups()
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1161 self.starta = int(self.starta)
8527
f9a80054dd3c use 'x is None' instead of 'x == None'
Martin Geisler <mg@lazybytes.net>
parents: 8526
diff changeset
1162 if aend is None:
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1163 aend = self.starta
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1164 self.lena = int(aend) - self.starta
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1165 if self.starta:
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1166 self.lena += 1
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1167 for x in xrange(self.lena):
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1168 l = lr.readline()
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1169 if l.startswith('---'):
12825
61f48581d8ef Test applying context diffs
Patrick Mezard <pmezard@gmail.com>
parents: 12728
diff changeset
1170 # lines addition, old block is empty
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1171 lr.push(l)
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1172 break
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1173 s = l[2:]
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1174 if l.startswith('- ') or l.startswith('! '):
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1175 u = '-' + s
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1176 elif l.startswith(' '):
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1177 u = ' ' + s
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1178 else:
4898
bc905a6c0e76 patch.py: fix some incorrect uses of _() for i18n
Bryan O'Sullivan <bos@serpentine.com>
parents: 4897
diff changeset
1179 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
1180 (self.number, x))
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1181 self.a.append(u)
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1182 self.hunk.append(u)
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1183
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1184 l = lr.readline()
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1185 if l.startswith('\ '):
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1186 s = self.a[-1][:-1]
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1187 self.a[-1] = s
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1188 self.hunk[-1] = s
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1189 l = lr.readline()
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1190 m = contextdesc.match(l)
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1191 if not m:
4898
bc905a6c0e76 patch.py: fix some incorrect uses of _() for i18n
Bryan O'Sullivan <bos@serpentine.com>
parents: 4897
diff changeset
1192 raise PatchError(_("bad hunk #%d") % self.number)
15510
5414b56cfad6 patch: simplify hunk extents parsing
Patrick Mezard <pmezard@gmail.com>
parents: 15462
diff changeset
1193 self.startb, bend = m.groups()
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1194 self.startb = int(self.startb)
8527
f9a80054dd3c use 'x is None' instead of 'x == None'
Martin Geisler <mg@lazybytes.net>
parents: 8526
diff changeset
1195 if bend is None:
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1196 bend = self.startb
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1197 self.lenb = int(bend) - self.startb
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1198 if self.startb:
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1199 self.lenb += 1
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1200 hunki = 1
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1201 for x in xrange(self.lenb):
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1202 l = lr.readline()
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1203 if l.startswith('\ '):
12825
61f48581d8ef Test applying context diffs
Patrick Mezard <pmezard@gmail.com>
parents: 12728
diff changeset
1204 # 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
1205 # 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
1206 # 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
1207 s = self.b[-1][:-1]
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1208 self.b[-1] = s
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
1209 self.hunk[hunki - 1] = s
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1210 continue
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1211 if not l:
12825
61f48581d8ef Test applying context diffs
Patrick Mezard <pmezard@gmail.com>
parents: 12728
diff changeset
1212 # 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
1213 lr.push(l)
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1214 break
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1215 s = l[2:]
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1216 if l.startswith('+ ') or l.startswith('! '):
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1217 u = '+' + s
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1218 elif l.startswith(' '):
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1219 u = ' ' + s
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1220 elif len(self.b) == 0:
12825
61f48581d8ef Test applying context diffs
Patrick Mezard <pmezard@gmail.com>
parents: 12728
diff changeset
1221 # line deletions, new block is empty
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1222 lr.push(l)
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1223 break
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1224 else:
4898
bc905a6c0e76 patch.py: fix some incorrect uses of _() for i18n
Bryan O'Sullivan <bos@serpentine.com>
parents: 4897
diff changeset
1225 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
1226 (self.number, x))
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1227 self.b.append(s)
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1228 while True:
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1229 if hunki >= len(self.hunk):
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1230 h = ""
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1231 else:
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1232 h = self.hunk[hunki]
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1233 hunki += 1
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1234 if h == u:
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1235 break
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1236 elif h.startswith('-'):
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1237 continue
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1238 else:
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
1239 self.hunk.insert(hunki - 1, u)
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1240 break
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1241
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1242 if not self.a:
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1243 # 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
1244 for x in self.hunk:
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1245 if x.startswith('-') or x.startswith(' '):
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1246 self.a.append(x)
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1247 if not self.b:
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1248 # 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
1249 for x in self.hunk:
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1250 if x.startswith('+') or x.startswith(' '):
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1251 self.b.append(x[1:])
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1252 # @@ -start,len +start,len @@
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1253 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
1254 self.startb, self.lenb)
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1255 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
1256 self._fixnewline(lr)
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1257
13699
d3c0e0033f13 patch: fix hunk newlines when parsing hunks, not in iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 13395
diff changeset
1258 def _fixnewline(self, lr):
d3c0e0033f13 patch: fix hunk newlines when parsing hunks, not in iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 13395
diff changeset
1259 l = lr.readline()
d3c0e0033f13 patch: fix hunk newlines when parsing hunks, not in iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 13395
diff changeset
1260 if l.startswith('\ '):
d3c0e0033f13 patch: fix hunk newlines when parsing hunks, not in iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 13395
diff changeset
1261 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
1262 else:
d3c0e0033f13 patch: fix hunk newlines when parsing hunks, not in iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 13395
diff changeset
1263 lr.push(l)
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1264
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1265 def complete(self):
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1266 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
1267
16121
ccba74472af2 patch: fuzz old and new lines at the same time
Patrick Mezard <patrick@mezard.eu>
parents: 16112
diff changeset
1268 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
1269 # 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
1270 # 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
1271 # 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
1272 fuzz = min(fuzz, len(old))
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1273 if fuzz:
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1274 top = 0
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1275 bot = 0
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1276 hlen = len(self.hunk)
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
1277 for x in xrange(hlen - 1):
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1278 # 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
1279 if self.hunk[x + 1][0] == ' ':
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1280 top += 1
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1281 else:
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1282 break
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1283 if not toponly:
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
1284 for x in xrange(hlen - 1):
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
1285 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
1286 bot += 1
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1287 else:
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1288 break
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1289
16124
0e0060bf2f44 patch: fuzz more aggressively to match patch(1) behaviour
Patrick Mezard <patrick@mezard.eu>
parents: 16123
diff changeset
1290 bot = min(fuzz, bot)
0e0060bf2f44 patch: fuzz more aggressively to match patch(1) behaviour
Patrick Mezard <patrick@mezard.eu>
parents: 16123
diff changeset
1291 top = min(fuzz, top)
18054
b35e3364f94a check-code: there must also be whitespace between ')' and operator
Mads Kiilerich <madski@unity3d.com>
parents: 17968
diff changeset
1292 return old[top:len(old) - bot], new[top:len(new) - bot], top
16122
9ef3a4a2c6c0 patch: make hunk.fuzzit() compute the fuzzed start locations
Patrick Mezard <patrick@mezard.eu>
parents: 16121
diff changeset
1293 return old, new, 0
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1294
16121
ccba74472af2 patch: fuzz old and new lines at the same time
Patrick Mezard <patrick@mezard.eu>
parents: 16112
diff changeset
1295 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
1296 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
1297 oldstart = self.starta + top
9ef3a4a2c6c0 patch: make hunk.fuzzit() compute the fuzzed start locations
Patrick Mezard <patrick@mezard.eu>
parents: 16121
diff changeset
1298 newstart = self.startb + top
9ef3a4a2c6c0 patch: make hunk.fuzzit() compute the fuzzed start locations
Patrick Mezard <patrick@mezard.eu>
parents: 16121
diff changeset
1299 # 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
1300 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
1301 oldstart -= 1
16650
fcb97d9a26cd patch: fix segfault against unified diffs which start line is zero
Yuya Nishihara <yuya@tcha.org>
parents: 16524
diff changeset
1302 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
1303 newstart -= 1
9ef3a4a2c6c0 patch: make hunk.fuzzit() compute the fuzzed start locations
Patrick Mezard <patrick@mezard.eu>
parents: 16121
diff changeset
1304 return old, oldstart, new, newstart
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1305
14764
a7d5816087a9 classes: fix class style problems found by b071cd58af50
Thomas Arendsen Hein <thomas@intevation.de>
parents: 14695
diff changeset
1306 class binhunk(object):
20137
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1307 'A binary patch file.'
16523
727068417b95 patch: include file name in binary patch error messages
Patrick Mezard <patrick@mezard.eu>
parents: 16522
diff changeset
1308 def __init__(self, lr, fname):
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1309 self.text = None
20137
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1310 self.delta = False
9585
ea1935e2020a patch: handle symlinks without symlinkhunk
Patrick Mezard <pmezard@gmail.com>
parents: 9573
diff changeset
1311 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
1312 self._fname = fname
14384
9d59c596eb9e patch: construct and parse binary hunks at the same time
Patrick Mezard <pmezard@gmail.com>
parents: 14383
diff changeset
1313 self._read(lr)
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1314
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1315 def complete(self):
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1316 return self.text is not None
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1317
20137
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1318 def new(self, lines):
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1319 if self.delta:
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1320 return [applybindelta(self.text, ''.join(lines))]
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1321 return [self.text]
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1322
14384
9d59c596eb9e patch: construct and parse binary hunks at the same time
Patrick Mezard <pmezard@gmail.com>
parents: 14383
diff changeset
1323 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
1324 def getline(lr, hunk):
ed6a74312176 patch: be more tolerant with EOLs in binary diffs (issue2870)
Patrick Mezard <patrick@mezard.eu>
parents: 16523
diff changeset
1325 l = lr.readline()
ed6a74312176 patch: be more tolerant with EOLs in binary diffs (issue2870)
Patrick Mezard <patrick@mezard.eu>
parents: 16523
diff changeset
1326 hunk.append(l)
ed6a74312176 patch: be more tolerant with EOLs in binary diffs (issue2870)
Patrick Mezard <patrick@mezard.eu>
parents: 16523
diff changeset
1327 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
1328
20137
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1329 size = 0
16567
aef3d0d4631c patch: clarify binary hunk parsing loop
Patrick Mezard <patrick@mezard.eu>
parents: 16524
diff changeset
1330 while True:
16524
ed6a74312176 patch: be more tolerant with EOLs in binary diffs (issue2870)
Patrick Mezard <patrick@mezard.eu>
parents: 16523
diff changeset
1331 line = getline(lr, self.hunk)
16567
aef3d0d4631c patch: clarify binary hunk parsing loop
Patrick Mezard <patrick@mezard.eu>
parents: 16524
diff changeset
1332 if not line:
aef3d0d4631c patch: clarify binary hunk parsing loop
Patrick Mezard <patrick@mezard.eu>
parents: 16524
diff changeset
1333 raise PatchError(_('could not extract "%s" binary data')
aef3d0d4631c patch: clarify binary hunk parsing loop
Patrick Mezard <patrick@mezard.eu>
parents: 16524
diff changeset
1334 % self._fname)
aef3d0d4631c patch: clarify binary hunk parsing loop
Patrick Mezard <patrick@mezard.eu>
parents: 16524
diff changeset
1335 if line.startswith('literal '):
20137
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1336 size = int(line[8:].rstrip())
16567
aef3d0d4631c patch: clarify binary hunk parsing loop
Patrick Mezard <patrick@mezard.eu>
parents: 16524
diff changeset
1337 break
20137
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1338 if line.startswith('delta '):
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1339 size = int(line[6:].rstrip())
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1340 self.delta = True
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1341 break
3367
7f486971d263 Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents: 3329
diff changeset
1342 dec = []
16524
ed6a74312176 patch: be more tolerant with EOLs in binary diffs (issue2870)
Patrick Mezard <patrick@mezard.eu>
parents: 16523
diff changeset
1343 line = getline(lr, self.hunk)
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1344 while len(line) > 1:
3374
fd43ff3b4442 Use line length field when extracting git binary patches
Brendan Cully <brendan@kublai.com>
parents: 3367
diff changeset
1345 l = line[0]
fd43ff3b4442 Use line length field when extracting git binary patches
Brendan Cully <brendan@kublai.com>
parents: 3367
diff changeset
1346 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
1347 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
1348 else:
fd43ff3b4442 Use line length field when extracting git binary patches
Brendan Cully <brendan@kublai.com>
parents: 3367
diff changeset
1349 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
1350 try:
16524
ed6a74312176 patch: be more tolerant with EOLs in binary diffs (issue2870)
Patrick Mezard <patrick@mezard.eu>
parents: 16523
diff changeset
1351 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
1352 except ValueError, e:
16523
727068417b95 patch: include file name in binary patch error messages
Patrick Mezard <patrick@mezard.eu>
parents: 16522
diff changeset
1353 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
1354 % (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
1355 line = getline(lr, self.hunk)
3367
7f486971d263 Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents: 3329
diff changeset
1356 text = zlib.decompress(''.join(dec))
7f486971d263 Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents: 3329
diff changeset
1357 if len(text) != size:
16523
727068417b95 patch: include file name in binary patch error messages
Patrick Mezard <patrick@mezard.eu>
parents: 16522
diff changeset
1358 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
1359 % (self._fname, len(text), size))
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1360 self.text = text
3367
7f486971d263 Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents: 3329
diff changeset
1361
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1362 def parsefilename(str):
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1363 # --- filename \t|space stuff
5851
03f550f9b554 patch: remove CRLF when parsing file names
Patrick Mezard <pmezard@gmail.com>
parents: 5669
diff changeset
1364 s = str[4:].rstrip('\r\n')
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1365 i = s.find('\t')
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1366 if i < 0:
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1367 i = s.find(' ')
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1368 if i < 0:
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1369 return s
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1370 return s[:i]
2861
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
1371
24341
616c01b69898 record: change interface of the filtering function
Laurent Charignon <lcharignon@fb.com>
parents: 24306
diff changeset
1372 def parsepatch(originalchunks):
24265
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1373 """patch -> [] of headers -> [] of hunks """
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1374 class parser(object):
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1375 """patch parsing state machine"""
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1376 def __init__(self):
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1377 self.fromline = 0
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1378 self.toline = 0
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1379 self.proc = ''
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1380 self.header = None
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1381 self.context = []
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1382 self.before = []
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1383 self.hunk = []
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1384 self.headers = []
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1385
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1386 def addrange(self, limits):
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1387 fromstart, fromend, tostart, toend, proc = limits
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1388 self.fromline = int(fromstart)
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1389 self.toline = int(tostart)
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1390 self.proc = proc
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1391
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1392 def addcontext(self, context):
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1393 if self.hunk:
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1394 h = recordhunk(self.header, self.fromline, self.toline,
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1395 self.proc, self.before, self.hunk, context)
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1396 self.header.hunks.append(h)
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1397 self.fromline += len(self.before) + h.removed
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1398 self.toline += len(self.before) + h.added
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1399 self.before = []
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1400 self.hunk = []
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1401 self.proc = ''
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1402 self.context = context
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1403
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1404 def addhunk(self, hunk):
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1405 if self.context:
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1406 self.before = self.context
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1407 self.context = []
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1408 self.hunk = hunk
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1409
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1410 def newfile(self, hdr):
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1411 self.addcontext([])
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1412 h = header(hdr)
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1413 self.headers.append(h)
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1414 self.header = h
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1415
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1416 def addother(self, line):
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1417 pass # 'other' lines are ignored
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1418
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1419 def finished(self):
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1420 self.addcontext([])
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1421 return self.headers
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1422
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1423 transitions = {
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1424 'file': {'context': addcontext,
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1425 'file': newfile,
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1426 'hunk': addhunk,
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1427 'range': addrange},
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1428 'context': {'file': newfile,
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1429 'hunk': addhunk,
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1430 'range': addrange,
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1431 'other': addother},
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1432 'hunk': {'context': addcontext,
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1433 'file': newfile,
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1434 'range': addrange},
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1435 'range': {'context': addcontext,
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1436 'hunk': addhunk},
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1437 'other': {'other': addother},
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1438 }
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1439
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1440 p = parser()
24341
616c01b69898 record: change interface of the filtering function
Laurent Charignon <lcharignon@fb.com>
parents: 24306
diff changeset
1441 fp = cStringIO.StringIO()
616c01b69898 record: change interface of the filtering function
Laurent Charignon <lcharignon@fb.com>
parents: 24306
diff changeset
1442 fp.write(''.join(originalchunks))
616c01b69898 record: change interface of the filtering function
Laurent Charignon <lcharignon@fb.com>
parents: 24306
diff changeset
1443 fp.seek(0)
24265
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1444
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1445 state = 'context'
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1446 for newstate, data in scanpatch(fp):
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1447 try:
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1448 p.transitions[state][newstate](p, data)
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1449 except KeyError:
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1450 raise PatchError('unhandled transition: %s -> %s' %
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1451 (state, newstate))
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1452 state = newstate
24341
616c01b69898 record: change interface of the filtering function
Laurent Charignon <lcharignon@fb.com>
parents: 24306
diff changeset
1453 del fp
24265
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1454 return p.finished()
dc655360bccb record: move parsepatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24264
diff changeset
1455
24244
5918bb365c72 patch.pathtransform: add a prefix parameter
Siddharth Agarwal <sid0@fb.com>
parents: 24243
diff changeset
1456 def pathtransform(path, strip, prefix):
24243
daee2039dd11 patch.pathtransform: add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 24242
diff changeset
1457 '''turn a path from a patch into a path suitable for the repository
daee2039dd11 patch.pathtransform: add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 24242
diff changeset
1458
24244
5918bb365c72 patch.pathtransform: add a prefix parameter
Siddharth Agarwal <sid0@fb.com>
parents: 24243
diff changeset
1459 prefix, if not empty, is expected to be normalized with a / at the end.
5918bb365c72 patch.pathtransform: add a prefix parameter
Siddharth Agarwal <sid0@fb.com>
parents: 24243
diff changeset
1460
24243
daee2039dd11 patch.pathtransform: add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 24242
diff changeset
1461 Returns (stripped components, path in repository).
daee2039dd11 patch.pathtransform: add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 24242
diff changeset
1462
24244
5918bb365c72 patch.pathtransform: add a prefix parameter
Siddharth Agarwal <sid0@fb.com>
parents: 24243
diff changeset
1463 >>> pathtransform('a/b/c', 0, '')
24243
daee2039dd11 patch.pathtransform: add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 24242
diff changeset
1464 ('', 'a/b/c')
24244
5918bb365c72 patch.pathtransform: add a prefix parameter
Siddharth Agarwal <sid0@fb.com>
parents: 24243
diff changeset
1465 >>> pathtransform(' a/b/c ', 0, '')
24243
daee2039dd11 patch.pathtransform: add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 24242
diff changeset
1466 ('', ' a/b/c')
24244
5918bb365c72 patch.pathtransform: add a prefix parameter
Siddharth Agarwal <sid0@fb.com>
parents: 24243
diff changeset
1467 >>> pathtransform(' a/b/c ', 2, '')
24243
daee2039dd11 patch.pathtransform: add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 24242
diff changeset
1468 ('a/b/', 'c')
24385
885a573fa619 patch.pathtransform: prepend prefix even if strip is 0
Siddharth Agarwal <sid0@fb.com>
parents: 24371
diff changeset
1469 >>> pathtransform('a/b/c', 0, 'd/e/')
885a573fa619 patch.pathtransform: prepend prefix even if strip is 0
Siddharth Agarwal <sid0@fb.com>
parents: 24371
diff changeset
1470 ('', 'd/e/a/b/c')
24244
5918bb365c72 patch.pathtransform: add a prefix parameter
Siddharth Agarwal <sid0@fb.com>
parents: 24243
diff changeset
1471 >>> pathtransform(' a//b/c ', 2, 'd/e/')
5918bb365c72 patch.pathtransform: add a prefix parameter
Siddharth Agarwal <sid0@fb.com>
parents: 24243
diff changeset
1472 ('a//b/', 'd/e/c')
5918bb365c72 patch.pathtransform: add a prefix parameter
Siddharth Agarwal <sid0@fb.com>
parents: 24243
diff changeset
1473 >>> pathtransform('a/b/c', 3, '')
24243
daee2039dd11 patch.pathtransform: add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 24242
diff changeset
1474 Traceback (most recent call last):
daee2039dd11 patch.pathtransform: add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 24242
diff changeset
1475 PatchError: unable to strip away 1 of 3 dirs from a/b/c
daee2039dd11 patch.pathtransform: add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 24242
diff changeset
1476 '''
11022
0429d0d49f92 patch: strip paths in leaked git patchmeta objects
Mads Kiilerich <mads@kiilerich.com>
parents: 11021
diff changeset
1477 pathlen = len(path)
0429d0d49f92 patch: strip paths in leaked git patchmeta objects
Mads Kiilerich <mads@kiilerich.com>
parents: 11021
diff changeset
1478 i = 0
0429d0d49f92 patch: strip paths in leaked git patchmeta objects
Mads Kiilerich <mads@kiilerich.com>
parents: 11021
diff changeset
1479 if strip == 0:
24385
885a573fa619 patch.pathtransform: prepend prefix even if strip is 0
Siddharth Agarwal <sid0@fb.com>
parents: 24371
diff changeset
1480 return '', prefix + path.rstrip()
11022
0429d0d49f92 patch: strip paths in leaked git patchmeta objects
Mads Kiilerich <mads@kiilerich.com>
parents: 11021
diff changeset
1481 count = strip
0429d0d49f92 patch: strip paths in leaked git patchmeta objects
Mads Kiilerich <mads@kiilerich.com>
parents: 11021
diff changeset
1482 while count > 0:
0429d0d49f92 patch: strip paths in leaked git patchmeta objects
Mads Kiilerich <mads@kiilerich.com>
parents: 11021
diff changeset
1483 i = path.find('/', i)
0429d0d49f92 patch: strip paths in leaked git patchmeta objects
Mads Kiilerich <mads@kiilerich.com>
parents: 11021
diff changeset
1484 if i == -1:
0429d0d49f92 patch: strip paths in leaked git patchmeta objects
Mads Kiilerich <mads@kiilerich.com>
parents: 11021
diff changeset
1485 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
1486 (count, strip, path))
0429d0d49f92 patch: strip paths in leaked git patchmeta objects
Mads Kiilerich <mads@kiilerich.com>
parents: 11021
diff changeset
1487 i += 1
0429d0d49f92 patch: strip paths in leaked git patchmeta objects
Mads Kiilerich <mads@kiilerich.com>
parents: 11021
diff changeset
1488 # consume '//' in the path
0429d0d49f92 patch: strip paths in leaked git patchmeta objects
Mads Kiilerich <mads@kiilerich.com>
parents: 11021
diff changeset
1489 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
1490 i += 1
0429d0d49f92 patch: strip paths in leaked git patchmeta objects
Mads Kiilerich <mads@kiilerich.com>
parents: 11021
diff changeset
1491 count -= 1
24244
5918bb365c72 patch.pathtransform: add a prefix parameter
Siddharth Agarwal <sid0@fb.com>
parents: 24243
diff changeset
1492 return path[:i].lstrip(), prefix + path[i:].rstrip()
11022
0429d0d49f92 patch: strip paths in leaked git patchmeta objects
Mads Kiilerich <mads@kiilerich.com>
parents: 11021
diff changeset
1493
24245
740a17f885a1 patch.makepatchmeta: accept a prefix parameter
Siddharth Agarwal <sid0@fb.com>
parents: 24244
diff changeset
1494 def makepatchmeta(backend, afile_orig, bfile_orig, hunk, strip, prefix):
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1495 nulla = afile_orig == "/dev/null"
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1496 nullb = bfile_orig == "/dev/null"
14451
c78d41db6f88 patch: refactor file creation/removal detection
Patrick Mezard <pmezard@gmail.com>
parents: 14437
diff changeset
1497 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
1498 remove = nullb and hunk.startb == 0 and hunk.lenb == 0
24245
740a17f885a1 patch.makepatchmeta: accept a prefix parameter
Siddharth Agarwal <sid0@fb.com>
parents: 24244
diff changeset
1499 abase, afile = pathtransform(afile_orig, strip, prefix)
14351
d54f9bbcc640 patch: add lexists() to backends, use it in selectfile()
Patrick Mezard <pmezard@gmail.com>
parents: 14350
diff changeset
1500 gooda = not nulla and backend.exists(afile)
24245
740a17f885a1 patch.makepatchmeta: accept a prefix parameter
Siddharth Agarwal <sid0@fb.com>
parents: 24244
diff changeset
1501 bbase, bfile = pathtransform(bfile_orig, strip, prefix)
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1502 if afile == bfile:
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1503 goodb = gooda
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1504 else:
14351
d54f9bbcc640 patch: add lexists() to backends, use it in selectfile()
Patrick Mezard <pmezard@gmail.com>
parents: 14350
diff changeset
1505 goodb = not nullb and backend.exists(bfile)
14451
c78d41db6f88 patch: refactor file creation/removal detection
Patrick Mezard <pmezard@gmail.com>
parents: 14437
diff changeset
1506 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
1507
11820
75de514a50f3 patch: fix typo in comment
Martin Geisler <mg@aragost.com>
parents: 11645
diff changeset
1508 # 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
1509 # 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
1510 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
1511 bbasedir = bfile[:bfile.rfind('/') + 1]
14451
c78d41db6f88 patch: refactor file creation/removal detection
Patrick Mezard <pmezard@gmail.com>
parents: 14437
diff changeset
1512 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
1513 and hunk.starta == 0 and hunk.lena == 0):
c78d41db6f88 patch: refactor file creation/removal detection
Patrick Mezard <pmezard@gmail.com>
parents: 14437
diff changeset
1514 create = True
c78d41db6f88 patch: refactor file creation/removal detection
Patrick Mezard <pmezard@gmail.com>
parents: 14437
diff changeset
1515 missing = False
9328
648d6a1a1cf2 patch: create file even if source is not /dev/null
Brendan Cully <brendan@kublai.com>
parents: 9248
diff changeset
1516
6295
bace1990ab12 patch: fix corner case with update + copy patch handling (issue 937)
Patrick Mezard <pmezard@gmail.com>
parents: 6280
diff changeset
1517 # 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
1518 # 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
1519 # 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
1520 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
1521 fname = None
e90e72c6b4c7 patch: write rej files for missing targets (issue 853)
Patrick Mezard <pmezard@gmail.com>
parents: 5651
diff changeset
1522 if not missing:
e90e72c6b4c7 patch: write rej files for missing targets (issue 853)
Patrick Mezard <pmezard@gmail.com>
parents: 5651
diff changeset
1523 if gooda and goodb:
24306
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24269
diff changeset
1524 if isbackup:
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24269
diff changeset
1525 fname = afile
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24269
diff changeset
1526 else:
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24269
diff changeset
1527 fname = bfile
5652
e90e72c6b4c7 patch: write rej files for missing targets (issue 853)
Patrick Mezard <pmezard@gmail.com>
parents: 5651
diff changeset
1528 elif gooda:
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1529 fname = afile
5760
0145f9afb0e7 Removed tabs and trailing whitespace in python files
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5706
diff changeset
1530
5652
e90e72c6b4c7 patch: write rej files for missing targets (issue 853)
Patrick Mezard <pmezard@gmail.com>
parents: 5651
diff changeset
1531 if not fname:
e90e72c6b4c7 patch: write rej files for missing targets (issue 853)
Patrick Mezard <pmezard@gmail.com>
parents: 5651
diff changeset
1532 if not nullb:
24306
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24269
diff changeset
1533 if isbackup:
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24269
diff changeset
1534 fname = afile
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24269
diff changeset
1535 else:
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24269
diff changeset
1536 fname = bfile
5652
e90e72c6b4c7 patch: write rej files for missing targets (issue 853)
Patrick Mezard <pmezard@gmail.com>
parents: 5651
diff changeset
1537 elif not nulla:
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1538 fname = afile
5652
e90e72c6b4c7 patch: write rej files for missing targets (issue 853)
Patrick Mezard <pmezard@gmail.com>
parents: 5651
diff changeset
1539 else:
e90e72c6b4c7 patch: write rej files for missing targets (issue 853)
Patrick Mezard <pmezard@gmail.com>
parents: 5651
diff changeset
1540 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
1541
14566
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
1542 gp = patchmeta(fname)
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
1543 if create:
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
1544 gp.op = 'ADD'
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
1545 elif remove:
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
1546 gp.op = 'DELETE'
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
1547 return gp
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1548
24264
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1549 def scanpatch(fp):
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1550 """like patch.iterhunks, but yield different events
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1551
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1552 - ('file', [header_lines + fromfile + tofile])
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1553 - ('context', [context_lines])
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1554 - ('hunk', [hunk_lines])
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1555 - ('range', (-start,len, +start,len, proc))
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1556 """
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1557 lines_re = re.compile(r'@@ -(\d+),(\d+) \+(\d+),(\d+) @@\s*(.*)')
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1558 lr = linereader(fp)
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1559
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1560 def scanwhile(first, p):
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1561 """scan lr while predicate holds"""
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1562 lines = [first]
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1563 while True:
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1564 line = lr.readline()
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1565 if not line:
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1566 break
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1567 if p(line):
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1568 lines.append(line)
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1569 else:
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1570 lr.push(line)
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1571 break
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1572 return lines
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1573
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1574 while True:
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1575 line = lr.readline()
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1576 if not line:
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1577 break
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1578 if line.startswith('diff --git a/') or line.startswith('diff -r '):
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1579 def notheader(line):
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1580 s = line.split(None, 1)
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1581 return not s or s[0] not in ('---', 'diff')
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1582 header = scanwhile(line, notheader)
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1583 fromfile = lr.readline()
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1584 if fromfile.startswith('---'):
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1585 tofile = lr.readline()
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1586 header += [fromfile, tofile]
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1587 else:
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1588 lr.push(fromfile)
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1589 yield 'file', header
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1590 elif line[0] == ' ':
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1591 yield 'context', scanwhile(line, lambda l: l[0] in ' \\')
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1592 elif line[0] in '-+':
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1593 yield 'hunk', scanwhile(line, lambda l: l[0] in '-+\\')
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1594 else:
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1595 m = lines_re.match(line)
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1596 if m:
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1597 yield 'range', m.groups()
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1598 else:
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1599 yield 'other', line
c4205452f1b7 record: move scanpatch from record to patch
Laurent Charignon <lcharignon@fb.com>
parents: 24263
diff changeset
1600
7152
f0055cec8446 patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 7151
diff changeset
1601 def scangitpatch(lr, firstline):
7186
f77c8d8331ca clean up trailing spaces, leading spaces in C
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7153
diff changeset
1602 """
7152
f0055cec8446 patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 7151
diff changeset
1603 Git patches can emit:
f0055cec8446 patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 7151
diff changeset
1604 - rename a to b
f0055cec8446 patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 7151
diff changeset
1605 - change b
f0055cec8446 patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 7151
diff changeset
1606 - copy a to c
f0055cec8446 patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 7151
diff changeset
1607 - change c
7186
f77c8d8331ca clean up trailing spaces, leading spaces in C
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7153
diff changeset
1608
7152
f0055cec8446 patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 7151
diff changeset
1609 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
1610 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
1611 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
1612 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
1613 perform the copies ahead of time.
f0055cec8446 patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 7151
diff changeset
1614 """
f0055cec8446 patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 7151
diff changeset
1615 pos = 0
f0055cec8446 patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 7151
diff changeset
1616 try:
f0055cec8446 patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 7151
diff changeset
1617 pos = lr.fp.tell()
f0055cec8446 patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 7151
diff changeset
1618 fp = lr.fp
f0055cec8446 patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 7151
diff changeset
1619 except IOError:
f0055cec8446 patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 7151
diff changeset
1620 fp = cStringIO.StringIO(lr.fp.read())
14418
0174d1f79280 patch: remove EOL support from linereader class
Patrick Mezard <pmezard@gmail.com>
parents: 14402
diff changeset
1621 gitlr = linereader(fp)
7152
f0055cec8446 patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 7151
diff changeset
1622 gitlr.push(firstline)
12669
b0fa39c68370 patch: remove unused flags from readgitpatch()
Patrick Mezard <pmezard@gmail.com>
parents: 12645
diff changeset
1623 gitpatches = readgitpatch(gitlr)
7152
f0055cec8446 patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 7151
diff changeset
1624 fp.seek(pos)
12669
b0fa39c68370 patch: remove unused flags from readgitpatch()
Patrick Mezard <pmezard@gmail.com>
parents: 12645
diff changeset
1625 return gitpatches
7152
f0055cec8446 patch: pass linereader to scangitpatch(), extract from iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 7151
diff changeset
1626
14240
28762bb767dc patch: remove unused ui arg to iterhunks
Idan Kamara <idankk86@gmail.com>
parents: 14234
diff changeset
1627 def iterhunks(fp):
5650
5d3e2f918d65 patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents: 5649
diff changeset
1628 """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
1629 - ("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
1630 - ("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
1631 "file" event.
5d3e2f918d65 patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents: 5649
diff changeset
1632 - ("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
1633 maps filenames to gitpatch records. Unique event.
5d3e2f918d65 patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents: 5649
diff changeset
1634 """
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1635 afile = ""
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1636 bfile = ""
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1637 state = None
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1638 hunknum = 0
14017
19a7b48446e3 patch: remove redundant variable in iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 13971
diff changeset
1639 emitfile = newfile = False
14388
37c997d21752 patch: stop handling hunkless git blocks out of stream
Patrick Mezard <pmezard@gmail.com>
parents: 14387
diff changeset
1640 gitpatches = None
2861
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
1641
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1642 # our states
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1643 BFILE = 1
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1644 context = None
10128
ea7c392f2b08 patch: drop eol normalization fast-path for 'lf' and 'crlf'
Patrick Mezard <pmezard@gmail.com>
parents: 10127
diff changeset
1645 lr = linereader(fp)
2861
0f08f2c042ec Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
1646
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1647 while True:
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1648 x = lr.readline()
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1649 if not x:
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1650 break
14383
1bd52cb12a55 patch: refactor iterhunks() regular and binary files emission
Patrick Mezard <pmezard@gmail.com>
parents: 14382
diff changeset
1651 if state == BFILE and (
1bd52cb12a55 patch: refactor iterhunks() regular and binary files emission
Patrick Mezard <pmezard@gmail.com>
parents: 14382
diff changeset
1652 (not context and x[0] == '@')
1bd52cb12a55 patch: refactor iterhunks() regular and binary files emission
Patrick Mezard <pmezard@gmail.com>
parents: 14382
diff changeset
1653 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
1654 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
1655 gp = None
14534
ecc79816d31e patch: fix patchmeta/hunk synchronization in iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 14533
diff changeset
1656 if (gitpatches and
16506
fc4e0fecf403 patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents: 16475
diff changeset
1657 gitpatches[-1].ispatching(afile, bfile)):
fc4e0fecf403 patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents: 16475
diff changeset
1658 gp = gitpatches.pop()
14383
1bd52cb12a55 patch: refactor iterhunks() regular and binary files emission
Patrick Mezard <pmezard@gmail.com>
parents: 14382
diff changeset
1659 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
1660 h = binhunk(lr, gp.path)
14383
1bd52cb12a55 patch: refactor iterhunks() regular and binary files emission
Patrick Mezard <pmezard@gmail.com>
parents: 14382
diff changeset
1661 else:
1bd52cb12a55 patch: refactor iterhunks() regular and binary files emission
Patrick Mezard <pmezard@gmail.com>
parents: 14382
diff changeset
1662 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
1663 context = True
14451
c78d41db6f88 patch: refactor file creation/removal detection
Patrick Mezard <pmezard@gmail.com>
parents: 14437
diff changeset
1664 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
1665 hunknum += 1
5650
5d3e2f918d65 patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents: 5649
diff changeset
1666 if emitfile:
5d3e2f918d65 patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents: 5649
diff changeset
1667 emitfile = False
14566
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
1668 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
1669 yield 'hunk', h
18830
6b827d84d286 patch: match 'diff --git a/' instead of 'diff --git'
Sean Farley <sean.michael.farley@gmail.com>
parents: 18824
diff changeset
1670 elif x.startswith('diff --git a/'):
16524
ed6a74312176 patch: be more tolerant with EOLs in binary diffs (issue2870)
Patrick Mezard <patrick@mezard.eu>
parents: 16523
diff changeset
1671 m = gitre.match(x.rstrip(' \r\n'))
14387
e1b4a7a7263a patch: reindent code
Patrick Mezard <pmezard@gmail.com>
parents: 14386
diff changeset
1672 if not m:
e1b4a7a7263a patch: reindent code
Patrick Mezard <pmezard@gmail.com>
parents: 14386
diff changeset
1673 continue
16506
fc4e0fecf403 patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents: 16475
diff changeset
1674 if gitpatches is None:
14387
e1b4a7a7263a patch: reindent code
Patrick Mezard <pmezard@gmail.com>
parents: 14386
diff changeset
1675 # scan whole input for git metadata
16506
fc4e0fecf403 patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents: 16475
diff changeset
1676 gitpatches = scangitpatch(lr, x)
fc4e0fecf403 patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents: 16475
diff changeset
1677 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
1678 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
1679 gitpatches.reverse()
14387
e1b4a7a7263a patch: reindent code
Patrick Mezard <pmezard@gmail.com>
parents: 14386
diff changeset
1680 afile = 'a/' + m.group(1)
e1b4a7a7263a patch: reindent code
Patrick Mezard <pmezard@gmail.com>
parents: 14386
diff changeset
1681 bfile = 'b/' + m.group(2)
16506
fc4e0fecf403 patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents: 16475
diff changeset
1682 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
1683 gp = gitpatches.pop()
14566
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
1684 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
1685 if not gitpatches:
fc4e0fecf403 patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents: 16475
diff changeset
1686 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
1687 % afile[2:])
fc4e0fecf403 patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents: 16475
diff changeset
1688 gp = gitpatches[-1]
14387
e1b4a7a7263a patch: reindent code
Patrick Mezard <pmezard@gmail.com>
parents: 14386
diff changeset
1689 newfile = True
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1690 elif x.startswith('---'):
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1691 # check for a unified diff
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1692 l2 = lr.readline()
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1693 if not l2.startswith('+++'):
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1694 lr.push(l2)
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1695 continue
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1696 newfile = True
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1697 context = False
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1698 afile = parsefilename(x)
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1699 bfile = parsefilename(l2)
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1700 elif x.startswith('***'):
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1701 # check for a context diff
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1702 l2 = lr.readline()
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1703 if not l2.startswith('---'):
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1704 lr.push(l2)
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1705 continue
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1706 l3 = lr.readline()
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1707 lr.push(l3)
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1708 if not l3.startswith("***************"):
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1709 lr.push(l2)
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1710 continue
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1711 newfile = True
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1712 context = True
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1713 afile = parsefilename(x)
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1714 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
1715
14017
19a7b48446e3 patch: remove redundant variable in iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 13971
diff changeset
1716 if newfile:
19a7b48446e3 patch: remove redundant variable in iterhunks()
Patrick Mezard <pmezard@gmail.com>
parents: 13971
diff changeset
1717 newfile = False
5650
5d3e2f918d65 patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents: 5649
diff changeset
1718 emitfile = True
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1719 state = BFILE
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1720 hunknum = 0
5650
5d3e2f918d65 patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents: 5649
diff changeset
1721
14388
37c997d21752 patch: stop handling hunkless git blocks out of stream
Patrick Mezard <pmezard@gmail.com>
parents: 14387
diff changeset
1722 while gitpatches:
16506
fc4e0fecf403 patch: fix patch hunk/metdata synchronization (issue3384)
Patrick Mezard <patrick@mezard.eu>
parents: 16475
diff changeset
1723 gp = gitpatches.pop()
14566
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
1724 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
1725
20137
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1726 def applybindelta(binchunk, data):
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1727 """Apply a binary delta hunk
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1728 The algorithm used is the algorithm from git's patch-delta.c
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1729 """
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1730 def deltahead(binchunk):
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1731 i = 0
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1732 for c in binchunk:
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1733 i += 1
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1734 if not (ord(c) & 0x80):
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1735 return i
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1736 return i
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1737 out = ""
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1738 s = deltahead(binchunk)
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1739 binchunk = binchunk[s:]
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1740 s = deltahead(binchunk)
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1741 binchunk = binchunk[s:]
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1742 i = 0
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1743 while i < len(binchunk):
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1744 cmd = ord(binchunk[i])
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1745 i += 1
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1746 if (cmd & 0x80):
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1747 offset = 0
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1748 size = 0
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1749 if (cmd & 0x01):
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1750 offset = ord(binchunk[i])
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1751 i += 1
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1752 if (cmd & 0x02):
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1753 offset |= ord(binchunk[i]) << 8
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1754 i += 1
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1755 if (cmd & 0x04):
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1756 offset |= ord(binchunk[i]) << 16
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1757 i += 1
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1758 if (cmd & 0x08):
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1759 offset |= ord(binchunk[i]) << 24
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1760 i += 1
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1761 if (cmd & 0x10):
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1762 size = ord(binchunk[i])
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1763 i += 1
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1764 if (cmd & 0x20):
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1765 size |= ord(binchunk[i]) << 8
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1766 i += 1
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1767 if (cmd & 0x40):
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1768 size |= ord(binchunk[i]) << 16
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1769 i += 1
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1770 if size == 0:
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1771 size = 0x10000
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1772 offset_end = offset + size
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1773 out += data[offset:offset_end]
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1774 elif cmd != 0:
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1775 offset_end = i + cmd
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1776 out += binchunk[i:offset_end]
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1777 i += cmd
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1778 else:
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1779 raise PatchError(_('unexpected delta opcode 0'))
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1780 return out
9f1d4323c749 patch: add support for git delta hunks
Nicolas Vigier <boklm@mars-attacks.org>
parents: 20035
diff changeset
1781
24247
6e19516094a3 patch.applydiff: accept a prefix parameter
Siddharth Agarwal <sid0@fb.com>
parents: 24246
diff changeset
1782 def applydiff(ui, fp, backend, store, strip=1, prefix='', eolmode='strict'):
10966
91c58cf54eee patch: refactor applydiff to allow for mempatching
Augie Fackler <durin42@gmail.com>
parents: 10965
diff changeset
1783 """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
1784
14565
3cacc232f27f patch: stop updating changed files set in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14564
diff changeset
1785 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
1786 there was any fuzz.
8810
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
1787
10101
155fe35534d3 patch: propagate eolmode down to patchfile
Martin Geisler <mg@lazybytes.net>
parents: 9725
diff changeset
1788 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
1789 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
1790 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
1791 """
14565
3cacc232f27f patch: stop updating changed files set in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14564
diff changeset
1792 return _applydiff(ui, fp, patchfile, backend, store, strip=strip,
24247
6e19516094a3 patch.applydiff: accept a prefix parameter
Siddharth Agarwal <sid0@fb.com>
parents: 24246
diff changeset
1793 prefix=prefix, eolmode=eolmode)
10966
91c58cf54eee patch: refactor applydiff to allow for mempatching
Augie Fackler <durin42@gmail.com>
parents: 10965
diff changeset
1794
24246
394a91cb3d4a patch._applydiff: accept a prefix parameter
Siddharth Agarwal <sid0@fb.com>
parents: 24245
diff changeset
1795 def _applydiff(ui, fp, patcher, backend, store, strip=1, prefix='',
14452
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
1796 eolmode='strict'):
14389
909ac6b9636b patch: stop modifying gitpatch objects
Patrick Mezard <pmezard@gmail.com>
parents: 14388
diff changeset
1797
24246
394a91cb3d4a patch._applydiff: accept a prefix parameter
Siddharth Agarwal <sid0@fb.com>
parents: 24245
diff changeset
1798 if prefix:
24390
72d7d390ef5d patch._applydiff: resolve prefix with respect to the cwd
Siddharth Agarwal <sid0@fb.com>
parents: 24385
diff changeset
1799 prefix = pathutil.canonpath(backend.repo.root, backend.repo.getcwd(),
72d7d390ef5d patch._applydiff: resolve prefix with respect to the cwd
Siddharth Agarwal <sid0@fb.com>
parents: 24385
diff changeset
1800 prefix)
72d7d390ef5d patch._applydiff: resolve prefix with respect to the cwd
Siddharth Agarwal <sid0@fb.com>
parents: 24385
diff changeset
1801 if prefix != '':
72d7d390ef5d patch._applydiff: resolve prefix with respect to the cwd
Siddharth Agarwal <sid0@fb.com>
parents: 24385
diff changeset
1802 prefix += '/'
14389
909ac6b9636b patch: stop modifying gitpatch objects
Patrick Mezard <pmezard@gmail.com>
parents: 14388
diff changeset
1803 def pstrip(p):
24246
394a91cb3d4a patch._applydiff: accept a prefix parameter
Siddharth Agarwal <sid0@fb.com>
parents: 24245
diff changeset
1804 return pathtransform(p, strip - 1, prefix)[1]
14389
909ac6b9636b patch: stop modifying gitpatch objects
Patrick Mezard <pmezard@gmail.com>
parents: 14388
diff changeset
1805
5650
5d3e2f918d65 patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents: 5649
diff changeset
1806 rejects = 0
5d3e2f918d65 patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents: 5649
diff changeset
1807 err = 0
5d3e2f918d65 patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents: 5649
diff changeset
1808 current_file = None
5d3e2f918d65 patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents: 5649
diff changeset
1809
14240
28762bb767dc patch: remove unused ui arg to iterhunks
Idan Kamara <idankk86@gmail.com>
parents: 14234
diff changeset
1810 for state, values in iterhunks(fp):
5650
5d3e2f918d65 patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents: 5649
diff changeset
1811 if state == 'hunk':
5d3e2f918d65 patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents: 5649
diff changeset
1812 if not current_file:
5d3e2f918d65 patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents: 5649
diff changeset
1813 continue
11021
c47a1cfad572 patch: minor cleanup of _applydiff
Mads Kiilerich <mads@kiilerich.com>
parents: 11020
diff changeset
1814 ret = current_file.apply(values)
14565
3cacc232f27f patch: stop updating changed files set in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14564
diff changeset
1815 if ret > 0:
3cacc232f27f patch: stop updating changed files set in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14564
diff changeset
1816 err = 1
5650
5d3e2f918d65 patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents: 5649
diff changeset
1817 elif state == 'file':
13701
bc38ff7cb919 patch: move closefile() into patchfile.close()
Patrick Mezard <pmezard@gmail.com>
parents: 13700
diff changeset
1818 if current_file:
bc38ff7cb919 patch: move closefile() into patchfile.close()
Patrick Mezard <pmezard@gmail.com>
parents: 13700
diff changeset
1819 rejects += current_file.close()
14388
37c997d21752 patch: stop handling hunkless git blocks out of stream
Patrick Mezard <pmezard@gmail.com>
parents: 14387
diff changeset
1820 current_file = None
37c997d21752 patch: stop handling hunkless git blocks out of stream
Patrick Mezard <pmezard@gmail.com>
parents: 14387
diff changeset
1821 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
1822 if gp:
14566
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
1823 gp.path = pstrip(gp.path)
14452
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
1824 if gp.oldpath:
14566
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
1825 gp.oldpath = pstrip(gp.oldpath)
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
1826 else:
24246
394a91cb3d4a patch._applydiff: accept a prefix parameter
Siddharth Agarwal <sid0@fb.com>
parents: 24245
diff changeset
1827 gp = makepatchmeta(backend, afile, bfile, first_hunk, strip,
394a91cb3d4a patch._applydiff: accept a prefix parameter
Siddharth Agarwal <sid0@fb.com>
parents: 24245
diff changeset
1828 prefix)
14566
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
1829 if gp.op == 'RENAME':
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
1830 backend.unlink(gp.oldpath)
14388
37c997d21752 patch: stop handling hunkless git blocks out of stream
Patrick Mezard <pmezard@gmail.com>
parents: 14387
diff changeset
1831 if not first_hunk:
14566
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
1832 if gp.op == 'DELETE':
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
1833 backend.unlink(gp.path)
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
1834 continue
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
1835 data, mode = None, None
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
1836 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
1837 data, mode = store.getfile(gp.oldpath)[:2]
22296
650b5b6e75ed convert: use None value for missing files instead of overloading IOError
Mads Kiilerich <madski@unity3d.com>
parents: 21833
diff changeset
1838 # FIXME: failing getfile has never been handled here
650b5b6e75ed convert: use None value for missing files instead of overloading IOError
Mads Kiilerich <madski@unity3d.com>
parents: 21833
diff changeset
1839 assert data is not None
14566
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
1840 if gp.mode:
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
1841 mode = gp.mode
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
1842 if gp.op == 'ADD':
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
1843 # 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
1844 # must be created
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
1845 data = ''
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
1846 if data or mode:
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
1847 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
1848 and backend.exists(gp.path)):
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
1849 raise PatchError(_("cannot create %s: destination "
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
1850 "already exists") % gp.path)
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
1851 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
1852 continue
5650
5d3e2f918d65 patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents: 5649
diff changeset
1853 try:
14566
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
1854 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
1855 eolmode=eolmode)
14218
202ff575d49b patch: fix clash between local variable and exception instance
Martin Geisler <mg@aragost.com>
parents: 14217
diff changeset
1856 except PatchError, inst:
202ff575d49b patch: fix clash between local variable and exception instance
Martin Geisler <mg@aragost.com>
parents: 14217
diff changeset
1857 ui.warn(str(inst) + '\n')
11021
c47a1cfad572 patch: minor cleanup of _applydiff
Mads Kiilerich <mads@kiilerich.com>
parents: 11020
diff changeset
1858 current_file = None
5650
5d3e2f918d65 patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents: 5649
diff changeset
1859 rejects += 1
5d3e2f918d65 patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents: 5649
diff changeset
1860 continue
5d3e2f918d65 patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents: 5649
diff changeset
1861 elif state == 'git':
11021
c47a1cfad572 patch: minor cleanup of _applydiff
Mads Kiilerich <mads@kiilerich.com>
parents: 11020
diff changeset
1862 for gp in values:
14452
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
1863 path = pstrip(gp.oldpath)
22296
650b5b6e75ed convert: use None value for missing files instead of overloading IOError
Mads Kiilerich <madski@unity3d.com>
parents: 21833
diff changeset
1864 data, mode = backend.getfile(path)
650b5b6e75ed convert: use None value for missing files instead of overloading IOError
Mads Kiilerich <madski@unity3d.com>
parents: 21833
diff changeset
1865 if data is None:
16813
6d42c797ca6e patch: keep patching after missing copy source (issue3480)
Patrick Mezard <patrick@mezard.eu>
parents: 16650
diff changeset
1866 # 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
1867 # 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
1868 # 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
1869 # process.
22296
650b5b6e75ed convert: use None value for missing files instead of overloading IOError
Mads Kiilerich <madski@unity3d.com>
parents: 21833
diff changeset
1870 pass
16813
6d42c797ca6e patch: keep patching after missing copy source (issue3480)
Patrick Mezard <patrick@mezard.eu>
parents: 16650
diff changeset
1871 else:
6d42c797ca6e patch: keep patching after missing copy source (issue3480)
Patrick Mezard <patrick@mezard.eu>
parents: 16650
diff changeset
1872 store.setfile(path, data, mode)
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1873 else:
5650
5d3e2f918d65 patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents: 5649
diff changeset
1874 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
1875
13701
bc38ff7cb919 patch: move closefile() into patchfile.close()
Patrick Mezard <pmezard@gmail.com>
parents: 13700
diff changeset
1876 if current_file:
bc38ff7cb919 patch: move closefile() into patchfile.close()
Patrick Mezard <pmezard@gmail.com>
parents: 13700
diff changeset
1877 rejects += current_file.close()
5650
5d3e2f918d65 patch: move diff parsing in iterhunks generator
Patrick Mezard <pmezard@gmail.com>
parents: 5649
diff changeset
1878
4897
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1879 if rejects:
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1880 return -1
4574925db5c0 Add Chris Mason's mpatch library.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4778
diff changeset
1881 return err
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2868
diff changeset
1882
14382
2d16f15da7bd patch: remove patch.patch() cwd argument
Patrick Mezard <pmezard@gmail.com>
parents: 14381
diff changeset
1883 def _externalpatch(ui, repo, patcher, patchname, strip, files,
14381
d4192500586a patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents: 14370
diff changeset
1884 similarity):
7151
b5bc5293021c patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents: 7150
diff changeset
1885 """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
1886 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
1887
b5bc5293021c patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents: 7150
diff changeset
1888 fuzz = False
12673
9ad16d1bce4b patch: simplify externalpatch() arguments
Patrick Mezard <pmezard@gmail.com>
parents: 12671
diff changeset
1889 args = []
14382
2d16f15da7bd patch: remove patch.patch() cwd argument
Patrick Mezard <pmezard@gmail.com>
parents: 14381
diff changeset
1890 cwd = repo.root
7151
b5bc5293021c patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents: 7150
diff changeset
1891 if cwd:
b5bc5293021c patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents: 7150
diff changeset
1892 args.append('-d %s' % util.shellquote(cwd))
b5bc5293021c patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents: 7150
diff changeset
1893 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
1894 util.shellquote(patchname)))
14381
d4192500586a patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents: 14370
diff changeset
1895 try:
d4192500586a patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents: 14370
diff changeset
1896 for line in fp:
d4192500586a patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents: 14370
diff changeset
1897 line = line.rstrip()
d4192500586a patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents: 14370
diff changeset
1898 ui.note(line + '\n')
d4192500586a patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents: 14370
diff changeset
1899 if line.startswith('patching file '):
d4192500586a patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents: 14370
diff changeset
1900 pf = util.parsepatchoutput(line)
d4192500586a patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents: 14370
diff changeset
1901 printed_file = False
14564
65f4512e40e4 patch: turn patch() touched files dict into a set
Patrick Mezard <pmezard@gmail.com>
parents: 14535
diff changeset
1902 files.add(pf)
14381
d4192500586a patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents: 14370
diff changeset
1903 elif line.find('with fuzz') >= 0:
d4192500586a patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents: 14370
diff changeset
1904 fuzz = True
d4192500586a patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents: 14370
diff changeset
1905 if not printed_file:
d4192500586a patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents: 14370
diff changeset
1906 ui.warn(pf + '\n')
d4192500586a patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents: 14370
diff changeset
1907 printed_file = True
d4192500586a patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents: 14370
diff changeset
1908 ui.warn(line + '\n')
d4192500586a patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents: 14370
diff changeset
1909 elif line.find('saving rejects to file') >= 0:
d4192500586a patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents: 14370
diff changeset
1910 ui.warn(line + '\n')
d4192500586a patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents: 14370
diff changeset
1911 elif line.find('FAILED') >= 0:
d4192500586a patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents: 14370
diff changeset
1912 if not printed_file:
d4192500586a patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents: 14370
diff changeset
1913 ui.warn(pf + '\n')
d4192500586a patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents: 14370
diff changeset
1914 printed_file = True
d4192500586a patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents: 14370
diff changeset
1915 ui.warn(line + '\n')
d4192500586a patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents: 14370
diff changeset
1916 finally:
d4192500586a patch: merge _updatedir() into externalpatch()
Patrick Mezard <pmezard@gmail.com>
parents: 14370
diff changeset
1917 if files:
19155
0b3689a08df5 patch: use scmutil.marktouched instead of scmutil.addremove
Siddharth Agarwal <sid0@fb.com>
parents: 18830
diff changeset
1918 scmutil.marktouched(repo, files, similarity)
7151
b5bc5293021c patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents: 7150
diff changeset
1919 code = fp.close()
b5bc5293021c patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents: 7150
diff changeset
1920 if code:
b5bc5293021c patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents: 7150
diff changeset
1921 raise PatchError(_("patch command failed: %s") %
14234
600e64004eb5 rename explain_exit to explainexit
Adrian Buehlmann <adrian@cadifra.com>
parents: 14231
diff changeset
1922 util.explainexit(code)[0])
7151
b5bc5293021c patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents: 7150
diff changeset
1923 return fuzz
b5bc5293021c patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents: 7150
diff changeset
1924
24253
26fa5ff9e660 patch.patchbackend: accept a prefix parameter
Siddharth Agarwal <sid0@fb.com>
parents: 24247
diff changeset
1925 def patchbackend(ui, backend, patchobj, strip, prefix, files=None,
26fa5ff9e660 patch.patchbackend: accept a prefix parameter
Siddharth Agarwal <sid0@fb.com>
parents: 24247
diff changeset
1926 eolmode='strict'):
9683
5c8651e2f5e0 patch: don't use mutable object as default argument
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9682
diff changeset
1927 if files is None:
14564
65f4512e40e4 patch: turn patch() touched files dict into a set
Patrick Mezard <pmezard@gmail.com>
parents: 14535
diff changeset
1928 files = set()
8810
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
1929 if eolmode is None:
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
1930 eolmode = ui.config('patch', 'eol', 'strict')
10101
155fe35534d3 patch: propagate eolmode down to patchfile
Martin Geisler <mg@lazybytes.net>
parents: 9725
diff changeset
1931 if eolmode.lower() not in eolmodes:
12067
a4fbbe0fbc38 Lowercase error messages
Martin Geisler <mg@lazybytes.net>
parents: 11645
diff changeset
1932 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
1933 eolmode = eolmode.lower()
8843
eb7b247a98ea kill trailing whitespace
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8817
diff changeset
1934
14452
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
1935 store = filestore()
7151
b5bc5293021c patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents: 7150
diff changeset
1936 try:
9031
3b76321aa0de compat: use open() instead of file() everywhere
Alejandro Santos <alejolp@alejolp.com>
parents: 9029
diff changeset
1937 fp = open(patchobj, 'rb')
7151
b5bc5293021c patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents: 7150
diff changeset
1938 except TypeError:
b5bc5293021c patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents: 7150
diff changeset
1939 fp = patchobj
b5bc5293021c patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents: 7150
diff changeset
1940 try:
24253
26fa5ff9e660 patch.patchbackend: accept a prefix parameter
Siddharth Agarwal <sid0@fb.com>
parents: 24247
diff changeset
1941 ret = applydiff(ui, fp, backend, store, strip=strip, prefix=prefix,
14452
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
1942 eolmode=eolmode)
7151
b5bc5293021c patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents: 7150
diff changeset
1943 finally:
10203
6e26e3c2083f patch: explicitely close input patch files when leaving
Patrick Mezard <pmezard@gmail.com>
parents: 10135
diff changeset
1944 if fp != patchobj:
6e26e3c2083f patch: explicitely close input patch files when leaving
Patrick Mezard <pmezard@gmail.com>
parents: 10135
diff changeset
1945 fp.close()
14564
65f4512e40e4 patch: turn patch() touched files dict into a set
Patrick Mezard <pmezard@gmail.com>
parents: 14535
diff changeset
1946 files.update(backend.close())
14452
ee574cfd0c32 patch: use temporary files to handle intermediate copies
Patrick Mezard <pmezard@gmail.com>
parents: 14451
diff changeset
1947 store.close()
7151
b5bc5293021c patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents: 7150
diff changeset
1948 if ret < 0:
12674
aa2fe1f52ff4 patch: always raise PatchError with a message, simplify handling
Patrick Mezard <pmezard@gmail.com>
parents: 12673
diff changeset
1949 raise PatchError(_('patch failed to apply'))
7151
b5bc5293021c patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents: 7150
diff changeset
1950 return ret > 0
b5bc5293021c patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents: 7150
diff changeset
1951
24268
cf7d252d8c30 patch.internalpatch: add a default value for prefix
Siddharth Agarwal <sid0@fb.com>
parents: 24265
diff changeset
1952 def internalpatch(ui, repo, patchobj, strip, prefix='', files=None,
24254
60c279ab7bd3 patch.internalpatch: accept a prefix parameter
Siddharth Agarwal <sid0@fb.com>
parents: 24253
diff changeset
1953 eolmode='strict', similarity=0):
14611
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
1954 """use builtin patch to apply <patchobj> to the working directory.
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
1955 returns whether patch was applied with fuzz factor."""
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
1956 backend = workingbackend(ui, repo, similarity)
24254
60c279ab7bd3 patch.internalpatch: accept a prefix parameter
Siddharth Agarwal <sid0@fb.com>
parents: 24253
diff changeset
1957 return patchbackend(ui, backend, patchobj, strip, prefix, files, eolmode)
14611
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
1958
24260
76225ab5a5da cmdutil.tryimportone: allow importing relative patches with --bypass
Siddharth Agarwal <sid0@fb.com>
parents: 24259
diff changeset
1959 def patchrepo(ui, repo, ctx, store, patchobj, strip, prefix, files=None,
14611
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
1960 eolmode='strict'):
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
1961 backend = repobackend(ui, repo, ctx, store)
24260
76225ab5a5da cmdutil.tryimportone: allow importing relative patches with --bypass
Siddharth Agarwal <sid0@fb.com>
parents: 24259
diff changeset
1962 return patchbackend(ui, backend, patchobj, strip, prefix, files, eolmode)
14611
adbf5e7df96d import: add --bypass option
Patrick Mezard <pmezard@gmail.com>
parents: 14609
diff changeset
1963
24259
5ac8ce04baa2 cmdutil.tryimportone: allow importing relative patches into the working dir
Siddharth Agarwal <sid0@fb.com>
parents: 24254
diff changeset
1964 def patch(ui, repo, patchname, strip=1, prefix='', files=None, eolmode='strict',
14260
00a881581400 patch: make patch()/internalpatch() always update the dirstate
Patrick Mezard <pmezard@gmail.com>
parents: 14259
diff changeset
1965 similarity=0):
8810
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
1966 """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
1967
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
1968 '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
1969 - '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
1970 - '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
1971 - '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
1972 - 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
1973 '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
1974
ac92775b3b80 Add patch.eol to ignore EOLs when patching (issue1019)
Patrick Mezard <pmezard@gmail.com>
parents: 8778
diff changeset
1975 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
1976 """
7151
b5bc5293021c patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents: 7150
diff changeset
1977 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
1978 if files is None:
14564
65f4512e40e4 patch: turn patch() touched files dict into a set
Patrick Mezard <pmezard@gmail.com>
parents: 14535
diff changeset
1979 files = set()
21553
bee0e1cffdd3 import: add --partial flag to create a changeset despite failed hunks
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20972
diff changeset
1980 if patcher:
bee0e1cffdd3 import: add --partial flag to create a changeset despite failed hunks
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20972
diff changeset
1981 return _externalpatch(ui, repo, patcher, patchname, strip,
bee0e1cffdd3 import: add --partial flag to create a changeset despite failed hunks
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20972
diff changeset
1982 files, similarity)
24259
5ac8ce04baa2 cmdutil.tryimportone: allow importing relative patches into the working dir
Siddharth Agarwal <sid0@fb.com>
parents: 24254
diff changeset
1983 return internalpatch(ui, repo, patchname, strip, prefix, files, eolmode,
21553
bee0e1cffdd3 import: add --partial flag to create a changeset despite failed hunks
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20972
diff changeset
1984 similarity)
7151
b5bc5293021c patch: change functions definition order for readability
Patrick Mezard <pmezard@gmail.com>
parents: 7150
diff changeset
1985
14351
d54f9bbcc640 patch: add lexists() to backends, use it in selectfile()
Patrick Mezard <pmezard@gmail.com>
parents: 14350
diff changeset
1986 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
1987 backend = fsbackend(ui, repo.root)
14255
576256a81cb6 patch: introduce changedfiles
Idan Kamara <idankk86@gmail.com>
parents: 14240
diff changeset
1988 fp = open(patchpath, 'rb')
576256a81cb6 patch: introduce changedfiles
Idan Kamara <idankk86@gmail.com>
parents: 14240
diff changeset
1989 try:
576256a81cb6 patch: introduce changedfiles
Idan Kamara <idankk86@gmail.com>
parents: 14240
diff changeset
1990 changed = set()
576256a81cb6 patch: introduce changedfiles
Idan Kamara <idankk86@gmail.com>
parents: 14240
diff changeset
1991 for state, values in iterhunks(fp):
14389
909ac6b9636b patch: stop modifying gitpatch objects
Patrick Mezard <pmezard@gmail.com>
parents: 14388
diff changeset
1992 if state == 'file':
14388
37c997d21752 patch: stop handling hunkless git blocks out of stream
Patrick Mezard <pmezard@gmail.com>
parents: 14387
diff changeset
1993 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
1994 if gp:
24244
5918bb365c72 patch.pathtransform: add a prefix parameter
Siddharth Agarwal <sid0@fb.com>
parents: 24243
diff changeset
1995 gp.path = pathtransform(gp.path, strip - 1, '')[1]
14566
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
1996 if gp.oldpath:
24244
5918bb365c72 patch.pathtransform: add a prefix parameter
Siddharth Agarwal <sid0@fb.com>
parents: 24243
diff changeset
1997 gp.oldpath = pathtransform(gp.oldpath, strip - 1, '')[1]
14566
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
1998 else:
24245
740a17f885a1 patch.makepatchmeta: accept a prefix parameter
Siddharth Agarwal <sid0@fb.com>
parents: 24244
diff changeset
1999 gp = makepatchmeta(backend, afile, bfile, first_hunk, strip,
740a17f885a1 patch.makepatchmeta: accept a prefix parameter
Siddharth Agarwal <sid0@fb.com>
parents: 24244
diff changeset
2000 '')
14566
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
2001 changed.add(gp.path)
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
2002 if gp.op == 'RENAME':
d0c2cc11e611 patch: generalize the use of patchmeta in applydiff()
Patrick Mezard <pmezard@gmail.com>
parents: 14565
diff changeset
2003 changed.add(gp.oldpath)
14389
909ac6b9636b patch: stop modifying gitpatch objects
Patrick Mezard <pmezard@gmail.com>
parents: 14388
diff changeset
2004 elif state not in ('hunk', 'git'):
14255
576256a81cb6 patch: introduce changedfiles
Idan Kamara <idankk86@gmail.com>
parents: 14240
diff changeset
2005 raise util.Abort(_('unsupported parser state: %s') % state)
576256a81cb6 patch: introduce changedfiles
Idan Kamara <idankk86@gmail.com>
parents: 14240
diff changeset
2006 return changed
576256a81cb6 patch: introduce changedfiles
Idan Kamara <idankk86@gmail.com>
parents: 14240
diff changeset
2007 finally:
576256a81cb6 patch: introduce changedfiles
Idan Kamara <idankk86@gmail.com>
parents: 14240
diff changeset
2008 fp.close()
576256a81cb6 patch: introduce changedfiles
Idan Kamara <idankk86@gmail.com>
parents: 14240
diff changeset
2009
10189
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10151
diff changeset
2010 class GitDiffRequired(Exception):
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10151
diff changeset
2011 pass
7198
df79ee9b6278 patch: extract local function addmodehdr
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7186
diff changeset
2012
23431
10223d2278f4 patch: rename diffopts to diffallopts
Siddharth Agarwal <sid0@fb.com>
parents: 23430
diff changeset
2013 def diffallopts(ui, opts=None, untrusted=False, section='diff'):
23430
3821be85fd4d patch: add a new function to initialize diffopts by feature
Siddharth Agarwal <sid0@fb.com>
parents: 23429
diff changeset
2014 '''return diffopts with all features supported and parsed'''
23433
41dd76b3facb patch.difffeatureopts: add a feature for whitespace diffopts
Siddharth Agarwal <sid0@fb.com>
parents: 23432
diff changeset
2015 return difffeatureopts(ui, opts=opts, untrusted=untrusted, section=section,
23434
60300a4c0ae5 patch.difffeatureopts: add a feature for format-changing diffopts
Siddharth Agarwal <sid0@fb.com>
parents: 23433
diff changeset
2016 git=True, whitespace=True, formatchanging=True)
23430
3821be85fd4d patch: add a new function to initialize diffopts by feature
Siddharth Agarwal <sid0@fb.com>
parents: 23429
diff changeset
2017
23431
10223d2278f4 patch: rename diffopts to diffallopts
Siddharth Agarwal <sid0@fb.com>
parents: 23430
diff changeset
2018 diffopts = diffallopts
10223d2278f4 patch: rename diffopts to diffallopts
Siddharth Agarwal <sid0@fb.com>
parents: 23430
diff changeset
2019
23433
41dd76b3facb patch.difffeatureopts: add a feature for whitespace diffopts
Siddharth Agarwal <sid0@fb.com>
parents: 23432
diff changeset
2020 def difffeatureopts(ui, opts=None, untrusted=False, section='diff', git=False,
23434
60300a4c0ae5 patch.difffeatureopts: add a feature for format-changing diffopts
Siddharth Agarwal <sid0@fb.com>
parents: 23433
diff changeset
2021 whitespace=False, formatchanging=False):
23432
27af986a332b patch.difffeatureopts: add a feature for diff.git
Siddharth Agarwal <sid0@fb.com>
parents: 23431
diff changeset
2022 '''return diffopts with only opted-in features parsed
27af986a332b patch.difffeatureopts: add a feature for diff.git
Siddharth Agarwal <sid0@fb.com>
parents: 23431
diff changeset
2023
27af986a332b patch.difffeatureopts: add a feature for diff.git
Siddharth Agarwal <sid0@fb.com>
parents: 23431
diff changeset
2024 Features:
27af986a332b patch.difffeatureopts: add a feature for diff.git
Siddharth Agarwal <sid0@fb.com>
parents: 23431
diff changeset
2025 - git: git-style diffs
23433
41dd76b3facb patch.difffeatureopts: add a feature for whitespace diffopts
Siddharth Agarwal <sid0@fb.com>
parents: 23432
diff changeset
2026 - whitespace: whitespace options like ignoreblanklines and ignorews
23434
60300a4c0ae5 patch.difffeatureopts: add a feature for format-changing diffopts
Siddharth Agarwal <sid0@fb.com>
parents: 23433
diff changeset
2027 - formatchanging: options that will likely break or cause correctness issues
60300a4c0ae5 patch.difffeatureopts: add a feature for format-changing diffopts
Siddharth Agarwal <sid0@fb.com>
parents: 23433
diff changeset
2028 with most diff parsers
23432
27af986a332b patch.difffeatureopts: add a feature for diff.git
Siddharth Agarwal <sid0@fb.com>
parents: 23431
diff changeset
2029 '''
23295
ac072c79bd9d patch.diffopts: break get function into if statements
Siddharth Agarwal <sid0@fb.com>
parents: 22460
diff changeset
2030 def get(key, name=None, getter=ui.configbool, forceplain=None):
ac072c79bd9d patch.diffopts: break get function into if statements
Siddharth Agarwal <sid0@fb.com>
parents: 22460
diff changeset
2031 if opts:
ac072c79bd9d patch.diffopts: break get function into if statements
Siddharth Agarwal <sid0@fb.com>
parents: 22460
diff changeset
2032 v = opts.get(key)
ac072c79bd9d patch.diffopts: break get function into if statements
Siddharth Agarwal <sid0@fb.com>
parents: 22460
diff changeset
2033 if v:
ac072c79bd9d patch.diffopts: break get function into if statements
Siddharth Agarwal <sid0@fb.com>
parents: 22460
diff changeset
2034 return v
23296
922fcfb02e77 patch.diffopts: allow a setting to be forced in plain mode
Siddharth Agarwal <sid0@fb.com>
parents: 23295
diff changeset
2035 if forceplain is not None and ui.plain():
922fcfb02e77 patch.diffopts: allow a setting to be forced in plain mode
Siddharth Agarwal <sid0@fb.com>
parents: 23295
diff changeset
2036 return forceplain
23295
ac072c79bd9d patch.diffopts: break get function into if statements
Siddharth Agarwal <sid0@fb.com>
parents: 22460
diff changeset
2037 return getter(section, name or key, None, untrusted=untrusted)
ac072c79bd9d patch.diffopts: break get function into if statements
Siddharth Agarwal <sid0@fb.com>
parents: 22460
diff changeset
2038
23434
60300a4c0ae5 patch.difffeatureopts: add a feature for format-changing diffopts
Siddharth Agarwal <sid0@fb.com>
parents: 23433
diff changeset
2039 # core options, expected to be understood by every diff parser
23429
f35526b999f4 patch.diffopts: use a dict for initialization
Siddharth Agarwal <sid0@fb.com>
parents: 23300
diff changeset
2040 buildopts = {
f35526b999f4 patch.diffopts: use a dict for initialization
Siddharth Agarwal <sid0@fb.com>
parents: 23300
diff changeset
2041 'nodates': get('nodates'),
f35526b999f4 patch.diffopts: use a dict for initialization
Siddharth Agarwal <sid0@fb.com>
parents: 23300
diff changeset
2042 'showfunc': get('show_function', 'showfunc'),
f35526b999f4 patch.diffopts: use a dict for initialization
Siddharth Agarwal <sid0@fb.com>
parents: 23300
diff changeset
2043 'context': get('unified', getter=ui.config),
f35526b999f4 patch.diffopts: use a dict for initialization
Siddharth Agarwal <sid0@fb.com>
parents: 23300
diff changeset
2044 }
f35526b999f4 patch.diffopts: use a dict for initialization
Siddharth Agarwal <sid0@fb.com>
parents: 23300
diff changeset
2045
23432
27af986a332b patch.difffeatureopts: add a feature for diff.git
Siddharth Agarwal <sid0@fb.com>
parents: 23431
diff changeset
2046 if git:
27af986a332b patch.difffeatureopts: add a feature for diff.git
Siddharth Agarwal <sid0@fb.com>
parents: 23431
diff changeset
2047 buildopts['git'] = get('git')
23433
41dd76b3facb patch.difffeatureopts: add a feature for whitespace diffopts
Siddharth Agarwal <sid0@fb.com>
parents: 23432
diff changeset
2048 if whitespace:
41dd76b3facb patch.difffeatureopts: add a feature for whitespace diffopts
Siddharth Agarwal <sid0@fb.com>
parents: 23432
diff changeset
2049 buildopts['ignorews'] = get('ignore_all_space', 'ignorews')
41dd76b3facb patch.difffeatureopts: add a feature for whitespace diffopts
Siddharth Agarwal <sid0@fb.com>
parents: 23432
diff changeset
2050 buildopts['ignorewsamount'] = get('ignore_space_change',
41dd76b3facb patch.difffeatureopts: add a feature for whitespace diffopts
Siddharth Agarwal <sid0@fb.com>
parents: 23432
diff changeset
2051 'ignorewsamount')
41dd76b3facb patch.difffeatureopts: add a feature for whitespace diffopts
Siddharth Agarwal <sid0@fb.com>
parents: 23432
diff changeset
2052 buildopts['ignoreblanklines'] = get('ignore_blank_lines',
41dd76b3facb patch.difffeatureopts: add a feature for whitespace diffopts
Siddharth Agarwal <sid0@fb.com>
parents: 23432
diff changeset
2053 'ignoreblanklines')
23434
60300a4c0ae5 patch.difffeatureopts: add a feature for format-changing diffopts
Siddharth Agarwal <sid0@fb.com>
parents: 23433
diff changeset
2054 if formatchanging:
60300a4c0ae5 patch.difffeatureopts: add a feature for format-changing diffopts
Siddharth Agarwal <sid0@fb.com>
parents: 23433
diff changeset
2055 buildopts['text'] = opts and opts.get('text')
60300a4c0ae5 patch.difffeatureopts: add a feature for format-changing diffopts
Siddharth Agarwal <sid0@fb.com>
parents: 23433
diff changeset
2056 buildopts['nobinary'] = get('nobinary')
60300a4c0ae5 patch.difffeatureopts: add a feature for format-changing diffopts
Siddharth Agarwal <sid0@fb.com>
parents: 23433
diff changeset
2057 buildopts['noprefix'] = get('noprefix', forceplain=False)
23432
27af986a332b patch.difffeatureopts: add a feature for diff.git
Siddharth Agarwal <sid0@fb.com>
parents: 23431
diff changeset
2058
23429
f35526b999f4 patch.diffopts: use a dict for initialization
Siddharth Agarwal <sid0@fb.com>
parents: 23300
diff changeset
2059 return mdiff.diffopts(**buildopts)
10615
3bb438ce4458 patch/diff: move diff related code next to each other
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10611
diff changeset
2060
10189
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10151
diff changeset
2061 def diff(repo, node1=None, node2=None, match=None, changes=None, opts=None,
24417
f2e1e097cda1 patch.diff: add support for diffs relative to a subdirectory
Siddharth Agarwal <sid0@fb.com>
parents: 24416
diff changeset
2062 losedatafn=None, prefix='', relroot=''):
7308
b6f5490effbf patch: turn patch.diff() into a generator
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7267
diff changeset
2063 '''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
2064 working directory.
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2868
diff changeset
2065
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2868
diff changeset
2066 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
2067 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
2068
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10151
diff changeset
2069 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
2070 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
2071 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
2072 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
2073 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
2074 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
2075 necessary.
12167
d2c5b0927c28 diff: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12144
diff changeset
2076
d2c5b0927c28 diff: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12144
diff changeset
2077 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
2078 display (used for subrepos).
24417
f2e1e097cda1 patch.diff: add support for diffs relative to a subdirectory
Siddharth Agarwal <sid0@fb.com>
parents: 24416
diff changeset
2079
f2e1e097cda1 patch.diff: add support for diffs relative to a subdirectory
Siddharth Agarwal <sid0@fb.com>
parents: 24416
diff changeset
2080 relroot, if not empty, must be normalized with a trailing /. Any match
f2e1e097cda1 patch.diff: add support for diffs relative to a subdirectory
Siddharth Agarwal <sid0@fb.com>
parents: 24416
diff changeset
2081 patterns that fall outside it will be ignored.'''
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2868
diff changeset
2082
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2868
diff changeset
2083 if opts is None:
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2868
diff changeset
2084 opts = mdiff.defaultopts
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2868
diff changeset
2085
9725
3f522d2fa633 diff: add --inverse option
Yannick Gingras <ygingras@ygingras.net>
parents: 9712
diff changeset
2086 if not node1 and not node2:
13878
a8d13ee0ce68 misc: replace .parents()[0] with p1()
Matt Mackall <mpm@selenic.com>
parents: 13751
diff changeset
2087 node1 = repo.dirstate.p1()
2934
2f190e998eb3 Teach mq about git patches
Brendan Cully <brendan@kublai.com>
parents: 2933
diff changeset
2088
9123
360f61c2919f Make patch.diff filelog cache LRU of 20 files. Fixes issue1738.
Brendan Cully <brendan@kublai.com>
parents: 8891
diff changeset
2089 def lrugetfilectx():
360f61c2919f Make patch.diff filelog cache LRU of 20 files. Fixes issue1738.
Brendan Cully <brendan@kublai.com>
parents: 8891
diff changeset
2090 cache = {}
16834
cafd8a8fb713 util: subclass deque for Python 2.4 backwards compatibility
Bryan O'Sullivan <bryano@fb.com>
parents: 16828
diff changeset
2091 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
2092 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
2093 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
2094 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
2095 if len(cache) > 20:
16803
107a3270a24a cleanup: use the deque type where appropriate
Bryan O'Sullivan <bryano@fb.com>
parents: 16705
diff changeset
2096 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
2097 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
2098 else:
360f61c2919f Make patch.diff filelog cache LRU of 20 files. Fixes issue1738.
Brendan Cully <brendan@kublai.com>
parents: 8891
diff changeset
2099 order.remove(f)
360f61c2919f Make patch.diff filelog cache LRU of 20 files. Fixes issue1738.
Brendan Cully <brendan@kublai.com>
parents: 8891
diff changeset
2100 order.append(f)
360f61c2919f Make patch.diff filelog cache LRU of 20 files. Fixes issue1738.
Brendan Cully <brendan@kublai.com>
parents: 8891
diff changeset
2101 return fctx
360f61c2919f Make patch.diff filelog cache LRU of 20 files. Fixes issue1738.
Brendan Cully <brendan@kublai.com>
parents: 8891
diff changeset
2102 return getfilectx
360f61c2919f Make patch.diff filelog cache LRU of 20 files. Fixes issue1738.
Brendan Cully <brendan@kublai.com>
parents: 8891
diff changeset
2103 getfilectx = lrugetfilectx()
2934
2f190e998eb3 Teach mq about git patches
Brendan Cully <brendan@kublai.com>
parents: 2933
diff changeset
2104
6747
f6c00b17387c use repo[changeid] to get a changectx
Matt Mackall <mpm@selenic.com>
parents: 6743
diff changeset
2105 ctx1 = repo[node1]
7090
7b5c063b0b94 diff: pass contexts to status
Matt Mackall <mpm@selenic.com>
parents: 6953
diff changeset
2106 ctx2 = repo[node2]
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2868
diff changeset
2107
24433
f5f4dc115fb2 patch.diff: restrict matcher to relative root in certain cases
Siddharth Agarwal <sid0@fb.com>
parents: 24417
diff changeset
2108 relfiltered = False
f5f4dc115fb2 patch.diff: restrict matcher to relative root in certain cases
Siddharth Agarwal <sid0@fb.com>
parents: 24417
diff changeset
2109 if relroot != '' and match.always():
f5f4dc115fb2 patch.diff: restrict matcher to relative root in certain cases
Siddharth Agarwal <sid0@fb.com>
parents: 24417
diff changeset
2110 # as a special case, create a new matcher with just the relroot
f5f4dc115fb2 patch.diff: restrict matcher to relative root in certain cases
Siddharth Agarwal <sid0@fb.com>
parents: 24417
diff changeset
2111 pats = [relroot]
f5f4dc115fb2 patch.diff: restrict matcher to relative root in certain cases
Siddharth Agarwal <sid0@fb.com>
parents: 24417
diff changeset
2112 match = scmutil.match(ctx2, pats, default='path')
f5f4dc115fb2 patch.diff: restrict matcher to relative root in certain cases
Siddharth Agarwal <sid0@fb.com>
parents: 24417
diff changeset
2113 relfiltered = True
f5f4dc115fb2 patch.diff: restrict matcher to relative root in certain cases
Siddharth Agarwal <sid0@fb.com>
parents: 24417
diff changeset
2114
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2868
diff changeset
2115 if not changes:
7090
7b5c063b0b94 diff: pass contexts to status
Matt Mackall <mpm@selenic.com>
parents: 6953
diff changeset
2116 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
2117 modified, added, removed = changes[:3]
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2868
diff changeset
2118
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2868
diff changeset
2119 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
2120 return []
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10151
diff changeset
2121
24306
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24269
diff changeset
2122 if repo.ui.debugflag:
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24269
diff changeset
2123 hexfunc = hex
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24269
diff changeset
2124 else:
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24269
diff changeset
2125 hexfunc = short
21833
c1ceec0c8cb4 patch: use ctx.node() instead of bare node variable
Sean Farley <sean.michael.farley@gmail.com>
parents: 21790
diff changeset
2126 revs = [hexfunc(node) for node in [ctx1.node(), ctx2.node()] if node]
10189
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10151
diff changeset
2127
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10151
diff changeset
2128 copy = {}
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10151
diff changeset
2129 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
2130 copy = copies.pathcopies(ctx1, ctx2)
10189
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10151
diff changeset
2131
24417
f2e1e097cda1 patch.diff: add support for diffs relative to a subdirectory
Siddharth Agarwal <sid0@fb.com>
parents: 24416
diff changeset
2132 if relroot is not None:
24433
f5f4dc115fb2 patch.diff: restrict matcher to relative root in certain cases
Siddharth Agarwal <sid0@fb.com>
parents: 24417
diff changeset
2133 if not relfiltered:
f5f4dc115fb2 patch.diff: restrict matcher to relative root in certain cases
Siddharth Agarwal <sid0@fb.com>
parents: 24417
diff changeset
2134 # XXX this would ideally be done in the matcher, but that is
f5f4dc115fb2 patch.diff: restrict matcher to relative root in certain cases
Siddharth Agarwal <sid0@fb.com>
parents: 24417
diff changeset
2135 # generally meant to 'or' patterns, not 'and' them. In this case we
f5f4dc115fb2 patch.diff: restrict matcher to relative root in certain cases
Siddharth Agarwal <sid0@fb.com>
parents: 24417
diff changeset
2136 # need to 'and' all the patterns from the matcher with relroot.
f5f4dc115fb2 patch.diff: restrict matcher to relative root in certain cases
Siddharth Agarwal <sid0@fb.com>
parents: 24417
diff changeset
2137 def filterrel(l):
f5f4dc115fb2 patch.diff: restrict matcher to relative root in certain cases
Siddharth Agarwal <sid0@fb.com>
parents: 24417
diff changeset
2138 return [f for f in l if f.startswith(relroot)]
f5f4dc115fb2 patch.diff: restrict matcher to relative root in certain cases
Siddharth Agarwal <sid0@fb.com>
parents: 24417
diff changeset
2139 modified = filterrel(modified)
f5f4dc115fb2 patch.diff: restrict matcher to relative root in certain cases
Siddharth Agarwal <sid0@fb.com>
parents: 24417
diff changeset
2140 added = filterrel(added)
f5f4dc115fb2 patch.diff: restrict matcher to relative root in certain cases
Siddharth Agarwal <sid0@fb.com>
parents: 24417
diff changeset
2141 removed = filterrel(removed)
f5f4dc115fb2 patch.diff: restrict matcher to relative root in certain cases
Siddharth Agarwal <sid0@fb.com>
parents: 24417
diff changeset
2142 relfiltered = True
24417
f2e1e097cda1 patch.diff: add support for diffs relative to a subdirectory
Siddharth Agarwal <sid0@fb.com>
parents: 24416
diff changeset
2143 # filter out copies where either side isn't inside the relative root
f2e1e097cda1 patch.diff: add support for diffs relative to a subdirectory
Siddharth Agarwal <sid0@fb.com>
parents: 24416
diff changeset
2144 copy = dict(((dst, src) for (dst, src) in copy.iteritems()
f2e1e097cda1 patch.diff: add support for diffs relative to a subdirectory
Siddharth Agarwal <sid0@fb.com>
parents: 24416
diff changeset
2145 if dst.startswith(relroot)
f2e1e097cda1 patch.diff: add support for diffs relative to a subdirectory
Siddharth Agarwal <sid0@fb.com>
parents: 24416
diff changeset
2146 and src.startswith(relroot)))
f2e1e097cda1 patch.diff: add support for diffs relative to a subdirectory
Siddharth Agarwal <sid0@fb.com>
parents: 24416
diff changeset
2147
17299
e51d4aedace9 check-code: indent 4 spaces in py files
Mads Kiilerich <mads@kiilerich.com>
parents: 16834
diff changeset
2148 def difffn(opts, losedata):
e51d4aedace9 check-code: indent 4 spaces in py files
Mads Kiilerich <mads@kiilerich.com>
parents: 16834
diff changeset
2149 return trydiff(repo, revs, ctx1, ctx2, modified, added, removed,
24417
f2e1e097cda1 patch.diff: add support for diffs relative to a subdirectory
Siddharth Agarwal <sid0@fb.com>
parents: 24416
diff changeset
2150 copy, getfilectx, opts, losedata, prefix, relroot)
10189
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10151
diff changeset
2151 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
2152 try:
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10151
diff changeset
2153 def losedata(fn):
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10151
diff changeset
2154 if not losedatafn or not losedatafn(fn=fn):
16687
e34106fa0dc3 cleanup: "raise SomeException()" -> "raise SomeException"
Brodie Rao <brodie@sf.io>
parents: 16686
diff changeset
2155 raise GitDiffRequired
10189
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10151
diff changeset
2156 # 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
2157 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
2158 except GitDiffRequired:
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10151
diff changeset
2159 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
2160 else:
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10151
diff changeset
2161 return difffn(opts, None)
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10151
diff changeset
2162
10818
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
2163 def difflabel(func, *args, **kw):
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
2164 '''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
2165 headprefixes = [('diff', 'diff.diffline'),
2c4fdee4d1a8 diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents: 15159
diff changeset
2166 ('copy', 'diff.extended'),
2c4fdee4d1a8 diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents: 15159
diff changeset
2167 ('rename', 'diff.extended'),
2c4fdee4d1a8 diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents: 15159
diff changeset
2168 ('old', 'diff.extended'),
2c4fdee4d1a8 diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents: 15159
diff changeset
2169 ('new', 'diff.extended'),
2c4fdee4d1a8 diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents: 15159
diff changeset
2170 ('deleted', 'diff.extended'),
2c4fdee4d1a8 diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents: 15159
diff changeset
2171 ('---', 'diff.file_a'),
2c4fdee4d1a8 diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents: 15159
diff changeset
2172 ('+++', 'diff.file_b')]
2c4fdee4d1a8 diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents: 15159
diff changeset
2173 textprefixes = [('@', 'diff.hunk'),
2c4fdee4d1a8 diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents: 15159
diff changeset
2174 ('-', 'diff.deleted'),
2c4fdee4d1a8 diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents: 15159
diff changeset
2175 ('+', 'diff.inserted')]
2c4fdee4d1a8 diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents: 15159
diff changeset
2176 head = False
10818
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
2177 for chunk in func(*args, **kw):
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
2178 lines = chunk.split('\n')
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
2179 for i, line in enumerate(lines):
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
2180 if i != 0:
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
2181 yield ('\n', '')
15201
2c4fdee4d1a8 diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents: 15159
diff changeset
2182 if head:
2c4fdee4d1a8 diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents: 15159
diff changeset
2183 if line.startswith('@'):
2c4fdee4d1a8 diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents: 15159
diff changeset
2184 head = False
2c4fdee4d1a8 diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents: 15159
diff changeset
2185 else:
16686
67964cda8701 cleanup: "not x in y" -> "x not in y"
Brodie Rao <brodie@sf.io>
parents: 16683
diff changeset
2186 if line and line[0] not in ' +-@\\':
15201
2c4fdee4d1a8 diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents: 15159
diff changeset
2187 head = True
10818
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
2188 stripline = line
22460
c343557a8442 patch: enable diff.tab markup for the color extension
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 22296
diff changeset
2189 diffline = False
15201
2c4fdee4d1a8 diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents: 15159
diff changeset
2190 if not head and line and line[0] in '+-':
22460
c343557a8442 patch: enable diff.tab markup for the color extension
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 22296
diff changeset
2191 # highlight tabs and trailing whitespace, but only in
c343557a8442 patch: enable diff.tab markup for the color extension
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 22296
diff changeset
2192 # changed lines
10818
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
2193 stripline = line.rstrip()
22460
c343557a8442 patch: enable diff.tab markup for the color extension
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 22296
diff changeset
2194 diffline = True
c343557a8442 patch: enable diff.tab markup for the color extension
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 22296
diff changeset
2195
15201
2c4fdee4d1a8 diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents: 15159
diff changeset
2196 prefixes = textprefixes
2c4fdee4d1a8 diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents: 15159
diff changeset
2197 if head:
2c4fdee4d1a8 diff: enhance highlighting with color (issue3034)
Kirill Elagin <kirelagin@gmail.com>
parents: 15159
diff changeset
2198 prefixes = headprefixes
10818
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
2199 for prefix, label in prefixes:
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
2200 if stripline.startswith(prefix):
22460
c343557a8442 patch: enable diff.tab markup for the color extension
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 22296
diff changeset
2201 if diffline:
c343557a8442 patch: enable diff.tab markup for the color extension
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 22296
diff changeset
2202 for token in tabsplitter.findall(stripline):
c343557a8442 patch: enable diff.tab markup for the color extension
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 22296
diff changeset
2203 if '\t' == token[0]:
c343557a8442 patch: enable diff.tab markup for the color extension
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 22296
diff changeset
2204 yield (token, 'diff.tab')
c343557a8442 patch: enable diff.tab markup for the color extension
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 22296
diff changeset
2205 else:
c343557a8442 patch: enable diff.tab markup for the color extension
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 22296
diff changeset
2206 yield (token, label)
c343557a8442 patch: enable diff.tab markup for the color extension
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 22296
diff changeset
2207 else:
c343557a8442 patch: enable diff.tab markup for the color extension
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 22296
diff changeset
2208 yield (stripline, label)
10818
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
2209 break
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
2210 else:
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
2211 yield (line, '')
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
2212 if line != stripline:
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
2213 yield (line[len(stripline):], 'diff.trailingwhitespace')
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
2214
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
2215 def diffui(*args, **kw):
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
2216 '''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
2217 return difflabel(diff, *args, **kw)
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
2218
24106
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
2219 def _filepairs(ctx1, modified, added, removed, copy, opts):
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
2220 '''generates tuples (f1, f2, copyop), where f1 is the name of the file
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
2221 before and f2 is the the name after. For added files, f1 will be None,
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
2222 and for removed files, f2 will be None. copyop may be set to None, 'copy'
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
2223 or 'rename' (the latter two only if opts.git is set).'''
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
2224 gone = set()
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
2225
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
2226 copyto = dict([(v, k) for k, v in copy.items()])
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
2227
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
2228 addedset, removedset = set(added), set(removed)
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
2229 # Fix up added, since merged-in additions appear as
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
2230 # modifications during merges
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
2231 for f in modified:
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
2232 if f not in ctx1:
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
2233 addedset.add(f)
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
2234
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
2235 for f in sorted(modified + added + removed):
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
2236 copyop = None
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
2237 f1, f2 = f, f
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
2238 if f in addedset:
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
2239 f1 = None
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
2240 if f in copy:
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
2241 if opts.git:
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
2242 f1 = copy[f]
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
2243 if f1 in removedset and f1 not in gone:
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
2244 copyop = 'rename'
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
2245 gone.add(f1)
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
2246 else:
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
2247 copyop = 'copy'
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
2248 elif f in removedset:
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
2249 f2 = None
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
2250 if opts.git:
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
2251 # have we already reported a copy above?
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
2252 if (f in copyto and copyto[f] in addedset
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
2253 and copy[copyto[f]] == f):
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
2254 continue
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
2255 yield f1, f2, copyop
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
2256
10189
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10151
diff changeset
2257 def trydiff(repo, revs, ctx1, ctx2, modified, added, removed,
24416
f07047a506d1 patch.trydiff: add support for stripping a relative root
Siddharth Agarwal <sid0@fb.com>
parents: 24390
diff changeset
2258 copy, getfilectx, opts, losedatafn, prefix, relroot):
24371
8a997bd73448 patch.trydiff: add a docstring
Siddharth Agarwal <sid0@fb.com>
parents: 24346
diff changeset
2259 '''given input data, generate a diff and yield it in blocks
8a997bd73448 patch.trydiff: add a docstring
Siddharth Agarwal <sid0@fb.com>
parents: 24346
diff changeset
2260
8a997bd73448 patch.trydiff: add a docstring
Siddharth Agarwal <sid0@fb.com>
parents: 24346
diff changeset
2261 If generating a diff would lose data like flags or binary data and
8a997bd73448 patch.trydiff: add a docstring
Siddharth Agarwal <sid0@fb.com>
parents: 24346
diff changeset
2262 losedatafn is not None, it will be called.
8a997bd73448 patch.trydiff: add a docstring
Siddharth Agarwal <sid0@fb.com>
parents: 24346
diff changeset
2263
24416
f07047a506d1 patch.trydiff: add support for stripping a relative root
Siddharth Agarwal <sid0@fb.com>
parents: 24390
diff changeset
2264 relroot is removed and prefix is added to every path in the diff output.
f07047a506d1 patch.trydiff: add support for stripping a relative root
Siddharth Agarwal <sid0@fb.com>
parents: 24390
diff changeset
2265
f07047a506d1 patch.trydiff: add support for stripping a relative root
Siddharth Agarwal <sid0@fb.com>
parents: 24390
diff changeset
2266 If relroot is not empty, this function expects every path in modified,
f07047a506d1 patch.trydiff: add support for stripping a relative root
Siddharth Agarwal <sid0@fb.com>
parents: 24390
diff changeset
2267 added, removed and copy to start with it.'''
12167
d2c5b0927c28 diff: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12144
diff changeset
2268
17946
1e13b1184292 diff: move index header generation to patch
Guillermo Pérez <bisho@fb.com>
parents: 17945
diff changeset
2269 def gitindex(text):
1e13b1184292 diff: move index header generation to patch
Guillermo Pérez <bisho@fb.com>
parents: 17945
diff changeset
2270 if not text:
19875
c172660eee01 patch: Fix nullid for binary git diffs (issue4054)
Johan Bjork <jbjoerk@gmail.com>
parents: 19513
diff changeset
2271 text = ""
17946
1e13b1184292 diff: move index header generation to patch
Guillermo Pérez <bisho@fb.com>
parents: 17945
diff changeset
2272 l = len(text)
1e13b1184292 diff: move index header generation to patch
Guillermo Pérez <bisho@fb.com>
parents: 17945
diff changeset
2273 s = util.sha1('blob %d\0' % l)
1e13b1184292 diff: move index header generation to patch
Guillermo Pérez <bisho@fb.com>
parents: 17945
diff changeset
2274 s.update(text)
1e13b1184292 diff: move index header generation to patch
Guillermo Pérez <bisho@fb.com>
parents: 17945
diff changeset
2275 return s.hexdigest()
1e13b1184292 diff: move index header generation to patch
Guillermo Pérez <bisho@fb.com>
parents: 17945
diff changeset
2276
23300
f8b5c3e77d4b patch.trydiff: add support for noprefix
Siddharth Agarwal <sid0@fb.com>
parents: 23297
diff changeset
2277 if opts.noprefix:
f8b5c3e77d4b patch.trydiff: add support for noprefix
Siddharth Agarwal <sid0@fb.com>
parents: 23297
diff changeset
2278 aprefix = bprefix = ''
f8b5c3e77d4b patch.trydiff: add support for noprefix
Siddharth Agarwal <sid0@fb.com>
parents: 23297
diff changeset
2279 else:
f8b5c3e77d4b patch.trydiff: add support for noprefix
Siddharth Agarwal <sid0@fb.com>
parents: 23297
diff changeset
2280 aprefix = 'a/'
f8b5c3e77d4b patch.trydiff: add support for noprefix
Siddharth Agarwal <sid0@fb.com>
parents: 23297
diff changeset
2281 bprefix = 'b/'
f8b5c3e77d4b patch.trydiff: add support for noprefix
Siddharth Agarwal <sid0@fb.com>
parents: 23297
diff changeset
2282
24021
f51a822dcf3b trydiff: remove unused argument to diffline()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24020
diff changeset
2283 def diffline(f, revs):
24024
a5c7e86a81c1 trydiff: move check for quietness out of diffline()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24023
diff changeset
2284 revinfo = ' '.join(["-r %s" % rev for rev in revs])
24025
bbb011f4eb32 trydiff: join elements in 'header' list by '\n'
Martin von Zweigbergk <martinvonz@google.com>
parents: 24024
diff changeset
2285 return 'diff %s %s' % (revinfo, f)
17941
9a6e4d5d7ea8 diff: move diffline to patch module
Guillermo Pérez <bisho@fb.com>
parents: 17940
diff changeset
2286
7090
7b5c063b0b94 diff: pass contexts to status
Matt Mackall <mpm@selenic.com>
parents: 6953
diff changeset
2287 date1 = util.datestr(ctx1.date())
23662
bc7d90c966d2 trydiff: extract 'date2' variable like existing 'date1'
Martin von Zweigbergk <martinvonz@google.com>
parents: 23661
diff changeset
2288 date2 = util.datestr(ctx2.date())
3967
dccb83241dd0 patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3963
diff changeset
2289
10189
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10151
diff changeset
2290 gitmode = {'l': '120000', 'x': '100755', '': '100644'}
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2868
diff changeset
2291
24416
f07047a506d1 patch.trydiff: add support for stripping a relative root
Siddharth Agarwal <sid0@fb.com>
parents: 24390
diff changeset
2292 if relroot != '' and (repo.ui.configbool('devel', 'all')
f07047a506d1 patch.trydiff: add support for stripping a relative root
Siddharth Agarwal <sid0@fb.com>
parents: 24390
diff changeset
2293 or repo.ui.configbool('devel', 'check-relroot')):
f07047a506d1 patch.trydiff: add support for stripping a relative root
Siddharth Agarwal <sid0@fb.com>
parents: 24390
diff changeset
2294 for f in modified + added + removed + copy.keys() + copy.values():
f07047a506d1 patch.trydiff: add support for stripping a relative root
Siddharth Agarwal <sid0@fb.com>
parents: 24390
diff changeset
2295 if f is not None and not f.startswith(relroot):
f07047a506d1 patch.trydiff: add support for stripping a relative root
Siddharth Agarwal <sid0@fb.com>
parents: 24390
diff changeset
2296 raise AssertionError(
f07047a506d1 patch.trydiff: add support for stripping a relative root
Siddharth Agarwal <sid0@fb.com>
parents: 24390
diff changeset
2297 "file %s doesn't start with relroot %s" % (f, relroot))
f07047a506d1 patch.trydiff: add support for stripping a relative root
Siddharth Agarwal <sid0@fb.com>
parents: 24390
diff changeset
2298
24106
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
2299 for f1, f2, copyop in _filepairs(
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
2300 ctx1, modified, added, removed, copy, opts):
24105
0f8baebcdbea trydiff: read file data in only one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 24104
diff changeset
2301 content1 = None
0f8baebcdbea trydiff: read file data in only one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 24104
diff changeset
2302 content2 = None
24103
c666c85f71ba trydiff: read flags in one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 24102
diff changeset
2303 flag1 = None
c666c85f71ba trydiff: read flags in one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 24102
diff changeset
2304 flag2 = None
24107
32e8d94b9473 trydiff: transpose 'if opts.git or losedatafn' with 'if f[12]'
Martin von Zweigbergk <martinvonz@google.com>
parents: 24106
diff changeset
2305 if f1:
32e8d94b9473 trydiff: transpose 'if opts.git or losedatafn' with 'if f[12]'
Martin von Zweigbergk <martinvonz@google.com>
parents: 24106
diff changeset
2306 content1 = getfilectx(f1, ctx1).data()
32e8d94b9473 trydiff: transpose 'if opts.git or losedatafn' with 'if f[12]'
Martin von Zweigbergk <martinvonz@google.com>
parents: 24106
diff changeset
2307 if opts.git or losedatafn:
32e8d94b9473 trydiff: transpose 'if opts.git or losedatafn' with 'if f[12]'
Martin von Zweigbergk <martinvonz@google.com>
parents: 24106
diff changeset
2308 flag1 = ctx1.flags(f1)
32e8d94b9473 trydiff: transpose 'if opts.git or losedatafn' with 'if f[12]'
Martin von Zweigbergk <martinvonz@google.com>
parents: 24106
diff changeset
2309 if f2:
32e8d94b9473 trydiff: transpose 'if opts.git or losedatafn' with 'if f[12]'
Martin von Zweigbergk <martinvonz@google.com>
parents: 24106
diff changeset
2310 content2 = getfilectx(f2, ctx2).data()
32e8d94b9473 trydiff: transpose 'if opts.git or losedatafn' with 'if f[12]'
Martin von Zweigbergk <martinvonz@google.com>
parents: 24106
diff changeset
2311 if opts.git or losedatafn:
32e8d94b9473 trydiff: transpose 'if opts.git or losedatafn' with 'if f[12]'
Martin von Zweigbergk <martinvonz@google.com>
parents: 24106
diff changeset
2312 flag2 = ctx2.flags(f2)
24102
00280a2b8b9a trydiff: break 'if opts.git or losedatafn' into two
Martin von Zweigbergk <martinvonz@google.com>
parents: 24101
diff changeset
2313 binary = False
00280a2b8b9a trydiff: break 'if opts.git or losedatafn' into two
Martin von Zweigbergk <martinvonz@google.com>
parents: 24101
diff changeset
2314 if opts.git or losedatafn:
24058
d1fcff9400c9 trydiff: call util.binary in only one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 24057
diff changeset
2315 binary = util.binary(content1) or util.binary(content2)
24057
696d0fd77d94 trydiff: collect all lossiness checks in one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 24056
diff changeset
2316
696d0fd77d94 trydiff: collect all lossiness checks in one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 24056
diff changeset
2317 if losedatafn and not opts.git:
696d0fd77d94 trydiff: collect all lossiness checks in one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 24056
diff changeset
2318 if (binary or
696d0fd77d94 trydiff: collect all lossiness checks in one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 24056
diff changeset
2319 # copy/rename
24106
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
2320 f2 in copy or
24057
696d0fd77d94 trydiff: collect all lossiness checks in one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 24056
diff changeset
2321 # empty file creation
24101
1ea90d140ee3 trydiff: make filenames None when they don't exist
Martin von Zweigbergk <martinvonz@google.com>
parents: 24058
diff changeset
2322 (not f1 and not content2) or
24057
696d0fd77d94 trydiff: collect all lossiness checks in one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 24056
diff changeset
2323 # empty file deletion
24101
1ea90d140ee3 trydiff: make filenames None when they don't exist
Martin von Zweigbergk <martinvonz@google.com>
parents: 24058
diff changeset
2324 (not content1 and not f2) or
24057
696d0fd77d94 trydiff: collect all lossiness checks in one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 24056
diff changeset
2325 # create with flags
24101
1ea90d140ee3 trydiff: make filenames None when they don't exist
Martin von Zweigbergk <martinvonz@google.com>
parents: 24058
diff changeset
2326 (not f1 and flag2) or
24057
696d0fd77d94 trydiff: collect all lossiness checks in one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 24056
diff changeset
2327 # change flags
24101
1ea90d140ee3 trydiff: make filenames None when they don't exist
Martin von Zweigbergk <martinvonz@google.com>
parents: 24058
diff changeset
2328 (f1 and f2 and flag1 != flag2)):
24106
9cf9432a505b trydiff: extract function that generates filename pairs
Martin von Zweigbergk <martinvonz@google.com>
parents: 24105
diff changeset
2329 losedatafn(f2 or f1)
10189
e451e599fbcf patch: support diff data loss detection and upgrade
Patrick Mezard <pmezard@gmail.com>
parents: 10151
diff changeset
2330
24416
f07047a506d1 patch.trydiff: add support for stripping a relative root
Siddharth Agarwal <sid0@fb.com>
parents: 24390
diff changeset
2331 path1 = f1 or f2
f07047a506d1 patch.trydiff: add support for stripping a relative root
Siddharth Agarwal <sid0@fb.com>
parents: 24390
diff changeset
2332 path2 = f2 or f1
f07047a506d1 patch.trydiff: add support for stripping a relative root
Siddharth Agarwal <sid0@fb.com>
parents: 24390
diff changeset
2333 path1 = posixpath.join(prefix, path1[len(relroot):])
f07047a506d1 patch.trydiff: add support for stripping a relative root
Siddharth Agarwal <sid0@fb.com>
parents: 24390
diff changeset
2334 path2 = posixpath.join(prefix, path2[len(relroot):])
23998
b65637247c69 trydiff: collect header-writing in one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 23997
diff changeset
2335 header = []
24022
da63f557d0dc trydiff: make 'revs' ignored if opts.git is set
Martin von Zweigbergk <martinvonz@google.com>
parents: 24021
diff changeset
2336 if opts.git:
24025
bbb011f4eb32 trydiff: join elements in 'header' list by '\n'
Martin von Zweigbergk <martinvonz@google.com>
parents: 24024
diff changeset
2337 header.append('diff --git %s%s %s%s' %
24020
cc81e6da0757 trydiff: move git-header code out of diffline function
Martin von Zweigbergk <martinvonz@google.com>
parents: 24005
diff changeset
2338 (aprefix, path1, bprefix, path2))
24101
1ea90d140ee3 trydiff: make filenames None when they don't exist
Martin von Zweigbergk <martinvonz@google.com>
parents: 24058
diff changeset
2339 if not f1: # added
24025
bbb011f4eb32 trydiff: join elements in 'header' list by '\n'
Martin von Zweigbergk <martinvonz@google.com>
parents: 24024
diff changeset
2340 header.append('new file mode %s' % gitmode[flag2])
24101
1ea90d140ee3 trydiff: make filenames None when they don't exist
Martin von Zweigbergk <martinvonz@google.com>
parents: 24058
diff changeset
2341 elif not f2: # removed
24025
bbb011f4eb32 trydiff: join elements in 'header' list by '\n'
Martin von Zweigbergk <martinvonz@google.com>
parents: 24024
diff changeset
2342 header.append('deleted file mode %s' % gitmode[flag1])
23998
b65637247c69 trydiff: collect header-writing in one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 23997
diff changeset
2343 else: # modified/copied/renamed
24000
82e3324c4df9 trydiff: inline sole addmodehdr() call
Martin von Zweigbergk <martinvonz@google.com>
parents: 23999
diff changeset
2344 mode1, mode2 = gitmode[flag1], gitmode[flag2]
82e3324c4df9 trydiff: inline sole addmodehdr() call
Martin von Zweigbergk <martinvonz@google.com>
parents: 23999
diff changeset
2345 if mode1 != mode2:
24025
bbb011f4eb32 trydiff: join elements in 'header' list by '\n'
Martin von Zweigbergk <martinvonz@google.com>
parents: 24024
diff changeset
2346 header.append('old mode %s' % mode1)
bbb011f4eb32 trydiff: join elements in 'header' list by '\n'
Martin von Zweigbergk <martinvonz@google.com>
parents: 24024
diff changeset
2347 header.append('new mode %s' % mode2)
24055
7f4e6b5fce03 trydiff: rename 'op' to make it more specific
Martin von Zweigbergk <martinvonz@google.com>
parents: 24025
diff changeset
2348 if copyop is not None:
7f4e6b5fce03 trydiff: rename 'op' to make it more specific
Martin von Zweigbergk <martinvonz@google.com>
parents: 24025
diff changeset
2349 header.append('%s from %s' % (copyop, path1))
7f4e6b5fce03 trydiff: rename 'op' to make it more specific
Martin von Zweigbergk <martinvonz@google.com>
parents: 24025
diff changeset
2350 header.append('%s to %s' % (copyop, path2))
24024
a5c7e86a81c1 trydiff: move check for quietness out of diffline()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24023
diff changeset
2351 elif revs and not repo.ui.quiet:
24022
da63f557d0dc trydiff: make 'revs' ignored if opts.git is set
Martin von Zweigbergk <martinvonz@google.com>
parents: 24021
diff changeset
2352 header.append(diffline(path1, revs))
23998
b65637247c69 trydiff: collect header-writing in one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 23997
diff changeset
2353
24056
ae453d166d51 trydiff: replace 'binarydiff' variable by 'binary' variable
Martin von Zweigbergk <martinvonz@google.com>
parents: 24055
diff changeset
2354 if binary and opts.git and not opts.nobinary:
23997
8b88870cbd1e trydiff: make variable names more consistent
Martin von Zweigbergk <martinvonz@google.com>
parents: 23996
diff changeset
2355 text = mdiff.b85diff(content1, content2)
24056
ae453d166d51 trydiff: replace 'binarydiff' variable by 'binary' variable
Martin von Zweigbergk <martinvonz@google.com>
parents: 24055
diff changeset
2356 if text:
24025
bbb011f4eb32 trydiff: join elements in 'header' list by '\n'
Martin von Zweigbergk <martinvonz@google.com>
parents: 24024
diff changeset
2357 header.append('index %s..%s' %
24005
2c166f6b5d10 trydiff: inline indexmeta()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24001
diff changeset
2358 (gitindex(content1), gitindex(content2)))
23753
e30c6aa6f2a2 trydiff: replace 'dodiff = False' by 'continue'
Martin von Zweigbergk <martinvonz@google.com>
parents: 23752
diff changeset
2359 else:
23997
8b88870cbd1e trydiff: make variable names more consistent
Martin von Zweigbergk <martinvonz@google.com>
parents: 23996
diff changeset
2360 text = mdiff.unidiff(content1, date1,
8b88870cbd1e trydiff: make variable names more consistent
Martin von Zweigbergk <martinvonz@google.com>
parents: 23996
diff changeset
2361 content2, date2,
23999
e02888efc5aa trydiff: join filename with prefix only once
Martin von Zweigbergk <martinvonz@google.com>
parents: 23998
diff changeset
2362 path1, path2, opts=opts)
23753
e30c6aa6f2a2 trydiff: replace 'dodiff = False' by 'continue'
Martin von Zweigbergk <martinvonz@google.com>
parents: 23752
diff changeset
2363 if header and (text or len(header) > 1):
24025
bbb011f4eb32 trydiff: join elements in 'header' list by '\n'
Martin von Zweigbergk <martinvonz@google.com>
parents: 24024
diff changeset
2364 yield '\n'.join(header) + '\n'
23753
e30c6aa6f2a2 trydiff: replace 'dodiff = False' by 'continue'
Martin von Zweigbergk <martinvonz@google.com>
parents: 23752
diff changeset
2365 if text:
e30c6aa6f2a2 trydiff: replace 'dodiff = False' by 'continue'
Martin von Zweigbergk <martinvonz@google.com>
parents: 23752
diff changeset
2366 yield text
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2868
diff changeset
2367
14401
7bb7be1c1385 patch: add diffstatsum helper
Matt Mackall <mpm@selenic.com>
parents: 14400
diff changeset
2368 def diffstatsum(stats):
14437
cbe13e6bdc34 patch: restore the previous output of 'diff --stat'
Steven Brown <StevenGBrown@gmail.com>
parents: 14435
diff changeset
2369 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
2370 for f, a, r, b in stats:
7bb7be1c1385 patch: add diffstatsum helper
Matt Mackall <mpm@selenic.com>
parents: 14400
diff changeset
2371 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
2372 maxtotal = max(maxtotal, a + r)
14401
7bb7be1c1385 patch: add diffstatsum helper
Matt Mackall <mpm@selenic.com>
parents: 14400
diff changeset
2373 addtotal += a
7bb7be1c1385 patch: add diffstatsum helper
Matt Mackall <mpm@selenic.com>
parents: 14400
diff changeset
2374 removetotal += r
7bb7be1c1385 patch: add diffstatsum helper
Matt Mackall <mpm@selenic.com>
parents: 14400
diff changeset
2375 binary = binary or b
7bb7be1c1385 patch: add diffstatsum helper
Matt Mackall <mpm@selenic.com>
parents: 14400
diff changeset
2376
14437
cbe13e6bdc34 patch: restore the previous output of 'diff --stat'
Steven Brown <StevenGBrown@gmail.com>
parents: 14435
diff changeset
2377 return maxfile, maxtotal, addtotal, removetotal, binary
14401
7bb7be1c1385 patch: add diffstatsum helper
Matt Mackall <mpm@selenic.com>
parents: 14400
diff changeset
2378
7547
4949729ee9ee python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7521
diff changeset
2379 def diffstatdata(lines):
13395
104c9ed93fc5 diffstat: fix parsing of filenames with spaces
Gastón Kleiman <gaston.kleiman@gmail.com>
parents: 13112
diff changeset
2380 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
2381
14400
cd1ca2556cac diffstatdata: no longer a generator
Matt Mackall <mpm@selenic.com>
parents: 14392
diff changeset
2382 results = []
15363
628a4a9e411d diffstat: be more picky when marking file as 'binary' (issue2816)
Patrick Mezard <pmezard@gmail.com>
parents: 15201
diff changeset
2383 filename, adds, removes, isbinary = None, 0, 0, False
14400
cd1ca2556cac diffstatdata: no longer a generator
Matt Mackall <mpm@selenic.com>
parents: 14392
diff changeset
2384
cd1ca2556cac diffstatdata: no longer a generator
Matt Mackall <mpm@selenic.com>
parents: 14392
diff changeset
2385 def addresult():
cd1ca2556cac diffstatdata: no longer a generator
Matt Mackall <mpm@selenic.com>
parents: 14392
diff changeset
2386 if filename:
cd1ca2556cac diffstatdata: no longer a generator
Matt Mackall <mpm@selenic.com>
parents: 14392
diff changeset
2387 results.append((filename, adds, removes, isbinary))
cd1ca2556cac diffstatdata: no longer a generator
Matt Mackall <mpm@selenic.com>
parents: 14392
diff changeset
2388
7547
4949729ee9ee python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7521
diff changeset
2389 for line in lines:
4949729ee9ee python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7521
diff changeset
2390 if line.startswith('diff'):
14400
cd1ca2556cac diffstatdata: no longer a generator
Matt Mackall <mpm@selenic.com>
parents: 14392
diff changeset
2391 addresult()
7547
4949729ee9ee python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7521
diff changeset
2392 # 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
2393 adds, removes, isbinary = 0, 0, False
18830
6b827d84d286 patch: match 'diff --git a/' instead of 'diff --git'
Sean Farley <sean.michael.farley@gmail.com>
parents: 18824
diff changeset
2394 if line.startswith('diff --git a/'):
20972
4e2fb0ad00a9 diff: use second filename for --stat reporting on git patches (issue4221)
Matt Mackall <mpm@selenic.com>
parents: 20869
diff changeset
2395 filename = gitre.search(line).group(2)
13395
104c9ed93fc5 diffstat: fix parsing of filenames with spaces
Gastón Kleiman <gaston.kleiman@gmail.com>
parents: 13112
diff changeset
2396 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
2397 # 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
2398 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
2399 elif line.startswith('+') and not line.startswith('+++ '):
7547
4949729ee9ee python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7521
diff changeset
2400 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
2401 elif line.startswith('-') and not line.startswith('--- '):
7547
4949729ee9ee python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7521
diff changeset
2402 removes += 1
15363
628a4a9e411d diffstat: be more picky when marking file as 'binary' (issue2816)
Patrick Mezard <pmezard@gmail.com>
parents: 15201
diff changeset
2403 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
2404 line.startswith('Binary file')):
628a4a9e411d diffstat: be more picky when marking file as 'binary' (issue2816)
Patrick Mezard <pmezard@gmail.com>
parents: 15201
diff changeset
2405 isbinary = True
14400
cd1ca2556cac diffstatdata: no longer a generator
Matt Mackall <mpm@selenic.com>
parents: 14392
diff changeset
2406 addresult()
cd1ca2556cac diffstatdata: no longer a generator
Matt Mackall <mpm@selenic.com>
parents: 14392
diff changeset
2407 return results
7547
4949729ee9ee python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7521
diff changeset
2408
9642
7d17794f08a9 diffstat: with --git, mark binary files with Bin
Brodie Rao <me+hg@dackz.net>
parents: 9639
diff changeset
2409 def diffstat(lines, width=80, git=False):
7547
4949729ee9ee python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7521
diff changeset
2410 output = []
14402
f03f08240c32 patch: use diffstatsum in diffstat
Matt Mackall <mpm@selenic.com>
parents: 14401
diff changeset
2411 stats = diffstatdata(lines)
14437
cbe13e6bdc34 patch: restore the previous output of 'diff --stat'
Steven Brown <StevenGBrown@gmail.com>
parents: 14435
diff changeset
2412 maxname, maxtotal, totaladds, totalremoves, hasbinary = diffstatsum(stats)
7547
4949729ee9ee python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7521
diff changeset
2413
4949729ee9ee python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7521
diff changeset
2414 countwidth = len(str(maxtotal))
9642
7d17794f08a9 diffstat: with --git, mark binary files with Bin
Brodie Rao <me+hg@dackz.net>
parents: 9639
diff changeset
2415 if hasbinary and countwidth < 3:
7d17794f08a9 diffstat: with --git, mark binary files with Bin
Brodie Rao <me+hg@dackz.net>
parents: 9639
diff changeset
2416 countwidth = 3
9330
be2a13153372 diffstat: scale adds/removes proportionally to graph width
Brodie Rao <me+hg@dackz.net>
parents: 9328
diff changeset
2417 graphwidth = width - countwidth - maxname - 6
7547
4949729ee9ee python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7521
diff changeset
2418 if graphwidth < 10:
4949729ee9ee python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7521
diff changeset
2419 graphwidth = 10
4949729ee9ee python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7521
diff changeset
2420
9330
be2a13153372 diffstat: scale adds/removes proportionally to graph width
Brodie Rao <me+hg@dackz.net>
parents: 9328
diff changeset
2421 def scale(i):
be2a13153372 diffstat: scale adds/removes proportionally to graph width
Brodie Rao <me+hg@dackz.net>
parents: 9328
diff changeset
2422 if maxtotal <= graphwidth:
be2a13153372 diffstat: scale adds/removes proportionally to graph width
Brodie Rao <me+hg@dackz.net>
parents: 9328
diff changeset
2423 return i
be2a13153372 diffstat: scale adds/removes proportionally to graph width
Brodie Rao <me+hg@dackz.net>
parents: 9328
diff changeset
2424 # 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
2425 # 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
2426 # 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
2427 return max(i * graphwidth // maxtotal, int(bool(i)))
7547
4949729ee9ee python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7521
diff changeset
2428
14402
f03f08240c32 patch: use diffstatsum in diffstat
Matt Mackall <mpm@selenic.com>
parents: 14401
diff changeset
2429 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
2430 if isbinary:
9642
7d17794f08a9 diffstat: with --git, mark binary files with Bin
Brodie Rao <me+hg@dackz.net>
parents: 9639
diff changeset
2431 count = 'Bin'
7d17794f08a9 diffstat: with --git, mark binary files with Bin
Brodie Rao <me+hg@dackz.net>
parents: 9639
diff changeset
2432 else:
7d17794f08a9 diffstat: with --git, mark binary files with Bin
Brodie Rao <me+hg@dackz.net>
parents: 9639
diff changeset
2433 count = adds + removes
9330
be2a13153372 diffstat: scale adds/removes proportionally to graph width
Brodie Rao <me+hg@dackz.net>
parents: 9328
diff changeset
2434 pluses = '+' * scale(adds)
be2a13153372 diffstat: scale adds/removes proportionally to graph width
Brodie Rao <me+hg@dackz.net>
parents: 9328
diff changeset
2435 minuses = '-' * scale(removes)
11611
4f5a6df2af92 i18n: use encoding.colwidth() for correct column width
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 11377
diff changeset
2436 output.append(' %s%s | %*s %s%s\n' %
14402
f03f08240c32 patch: use diffstatsum in diffstat
Matt Mackall <mpm@selenic.com>
parents: 14401
diff changeset
2437 (filename, ' ' * (maxname - encoding.colwidth(filename)),
f03f08240c32 patch: use diffstatsum in diffstat
Matt Mackall <mpm@selenic.com>
parents: 14401
diff changeset
2438 countwidth, count, pluses, minuses))
7547
4949729ee9ee python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7521
diff changeset
2439
4949729ee9ee python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7521
diff changeset
2440 if stats:
16683
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16662
diff changeset
2441 output.append(_(' %d files changed, %d insertions(+), '
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16662
diff changeset
2442 '%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
2443 % (len(stats), totaladds, totalremoves))
7547
4949729ee9ee python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7521
diff changeset
2444
4949729ee9ee python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7521
diff changeset
2445 return ''.join(output)
10818
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
2446
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
2447 def diffstatui(*args, **kw):
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
2448 '''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
2449 ui.write()
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
2450 '''
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
2451
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
2452 for line in diffstat(*args, **kw).splitlines():
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
2453 if line and line[-1] in '+-':
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
2454 name, graph = line.rsplit(' ', 1)
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
2455 yield (name + ' ', '')
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
2456 m = re.search(r'\++', graph)
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
2457 if m:
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
2458 yield (m.group(0), 'diffstat.inserted')
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
2459 m = re.search(r'-+', graph)
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
2460 if m:
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
2461 yield (m.group(0), 'diffstat.deleted')
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
2462 else:
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
2463 yield (line, '')
d14d45fae927 diff: make use of output labeling
Brodie Rao <brodie@bitheap.org>
parents: 10751
diff changeset
2464 yield ('\n', '')