##// END OF EJS Templates
patch: stop handling hunkless git blocks out of stream...
Patrick Mezard -
r14388:37c997d2 default
parent child Browse files
Show More
@@ -1113,13 +1113,12 b' def iterhunks(fp):'
1113 1113 - ("git", gitchanges): current diff is in git format, gitchanges
1114 1114 maps filenames to gitpatch records. Unique event.
1115 1115 """
1116 changed = {}
1117 1116 afile = ""
1118 1117 bfile = ""
1119 1118 state = None
1120 1119 hunknum = 0
1121 1120 emitfile = newfile = False
1122 git = False
1121 gitpatches = None
1123 1122
1124 1123 # our states
1125 1124 BFILE = 1
@@ -1134,7 +1133,9 b' def iterhunks(fp):'
1134 1133 (not context and x[0] == '@')
1135 1134 or (context is not False and x.startswith('***************'))
1136 1135 or x.startswith('GIT binary patch')):
1137 gp = changed.get(bfile)
1136 gp = None
1137 if gitpatches and gitpatches[-1][0] == bfile:
1138 gp = gitpatches.pop()[1]
1138 1139 if x.startswith('GIT binary patch'):
1139 1140 h = binhunk(gp, lr)
1140 1141 else:
@@ -1146,22 +1147,24 b' def iterhunks(fp):'
1146 1147 hunknum += 1
1147 1148 if emitfile:
1148 1149 emitfile = False
1149 yield 'file', (afile, bfile, h, gp and gp.mode or None)
1150 yield 'file', (afile, bfile, h, gp)
1150 1151 yield 'hunk', h
1151 1152 elif x.startswith('diff --git'):
1152 1153 m = gitre.match(x)
1153 1154 if not m:
1154 1155 continue
1155 if not git:
1156 if gitpatches is None:
1156 1157 # scan whole input for git metadata
1157 git = True
1158 gitpatches = scangitpatch(lr, x)
1159 for gp in gitpatches:
1160 changed['b/' + gp.path] = gp
1161 yield 'git', gitpatches
1158 gitpatches = [('b/' + gp.path, gp) for gp
1159 in scangitpatch(lr, x)]
1160 yield 'git', [g[1] for g in gitpatches]
1161 gitpatches.reverse()
1162 1162 afile = 'a/' + m.group(1)
1163 1163 bfile = 'b/' + m.group(2)
1164 gp = changed[bfile]
1164 while bfile != gitpatches[-1][0]:
1165 gp = gitpatches.pop()[1]
1166 yield 'file', ('a/' + gp.path, 'b/' + gp.path, None, gp)
1167 gp = gitpatches[-1][1]
1165 1168 # copy/rename + modify should modify target, not source
1166 1169 if gp.op in ('COPY', 'DELETE', 'RENAME', 'ADD') or gp.mode:
1167 1170 afile = bfile
@@ -1198,6 +1201,10 b' def iterhunks(fp):'
1198 1201 state = BFILE
1199 1202 hunknum = 0
1200 1203
1204 while gitpatches:
1205 gp = gitpatches.pop()[1]
1206 yield 'file', ('a/' + gp.path, 'b/' + gp.path, None, gp)
1207
1201 1208 def applydiff(ui, fp, changed, backend, strip=1, eolmode='strict'):
1202 1209 """Reads a patch from fp and tries to apply it.
1203 1210
@@ -1229,8 +1236,25 b' def _applydiff(ui, fp, patcher, backend,'
1229 1236 elif state == 'file':
1230 1237 if current_file:
1231 1238 rejects += current_file.close()
1232 afile, bfile, first_hunk, mode = values
1239 current_file = None
1240 afile, bfile, first_hunk, gp = values
1241 if gp:
1242 changed[gp.path] = gp
1243 if gp.op == 'DELETE':
1244 backend.unlink(gp.path)
1245 continue
1246 if gp.op == 'RENAME':
1247 backend.unlink(gp.oldpath)
1248 if gp.mode and not first_hunk:
1249 if gp.op == 'ADD':
1250 # Added files without content have no hunk and must be created
1251 backend.writelines(gp.path, [], gp.mode)
1252 else:
1253 backend.setmode(gp.path, gp.mode[0], gp.mode[1])
1254 if not first_hunk:
1255 continue
1233 1256 try:
1257 mode = gp and gp.mode or None
1234 1258 current_file, missing = selectfile(backend, afile, bfile,
1235 1259 first_hunk, strip)
1236 1260 current_file = patcher(ui, current_file, backend, mode,
@@ -1247,32 +1271,12 b' def _applydiff(ui, fp, patcher, backend,'
1247 1271 gp.oldpath = pathstrip(gp.oldpath, strip - 1)[1]
1248 1272 if gp.op in ('COPY', 'RENAME'):
1249 1273 backend.copy(gp.oldpath, gp.path)
1250 changed[gp.path] = gp
1251 1274 else:
1252 1275 raise util.Abort(_('unsupported parser state: %s') % state)
1253 1276
1254 1277 if current_file:
1255 1278 rejects += current_file.close()
1256 1279
1257 # Handle mode changes without hunk
1258 removed = set()
1259 for gp in changed.itervalues():
1260 if not gp:
1261 continue
1262 if gp.op == 'DELETE':
1263 removed.add(gp.path)
1264 continue
1265 if gp.op == 'RENAME':
1266 removed.add(gp.oldpath)
1267 if gp.mode:
1268 if gp.op == 'ADD' and not backend.exists(gp.path):
1269 # Added files without content have no hunk and must be created
1270 backend.writelines(gp.path, [], gp.mode)
1271 else:
1272 backend.setmode(gp.path, gp.mode[0], gp.mode[1])
1273 for path in sorted(removed):
1274 backend.unlink(path)
1275
1276 1280 if rejects:
1277 1281 return -1
1278 1282 return err
@@ -1386,18 +1390,21 b' def changedfiles(ui, repo, patchpath, st'
1386 1390 if state == 'hunk':
1387 1391 continue
1388 1392 elif state == 'file':
1389 afile, bfile, first_hunk, mode = values
1393 afile, bfile, first_hunk, gp = values
1394 if gp:
1395 changed.add(gp.path)
1396 if gp.op == 'RENAME':
1397 changed.add(gp.oldpath)
1398 if not first_hunk:
1399 continue
1390 1400 current_file, missing = selectfile(backend, afile, bfile,
1391 1401 first_hunk, strip)
1392 1402 changed.add(current_file)
1393 1403 elif state == 'git':
1394 1404 for gp in values:
1395 1405 gp.path = pathstrip(gp.path, strip - 1)[1]
1396 changed.add(gp.path)
1397 1406 if gp.oldpath:
1398 1407 gp.oldpath = pathstrip(gp.oldpath, strip - 1)[1]
1399 if gp.op == 'RENAME':
1400 changed.add(gp.oldpath)
1401 1408 else:
1402 1409 raise util.Abort(_('unsupported parser state: %s') % state)
1403 1410 return changed
General Comments 0
You need to be logged in to leave comments. Login now