Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/patch.py @ 10101:155fe35534d3
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.
author | Martin Geisler <mg@lazybytes.net> |
---|---|
date | Sun, 20 Dec 2009 17:18:02 +0100 |
parents | 3f522d2fa633 |
children | 1720d70cd6d4 |
comparison
equal
deleted
inserted
replaced
10100:be442c7d84b4 | 10101:155fe35534d3 |
---|---|
262 yield l | 262 yield l |
263 | 263 |
264 # @@ -start,len +start,len @@ or @@ -start +start @@ if len is 1 | 264 # @@ -start,len +start,len @@ or @@ -start +start @@ if len is 1 |
265 unidesc = re.compile('@@ -(\d+)(,(\d+))? \+(\d+)(,(\d+))? @@') | 265 unidesc = re.compile('@@ -(\d+)(,(\d+))? \+(\d+)(,(\d+))? @@') |
266 contextdesc = re.compile('(---|\*\*\*) (\d+)(,(\d+))? (---|\*\*\*)') | 266 contextdesc = re.compile('(---|\*\*\*) (\d+)(,(\d+))? (---|\*\*\*)') |
267 eolmodes = ['strict', 'crlf', 'lf'] | |
267 | 268 |
268 class patchfile(object): | 269 class patchfile(object): |
269 def __init__(self, ui, fname, opener, missing=False, eol=None): | 270 def __init__(self, ui, fname, opener, missing=False, eolmode='strict'): |
270 self.fname = fname | 271 self.fname = fname |
271 self.eol = eol | 272 self.eolmode = eolmode |
273 self.eol = {'strict': None, 'crlf': '\r\n', 'lf': '\n'}[eolmode] | |
272 self.opener = opener | 274 self.opener = opener |
273 self.ui = ui | 275 self.ui = ui |
274 self.lines = [] | 276 self.lines = [] |
275 self.exists = False | 277 self.exists = False |
276 self.missing = missing | 278 self.missing = missing |
294 def readlines(self, fname): | 296 def readlines(self, fname): |
295 if os.path.islink(fname): | 297 if os.path.islink(fname): |
296 return [os.readlink(fname)] | 298 return [os.readlink(fname)] |
297 fp = self.opener(fname, 'r') | 299 fp = self.opener(fname, 'r') |
298 try: | 300 try: |
299 return list(linereader(fp, self.eol is not None)) | 301 return list(linereader(fp, self.eolmode != 'strict')) |
300 finally: | 302 finally: |
301 fp.close() | 303 fp.close() |
302 | 304 |
303 def writelines(self, fname, lines): | 305 def writelines(self, fname, lines): |
304 # Ensure supplied data ends in fname, being a regular file or | 306 # Ensure supplied data ends in fname, being a regular file or |
937 current_hunk.desc)) | 939 current_hunk.desc)) |
938 | 940 |
939 if hunknum == 0 and dopatch and not gitworkdone: | 941 if hunknum == 0 and dopatch and not gitworkdone: |
940 raise NoHunks | 942 raise NoHunks |
941 | 943 |
942 def applydiff(ui, fp, changed, strip=1, sourcefile=None, eol=None): | 944 def applydiff(ui, fp, changed, strip=1, sourcefile=None, eolmode='strict'): |
943 """ | 945 """ |
944 Reads a patch from fp and tries to apply it. | 946 Reads a patch from fp and tries to apply it. |
945 | 947 |
946 The dict 'changed' is filled in with all of the filenames changed | 948 The dict 'changed' is filled in with all of the filenames changed |
947 by the patch. Returns 0 for a clean patch, -1 if any rejects were | 949 by the patch. Returns 0 for a clean patch, -1 if any rejects were |
948 found and 1 if there was any fuzz. | 950 found and 1 if there was any fuzz. |
949 | 951 |
950 If 'eol' is None, the patch content and patched file are read in | 952 If 'eolmode' is 'strict', the patch content and patched file are |
951 binary mode. Otherwise, line endings are ignored when patching then | 953 read in binary mode. Otherwise, line endings are ignored when |
952 normalized to 'eol' (usually '\n' or \r\n'). | 954 patching then normalized according to 'eolmode'. |
953 """ | 955 """ |
954 rejects = 0 | 956 rejects = 0 |
955 err = 0 | 957 err = 0 |
956 current_file = None | 958 current_file = None |
957 gitpatches = None | 959 gitpatches = None |
958 opener = util.opener(os.getcwd()) | 960 opener = util.opener(os.getcwd()) |
959 textmode = eol is not None | 961 textmode = eolmode != 'strict' |
960 | 962 |
961 def closefile(): | 963 def closefile(): |
962 if not current_file: | 964 if not current_file: |
963 return 0 | 965 return 0 |
964 current_file.close() | 966 current_file.close() |
977 elif state == 'file': | 979 elif state == 'file': |
978 rejects += closefile() | 980 rejects += closefile() |
979 afile, bfile, first_hunk = values | 981 afile, bfile, first_hunk = values |
980 try: | 982 try: |
981 if sourcefile: | 983 if sourcefile: |
982 current_file = patchfile(ui, sourcefile, opener, eol=eol) | 984 current_file = patchfile(ui, sourcefile, opener, eolmode=eolmode) |
983 else: | 985 else: |
984 current_file, missing = selectfile(afile, bfile, first_hunk, | 986 current_file, missing = selectfile(afile, bfile, first_hunk, |
985 strip) | 987 strip) |
986 current_file = patchfile(ui, current_file, opener, missing, eol) | 988 current_file = patchfile(ui, current_file, opener, missing, eolmode) |
987 except PatchError, err: | 989 except PatchError, err: |
988 ui.warn(str(err) + '\n') | 990 ui.warn(str(err) + '\n') |
989 current_file, current_hunk = None, None | 991 current_file, current_hunk = None, None |
990 rejects += 1 | 992 rejects += 1 |
991 continue | 993 continue |
1102 | 1104 |
1103 if files is None: | 1105 if files is None: |
1104 files = {} | 1106 files = {} |
1105 if eolmode is None: | 1107 if eolmode is None: |
1106 eolmode = ui.config('patch', 'eol', 'strict') | 1108 eolmode = ui.config('patch', 'eol', 'strict') |
1107 try: | 1109 if eolmode.lower() not in eolmodes: |
1108 eol = {'strict': None, 'crlf': '\r\n', 'lf': '\n'}[eolmode.lower()] | |
1109 except KeyError: | |
1110 raise util.Abort(_('Unsupported line endings type: %s') % eolmode) | 1110 raise util.Abort(_('Unsupported line endings type: %s') % eolmode) |
1111 eolmode = eolmode.lower() | |
1111 | 1112 |
1112 try: | 1113 try: |
1113 fp = open(patchobj, 'rb') | 1114 fp = open(patchobj, 'rb') |
1114 except TypeError: | 1115 except TypeError: |
1115 fp = patchobj | 1116 fp = patchobj |
1116 if cwd: | 1117 if cwd: |
1117 curdir = os.getcwd() | 1118 curdir = os.getcwd() |
1118 os.chdir(cwd) | 1119 os.chdir(cwd) |
1119 try: | 1120 try: |
1120 ret = applydiff(ui, fp, files, strip=strip, eol=eol) | 1121 ret = applydiff(ui, fp, files, strip=strip, eolmode=eolmode) |
1121 finally: | 1122 finally: |
1122 if cwd: | 1123 if cwd: |
1123 os.chdir(curdir) | 1124 os.chdir(curdir) |
1124 if ret < 0: | 1125 if ret < 0: |
1125 raise PatchError | 1126 raise PatchError |