Mercurial > hg-stable
changeset 10102:1720d70cd6d4
patch: implement patch.eol=auto mode
EOLs in patched files are restored to their original value after
patching. We use the first EOL found in the file, files with
inconsistent EOLs will thus be normalized during this process.
author | Martin Geisler <mg@lazybytes.net> |
---|---|
date | Sun, 20 Dec 2009 17:18:04 +0100 |
parents | 155fe35534d3 |
children | e533fc8a058b |
files | doc/hgrc.5.txt mercurial/patch.py tests/test-import-eol tests/test-import-eol.out |
diffstat | 4 files changed, 48 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/doc/hgrc.5.txt Sun Dec 20 17:18:02 2009 +0100 +++ b/doc/hgrc.5.txt Sun Dec 20 17:18:04 2009 +0100 @@ -648,7 +648,10 @@ When set to 'strict' patch content and patched files end of lines are preserved. When set to ``lf`` or ``crlf``, both files end of lines are ignored when patching and the result line endings are - normalized to either LF (Unix) or CRLF (Windows). + normalized to either LF (Unix) or CRLF (Windows). When set to + ``auto``, end of lines are again ignored while patching but line + endings in patched files are normalized to their original setting + on a per-file basis. Default: strict.
--- a/mercurial/patch.py Sun Dec 20 17:18:02 2009 +0100 +++ b/mercurial/patch.py Sun Dec 20 17:18:04 2009 +0100 @@ -239,6 +239,7 @@ self.fp = fp self.buf = [] self.textmode = textmode + self.eol = None def push(self, line): if line is not None: @@ -250,6 +251,11 @@ del self.buf[0] return l l = self.fp.readline() + if not self.eol: + if l.endswith('\r\n'): + self.eol = '\r\n' + elif l.endswith('\n'): + self.eol = '\n' if self.textmode and l.endswith('\r\n'): l = l[:-2] + '\n' return l @@ -264,13 +270,13 @@ # @@ -start,len +start,len @@ or @@ -start +start @@ if len is 1 unidesc = re.compile('@@ -(\d+)(,(\d+))? \+(\d+)(,(\d+))? @@') contextdesc = re.compile('(---|\*\*\*) (\d+)(,(\d+))? (---|\*\*\*)') -eolmodes = ['strict', 'crlf', 'lf'] +eolmodes = ['strict', 'crlf', 'lf', 'auto'] class patchfile(object): def __init__(self, ui, fname, opener, missing=False, eolmode='strict'): self.fname = fname self.eolmode = eolmode - self.eol = {'strict': None, 'crlf': '\r\n', 'lf': '\n'}[eolmode] + self.eol = None self.opener = opener self.ui = ui self.lines = [] @@ -298,7 +304,10 @@ return [os.readlink(fname)] fp = self.opener(fname, 'r') try: - return list(linereader(fp, self.eolmode != 'strict')) + lr = linereader(fp, self.eolmode != 'strict') + lines = list(lr) + self.eol = lr.eol + return lines finally: fp.close() @@ -312,10 +321,17 @@ else: fp = self.opener(fname, 'w') try: - if self.eol and self.eol != '\n': + if self.eolmode == 'auto' and self.eol: + eol = self.eol + elif self.eolmode == 'crlf': + eol = '\r\n' + else: + eol = '\n' + + if self.eolmode != 'strict' and eol != '\n': for l in lines: if l and l[-1] == '\n': - l = l[:-1] + self.eol + l = l[:-1] + eol fp.write(l) else: fp.writelines(lines)
--- a/tests/test-import-eol Sun Dec 20 17:18:02 2009 +0100 +++ b/tests/test-import-eol Sun Dec 20 17:18:04 2009 +0100 @@ -28,19 +28,35 @@ python -c 'file("a", "wb").write("a\nbbb\ncc\n\nd\ne")' hg ci -Am adda python ../makepatch.py + echo % invalid eol hg --config patch.eol='LFCR' import eol.diff hg revert -a + echo % force LF hg --traceback --config patch.eol='LF' import eol.diff python -c 'print repr(file("a","rb").read())' hg st + echo % force CRLF hg up -C 0 hg --traceback --config patch.eol='CRLF' import eol.diff python -c 'print repr(file("a","rb").read())' hg st +echo % auto EOL on LF file +hg up -C 0 +hg --traceback --config patch.eol='auto' import eol.diff +python -c 'print repr(file("a","rb").read())' +hg st + +echo % auto EOL on CRLF file +python -c 'file("a", "wb").write("a\r\nbbb\r\ncc\r\n\r\nd\r\ne")' +hg commit -m 'switch EOLs in a' +hg --traceback --config patch.eol='auto' import eol.diff +python -c 'print repr(file("a","rb").read())' +hg st + # Test --eol and binary patches python -c 'file("b", "wb").write("a\x00\nb")' hg ci -Am addb
--- a/tests/test-import-eol.out Sun Dec 20 17:18:02 2009 +0100 +++ b/tests/test-import-eol.out Sun Dec 20 17:18:04 2009 +0100 @@ -10,6 +10,13 @@ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved applying eol.diff 'a\r\nyyyy\r\ncc\r\n\r\nd\r\ne' +% auto EOL on LF file +1 files updated, 0 files merged, 0 files removed, 0 files unresolved +applying eol.diff +'a\nyyyy\ncc\n\nd\ne' +% auto EOL on CRLF file +applying eol.diff +'a\r\nyyyy\r\ncc\r\n\r\nd\r\ne' adding b % binary patch with --eol applying bin.diff