# HG changeset patch # User Patrick Mezard # Date 2009-12-23 18:31:48 # Node ID ea7c392f2b08f5e4758ed0247c2d39f191b563ad # Parent d8214e944b84a1a8b2e3fc0fe9d2c97963c096a2 patch: drop eol normalization fast-path for 'lf' and 'crlf' With eolmode set to 'lf' or 'crlf' we avoided the hunk duplication and normalization by reading the input patch in text mode. Dropping this optimization simplifies code expectations for a small overhead. The change in test-mq-eol comes from a tolerance to CRLF instead of LF for last lines without newlines being broken by this revision. This tolerance was only partially supported and will be added again in a better way. diff --git a/mercurial/patch.py b/mercurial/patch.py --- a/mercurial/patch.py +++ b/mercurial/patch.py @@ -434,12 +434,11 @@ class patchfile(object): return 0 horig = h - if self.eolmode == 'auto' and self.eol: - # If eolmode == 'auto' and target file exists and has line - # endings we have to normalize input data before patching. - # Otherwise, patchfile operates in 'strict' mode. If - # eolmode is set to 'crlf' or 'lf', input hunk is already - # normalized to avoid data copy. + if (self.eolmode in ('crlf', 'lf') + or self.eolmode == 'auto' and self.eol): + # If new eols are going to be normalized, then normalize + # hunk data before patching. Otherwise, preserve input + # line-endings. h = h.getnormalized() # fast case first, no offsets, no fuzz @@ -870,15 +869,13 @@ def scangitpatch(lr, firstline): fp.seek(pos) return dopatch, gitpatches -def iterhunks(ui, fp, sourcefile=None, textmode=False): +def iterhunks(ui, fp, sourcefile=None): """Read a patch and yield the following events: - ("file", afile, bfile, firsthunk): select a new target file. - ("hunk", hunk): a new hunk is ready to be applied, follows a "file" event. - ("git", gitchanges): current diff is in git format, gitchanges maps filenames to gitpatch records. Unique event. - - If textmode is True, input line-endings are normalized to LF. """ changed = {} current_hunk = None @@ -892,7 +889,7 @@ def iterhunks(ui, fp, sourcefile=None, t # our states BFILE = 1 context = None - lr = linereader(fp, textmode) + lr = linereader(fp) dopatch = True # gitworkdone is True if a git operation (copy, rename, ...) was # performed already for the current file. Useful when the file @@ -1009,10 +1006,6 @@ def applydiff(ui, fp, changed, strip=1, current_file = None gitpatches = None opener = util.opener(os.getcwd()) - # In 'auto' mode, we must preserve original eols if target file - # eols are undefined. Otherwise, hunk data will be normalized - # later. - textmode = eolmode not in ('strict', 'auto') def closefile(): if not current_file: @@ -1020,7 +1013,7 @@ def applydiff(ui, fp, changed, strip=1, current_file.close() return len(current_file.rej) - for state, values in iterhunks(ui, fp, sourcefile, textmode): + for state, values in iterhunks(ui, fp, sourcefile): if state == 'hunk': if not current_file: continue diff --git a/tests/test-mq-eol b/tests/test-mq-eol --- a/tests/test-mq-eol +++ b/tests/test-mq-eol @@ -20,7 +20,7 @@ w(' c\r\n') w(' d\n') w('-e\n') w('\ No newline at end of file\n') -w('+z\r\n') +w('+z\n') w('\ No newline at end of file\r\n') EOF