##// END OF EJS Templates
patch: fix eolmode=auto with new files...
Patrick Mezard -
r10127:d8214e94 default
parent child Browse files
Show More
@@ -646,12 +646,13 b' command or with Mercurial Queues extensi'
646
646
647 ``eol``
647 ``eol``
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
650 are ignored when patching and the result line endings are
650 lines are ignored when patching and the result line endings are
651 normalized to either LF (Unix) or CRLF (Windows). When set to
651 normalized to either LF (Unix) or CRLF (Windows). When set to
652 ``auto``, end of lines are again ignored while patching but line
652 ``auto``, end of lines are again ignored while patching but line
653 endings in patched files are normalized to their original setting
653 endings in patched files are normalized to their original setting
654 on a per-file basis.
654 on a per-file basis. If target file does not exist or has no end
655 of line, patch line endings are preserved.
655 Default: strict.
656 Default: strict.
656
657
657
658
@@ -321,14 +321,14 b' class patchfile(object):'
321 else:
321 else:
322 fp = self.opener(fname, 'w')
322 fp = self.opener(fname, 'w')
323 try:
323 try:
324 if self.eolmode == 'auto' and self.eol:
324 if self.eolmode == 'auto':
325 eol = self.eol
325 eol = self.eol
326 elif self.eolmode == 'crlf':
326 elif self.eolmode == 'crlf':
327 eol = '\r\n'
327 eol = '\r\n'
328 else:
328 else:
329 eol = '\n'
329 eol = '\n'
330
330
331 if self.eolmode != 'strict' and eol != '\n':
331 if self.eolmode != 'strict' and eol and eol != '\n':
332 for l in lines:
332 for l in lines:
333 if l and l[-1] == '\n':
333 if l and l[-1] == '\n':
334 l = l[:-1] + eol
334 l = l[:-1] + eol
@@ -433,6 +433,15 b' class patchfile(object):'
433 self.dirty = 1
433 self.dirty = 1
434 return 0
434 return 0
435
435
436 horig = h
437 if self.eolmode == 'auto' and self.eol:
438 # If eolmode == 'auto' and target file exists and has line
439 # endings we have to normalize input data before patching.
440 # Otherwise, patchfile operates in 'strict' mode. If
441 # eolmode is set to 'crlf' or 'lf', input hunk is already
442 # normalized to avoid data copy.
443 h = h.getnormalized()
444
436 # fast case first, no offsets, no fuzz
445 # fast case first, no offsets, no fuzz
437 old = h.old()
446 old = h.old()
438 # patch starts counting at 1 unless we are adding the file
447 # patch starts counting at 1 unless we are adding the file
@@ -488,7 +497,7 b' class patchfile(object):'
488 return fuzzlen
497 return fuzzlen
489 self.printfile(True)
498 self.printfile(True)
490 self.ui.warn(_("Hunk #%d FAILED at %d\n") % (h.number, orig_start))
499 self.ui.warn(_("Hunk #%d FAILED at %d\n") % (h.number, orig_start))
491 self.rej.append(h)
500 self.rej.append(horig)
492 return -1
501 return -1
493
502
494 class hunk(object):
503 class hunk(object):
@@ -500,6 +509,7 b' class hunk(object):'
500 self.b = []
509 self.b = []
501 self.starta = self.lena = None
510 self.starta = self.lena = None
502 self.startb = self.lenb = None
511 self.startb = self.lenb = None
512 if lr is not None:
503 if context:
513 if context:
504 self.read_context_hunk(lr)
514 self.read_context_hunk(lr)
505 else:
515 else:
@@ -507,6 +517,31 b' class hunk(object):'
507 self.create = create
517 self.create = create
508 self.remove = remove and not create
518 self.remove = remove and not create
509
519
520 def getnormalized(self):
521 """Return a copy with line endings normalized to LF."""
522
523 def normalize(lines):
524 nlines = []
525 for line in lines:
526 if line.endswith('\r\n'):
527 line = line[:-2] + '\n'
528 nlines.append(line)
529 return nlines
530
531 # Dummy object, it is rebuilt manually
532 nh = hunk(self.desc, self.number, None, None, False, False)
533 nh.number = self.number
534 nh.desc = self.desc
535 nh.a = normalize(self.a)
536 nh.b = normalize(self.b)
537 nh.starta = self.starta
538 nh.startb = self.startb
539 nh.lena = self.lena
540 nh.lenb = self.lenb
541 nh.create = self.create
542 nh.remove = self.remove
543 return nh
544
510 def read_unified_hunk(self, lr):
545 def read_unified_hunk(self, lr):
511 m = unidesc.match(self.desc)
546 m = unidesc.match(self.desc)
512 if not m:
547 if not m:
@@ -974,7 +1009,10 b' def applydiff(ui, fp, changed, strip=1, '
974 current_file = None
1009 current_file = None
975 gitpatches = None
1010 gitpatches = None
976 opener = util.opener(os.getcwd())
1011 opener = util.opener(os.getcwd())
977 textmode = eolmode != 'strict'
1012 # In 'auto' mode, we must preserve original eols if target file
1013 # eols are undefined. Otherwise, hunk data will be normalized
1014 # later.
1015 textmode = eolmode not in ('strict', 'auto')
978
1016
979 def closefile():
1017 def closefile():
980 if not current_file:
1018 if not current_file:
@@ -57,6 +57,21 b" hg --traceback --config patch.eol='auto'"
57 python -c 'print repr(file("a","rb").read())'
57 python -c 'print repr(file("a","rb").read())'
58 hg st
58 hg st
59
59
60 echo % auto EOL on new file or source without any EOL
61 python -c 'file("noeol", "wb").write("noeol")'
62 hg add noeol
63 hg commit -m 'add noeol'
64 python -c 'file("noeol", "wb").write("noeol\r\nnoeol\n")'
65 python -c 'file("neweol", "wb").write("neweol\nneweol\r\n")'
66 hg add neweol
67 hg diff --git > noeol.diff
68 hg revert --no-backup noeol neweol
69 rm neweol
70 hg --traceback --config patch.eol='auto' import -m noeol noeol.diff
71 python -c 'print repr(file("noeol","rb").read())'
72 python -c 'print repr(file("neweol","rb").read())'
73 hg st
74
60 # Test --eol and binary patches
75 # Test --eol and binary patches
61 python -c 'file("b", "wb").write("a\x00\nb")'
76 python -c 'file("b", "wb").write("a\x00\nb")'
62 hg ci -Am addb
77 hg ci -Am addb
@@ -17,6 +17,10 b' applying eol.diff'
17 % auto EOL on CRLF file
17 % auto EOL on CRLF file
18 applying eol.diff
18 applying eol.diff
19 'a\r\nyyyy\r\ncc\r\n\r\nd\r\ne'
19 'a\r\nyyyy\r\ncc\r\n\r\nd\r\ne'
20 % auto EOL on new file or source without any EOL
21 applying noeol.diff
22 'noeol\r\nnoeol\n'
23 'neweol\nneweol\r\n'
20 adding b
24 adding b
21 % binary patch with --eol
25 % binary patch with --eol
22 applying bin.diff
26 applying bin.diff
General Comments 0
You need to be logged in to leave comments. Login now