##// END OF EJS Templates
patch: implement patch.eol=auto mode...
Martin Geisler -
r10102:1720d70c default
parent child Browse files
Show More
@@ -648,7 +648,10 b' command or with Mercurial Queues extensi'
648 When set to 'strict' patch content and patched files end of lines
648 When set to 'strict' patch content and patched files end of lines
649 are preserved. When set to ``lf`` or ``crlf``, both files end of lines
649 are preserved. When set to ``lf`` or ``crlf``, both files end of lines
650 are ignored when patching and the result line endings are
650 are ignored when patching and the result line endings are
651 normalized to either LF (Unix) or CRLF (Windows).
651 normalized to either LF (Unix) or CRLF (Windows). When set to
652 ``auto``, end of lines are again ignored while patching but line
653 endings in patched files are normalized to their original setting
654 on a per-file basis.
652 Default: strict.
655 Default: strict.
653
656
654
657
@@ -239,6 +239,7 b' class linereader(object):'
239 self.fp = fp
239 self.fp = fp
240 self.buf = []
240 self.buf = []
241 self.textmode = textmode
241 self.textmode = textmode
242 self.eol = None
242
243
243 def push(self, line):
244 def push(self, line):
244 if line is not None:
245 if line is not None:
@@ -250,6 +251,11 b' class linereader(object):'
250 del self.buf[0]
251 del self.buf[0]
251 return l
252 return l
252 l = self.fp.readline()
253 l = self.fp.readline()
254 if not self.eol:
255 if l.endswith('\r\n'):
256 self.eol = '\r\n'
257 elif l.endswith('\n'):
258 self.eol = '\n'
253 if self.textmode and l.endswith('\r\n'):
259 if self.textmode and l.endswith('\r\n'):
254 l = l[:-2] + '\n'
260 l = l[:-2] + '\n'
255 return l
261 return l
@@ -264,13 +270,13 b' class linereader(object):'
264 # @@ -start,len +start,len @@ or @@ -start +start @@ if len is 1
270 # @@ -start,len +start,len @@ or @@ -start +start @@ if len is 1
265 unidesc = re.compile('@@ -(\d+)(,(\d+))? \+(\d+)(,(\d+))? @@')
271 unidesc = re.compile('@@ -(\d+)(,(\d+))? \+(\d+)(,(\d+))? @@')
266 contextdesc = re.compile('(---|\*\*\*) (\d+)(,(\d+))? (---|\*\*\*)')
272 contextdesc = re.compile('(---|\*\*\*) (\d+)(,(\d+))? (---|\*\*\*)')
267 eolmodes = ['strict', 'crlf', 'lf']
273 eolmodes = ['strict', 'crlf', 'lf', 'auto']
268
274
269 class patchfile(object):
275 class patchfile(object):
270 def __init__(self, ui, fname, opener, missing=False, eolmode='strict'):
276 def __init__(self, ui, fname, opener, missing=False, eolmode='strict'):
271 self.fname = fname
277 self.fname = fname
272 self.eolmode = eolmode
278 self.eolmode = eolmode
273 self.eol = {'strict': None, 'crlf': '\r\n', 'lf': '\n'}[eolmode]
279 self.eol = None
274 self.opener = opener
280 self.opener = opener
275 self.ui = ui
281 self.ui = ui
276 self.lines = []
282 self.lines = []
@@ -298,7 +304,10 b' class patchfile(object):'
298 return [os.readlink(fname)]
304 return [os.readlink(fname)]
299 fp = self.opener(fname, 'r')
305 fp = self.opener(fname, 'r')
300 try:
306 try:
301 return list(linereader(fp, self.eolmode != 'strict'))
307 lr = linereader(fp, self.eolmode != 'strict')
308 lines = list(lr)
309 self.eol = lr.eol
310 return lines
302 finally:
311 finally:
303 fp.close()
312 fp.close()
304
313
@@ -312,10 +321,17 b' class patchfile(object):'
312 else:
321 else:
313 fp = self.opener(fname, 'w')
322 fp = self.opener(fname, 'w')
314 try:
323 try:
315 if self.eol and self.eol != '\n':
324 if self.eolmode == 'auto' and self.eol:
325 eol = self.eol
326 elif self.eolmode == 'crlf':
327 eol = '\r\n'
328 else:
329 eol = '\n'
330
331 if self.eolmode != 'strict' and eol != '\n':
316 for l in lines:
332 for l in lines:
317 if l and l[-1] == '\n':
333 if l and l[-1] == '\n':
318 l = l[:-1] + self.eol
334 l = l[:-1] + eol
319 fp.write(l)
335 fp.write(l)
320 else:
336 else:
321 fp.writelines(lines)
337 fp.writelines(lines)
@@ -28,19 +28,35 b" echo '\\.diff' > .hgignore"
28 python -c 'file("a", "wb").write("a\nbbb\ncc\n\nd\ne")'
28 python -c 'file("a", "wb").write("a\nbbb\ncc\n\nd\ne")'
29 hg ci -Am adda
29 hg ci -Am adda
30 python ../makepatch.py
30 python ../makepatch.py
31
31 echo % invalid eol
32 echo % invalid eol
32 hg --config patch.eol='LFCR' import eol.diff
33 hg --config patch.eol='LFCR' import eol.diff
33 hg revert -a
34 hg revert -a
35
34 echo % force LF
36 echo % force LF
35 hg --traceback --config patch.eol='LF' import eol.diff
37 hg --traceback --config patch.eol='LF' import eol.diff
36 python -c 'print repr(file("a","rb").read())'
38 python -c 'print repr(file("a","rb").read())'
37 hg st
39 hg st
40
38 echo % force CRLF
41 echo % force CRLF
39 hg up -C 0
42 hg up -C 0
40 hg --traceback --config patch.eol='CRLF' import eol.diff
43 hg --traceback --config patch.eol='CRLF' import eol.diff
41 python -c 'print repr(file("a","rb").read())'
44 python -c 'print repr(file("a","rb").read())'
42 hg st
45 hg st
43
46
47 echo % auto EOL on LF file
48 hg up -C 0
49 hg --traceback --config patch.eol='auto' import eol.diff
50 python -c 'print repr(file("a","rb").read())'
51 hg st
52
53 echo % auto EOL on CRLF file
54 python -c 'file("a", "wb").write("a\r\nbbb\r\ncc\r\n\r\nd\r\ne")'
55 hg commit -m 'switch EOLs in a'
56 hg --traceback --config patch.eol='auto' import eol.diff
57 python -c 'print repr(file("a","rb").read())'
58 hg st
59
44 # Test --eol and binary patches
60 # Test --eol and binary patches
45 python -c 'file("b", "wb").write("a\x00\nb")'
61 python -c 'file("b", "wb").write("a\x00\nb")'
46 hg ci -Am addb
62 hg ci -Am addb
@@ -10,6 +10,13 b' applying eol.diff'
10 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
10 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
11 applying eol.diff
11 applying eol.diff
12 'a\r\nyyyy\r\ncc\r\n\r\nd\r\ne'
12 'a\r\nyyyy\r\ncc\r\n\r\nd\r\ne'
13 % auto EOL on LF file
14 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
15 applying eol.diff
16 'a\nyyyy\ncc\n\nd\ne'
17 % auto EOL on CRLF file
18 applying eol.diff
19 'a\r\nyyyy\r\ncc\r\n\r\nd\r\ne'
13 adding b
20 adding b
14 % binary patch with --eol
21 % binary patch with --eol
15 applying bin.diff
22 applying bin.diff
General Comments 0
You need to be logged in to leave comments. Login now