patch: propagate eolmode down to patchfile
authorMartin Geisler <mg@lazybytes.net>
Sun, 20 Dec 2009 17:18:02 +0100
changeset 10101 155fe35534d3
parent 10100 be442c7d84b4
child 10102 1720d70cd6d4
patch: propagate eolmode down to patchfile The old code mapped the value of eolmode ('strict', 'crlf' or 'lf') to eol (None, '\r\n' or '\n') at the entry point in internalpatch. The value of eol was then used directly as the desired EOL in patchfile. We now delay the mapping and let patchfile do it instead. This allows for more complicated behavior where it does not make sense to map eolmode directly to the target EOLs.
mercurial/patch.py
--- a/mercurial/patch.py	Sat Dec 19 22:56:01 2009 -0800
+++ b/mercurial/patch.py	Sun Dec 20 17:18:02 2009 +0100
@@ -264,11 +264,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']
 
 class patchfile(object):
-    def __init__(self, ui, fname, opener, missing=False, eol=None):
+    def __init__(self, ui, fname, opener, missing=False, eolmode='strict'):
         self.fname = fname
-        self.eol = eol
+        self.eolmode = eolmode
+        self.eol = {'strict': None, 'crlf': '\r\n', 'lf': '\n'}[eolmode]
         self.opener = opener
         self.ui = ui
         self.lines = []
@@ -296,7 +298,7 @@
             return [os.readlink(fname)]
         fp = self.opener(fname, 'r')
         try:
-            return list(linereader(fp, self.eol is not None))
+            return list(linereader(fp, self.eolmode != 'strict'))
         finally:
             fp.close()
 
@@ -939,7 +941,7 @@
     if hunknum == 0 and dopatch and not gitworkdone:
         raise NoHunks
 
-def applydiff(ui, fp, changed, strip=1, sourcefile=None, eol=None):
+def applydiff(ui, fp, changed, strip=1, sourcefile=None, eolmode='strict'):
     """
     Reads a patch from fp and tries to apply it.
 
@@ -947,16 +949,16 @@
     by the patch. Returns 0 for a clean patch, -1 if any rejects were
     found and 1 if there was any fuzz.
 
-    If 'eol' is None, the patch content and patched file are read in
-    binary mode. Otherwise, line endings are ignored when patching then
-    normalized to 'eol' (usually '\n' or \r\n').
+    If 'eolmode' is 'strict', the patch content and patched file are
+    read in binary mode. Otherwise, line endings are ignored when
+    patching then normalized according to 'eolmode'.
     """
     rejects = 0
     err = 0
     current_file = None
     gitpatches = None
     opener = util.opener(os.getcwd())
-    textmode = eol is not None
+    textmode = eolmode != 'strict'
 
     def closefile():
         if not current_file:
@@ -979,11 +981,11 @@
             afile, bfile, first_hunk = values
             try:
                 if sourcefile:
-                    current_file = patchfile(ui, sourcefile, opener, eol=eol)
+                    current_file = patchfile(ui, sourcefile, opener, eolmode=eolmode)
                 else:
                     current_file, missing = selectfile(afile, bfile, first_hunk,
                                             strip)
-                    current_file = patchfile(ui, current_file, opener, missing, eol)
+                    current_file = patchfile(ui, current_file, opener, missing, eolmode)
             except PatchError, err:
                 ui.warn(str(err) + '\n')
                 current_file, current_hunk = None, None
@@ -1104,10 +1106,9 @@
         files = {}
     if eolmode is None:
         eolmode = ui.config('patch', 'eol', 'strict')
-    try:
-        eol = {'strict': None, 'crlf': '\r\n', 'lf': '\n'}[eolmode.lower()]
-    except KeyError:
+    if eolmode.lower() not in eolmodes:
         raise util.Abort(_('Unsupported line endings type: %s') % eolmode)
+    eolmode = eolmode.lower()
 
     try:
         fp = open(patchobj, 'rb')
@@ -1117,7 +1118,7 @@
         curdir = os.getcwd()
         os.chdir(cwd)
     try:
-        ret = applydiff(ui, fp, files, strip=strip, eol=eol)
+        ret = applydiff(ui, fp, files, strip=strip, eolmode=eolmode)
     finally:
         if cwd:
             os.chdir(curdir)