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 |
|
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' |
|
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