comparison mercurial/patch.py @ 10966:91c58cf54eee

patch: refactor applydiff to allow for mempatching
author Augie Fackler <durin42@gmail.com>
date Sat, 17 Apr 2010 13:23:24 -0500
parents 7faef79a89c7
children 17cf756ba25d
comparison
equal deleted inserted replaced
10965:7faef79a89c7 10966:91c58cf54eee
1124 current_hunk.desc)) 1124 current_hunk.desc))
1125 1125
1126 if (empty is None and not gitworkdone) or empty: 1126 if (empty is None and not gitworkdone) or empty:
1127 raise NoHunks 1127 raise NoHunks
1128 1128
1129
1129 def applydiff(ui, fp, changed, strip=1, sourcefile=None, eolmode='strict'): 1130 def applydiff(ui, fp, changed, strip=1, sourcefile=None, eolmode='strict'):
1130 """ 1131 """Reads a patch from fp and tries to apply it.
1131 Reads a patch from fp and tries to apply it.
1132 1132
1133 The dict 'changed' is filled in with all of the filenames changed 1133 The dict 'changed' is filled in with all of the filenames changed
1134 by the patch. Returns 0 for a clean patch, -1 if any rejects were 1134 by the patch. Returns 0 for a clean patch, -1 if any rejects were
1135 found and 1 if there was any fuzz. 1135 found and 1 if there was any fuzz.
1136 1136
1137 If 'eolmode' is 'strict', the patch content and patched file are 1137 If 'eolmode' is 'strict', the patch content and patched file are
1138 read in binary mode. Otherwise, line endings are ignored when 1138 read in binary mode. Otherwise, line endings are ignored when
1139 patching then normalized according to 'eolmode'. 1139 patching then normalized according to 'eolmode'.
1140
1141 Callers probably want to call 'updatedir' after this to apply
1142 certain categories of changes not done by this function.
1140 """ 1143 """
1144 return _applydiff(
1145 ui, fp, patchfile, copyfile,
1146 changed, strip=strip, sourcefile=sourcefile, eolmode=eolmode)
1147
1148
1149 def _applydiff(ui, fp, patcher, copyfn, changed, strip=1,
1150 sourcefile=None, eolmode='strict'):
1141 rejects = 0 1151 rejects = 0
1142 err = 0 1152 err = 0
1143 current_file = None 1153 current_file = None
1144 gitpatches = None 1154 gitpatches = None
1145 opener = util.opener(os.getcwd()) 1155 opener = util.opener(os.getcwd())
1163 elif state == 'file': 1173 elif state == 'file':
1164 rejects += closefile() 1174 rejects += closefile()
1165 afile, bfile, first_hunk = values 1175 afile, bfile, first_hunk = values
1166 try: 1176 try:
1167 if sourcefile: 1177 if sourcefile:
1168 current_file = patchfile(ui, sourcefile, opener, 1178 current_file = patcher(ui, sourcefile, opener,
1169 eolmode=eolmode) 1179 eolmode=eolmode)
1170 else: 1180 else:
1171 current_file, missing = selectfile(afile, bfile, 1181 current_file, missing = selectfile(afile, bfile,
1172 first_hunk, strip) 1182 first_hunk, strip)
1173 current_file = patchfile(ui, current_file, opener, 1183 current_file = patcher(ui, current_file, opener,
1174 missing, eolmode) 1184 missing=missing, eolmode=eolmode)
1175 except PatchError, err: 1185 except PatchError, err:
1176 ui.warn(str(err) + '\n') 1186 ui.warn(str(err) + '\n')
1177 current_file, current_hunk = None, None 1187 current_file, current_hunk = None, None
1178 rejects += 1 1188 rejects += 1
1179 continue 1189 continue
1180 elif state == 'git': 1190 elif state == 'git':
1181 gitpatches = values 1191 gitpatches = values
1182 cwd = os.getcwd() 1192 cwd = os.getcwd()
1183 for gp in gitpatches: 1193 for gp in gitpatches:
1184 if gp.op in ('COPY', 'RENAME'): 1194 if gp.op in ('COPY', 'RENAME'):
1185 copyfile(gp.oldpath, gp.path, cwd) 1195 copyfn(gp.oldpath, gp.path, cwd)
1186 changed[gp.path] = gp 1196 changed[gp.path] = gp
1187 else: 1197 else:
1188 raise util.Abort(_('unsupported parser state: %s') % state) 1198 raise util.Abort(_('unsupported parser state: %s') % state)
1189 1199
1190 rejects += closefile() 1200 rejects += closefile()