##// 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 - ("git", gitchanges): current diff is in git format, gitchanges
1113 - ("git", gitchanges): current diff is in git format, gitchanges
1114 maps filenames to gitpatch records. Unique event.
1114 maps filenames to gitpatch records. Unique event.
1115 """
1115 """
1116 changed = {}
1117 afile = ""
1116 afile = ""
1118 bfile = ""
1117 bfile = ""
1119 state = None
1118 state = None
1120 hunknum = 0
1119 hunknum = 0
1121 emitfile = newfile = False
1120 emitfile = newfile = False
1122 git = False
1121 gitpatches = None
1123
1122
1124 # our states
1123 # our states
1125 BFILE = 1
1124 BFILE = 1
@@ -1134,7 +1133,9 b' def iterhunks(fp):'
1134 (not context and x[0] == '@')
1133 (not context and x[0] == '@')
1135 or (context is not False and x.startswith('***************'))
1134 or (context is not False and x.startswith('***************'))
1136 or x.startswith('GIT binary patch')):
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 if x.startswith('GIT binary patch'):
1139 if x.startswith('GIT binary patch'):
1139 h = binhunk(gp, lr)
1140 h = binhunk(gp, lr)
1140 else:
1141 else:
@@ -1146,22 +1147,24 b' def iterhunks(fp):'
1146 hunknum += 1
1147 hunknum += 1
1147 if emitfile:
1148 if emitfile:
1148 emitfile = False
1149 emitfile = False
1149 yield 'file', (afile, bfile, h, gp and gp.mode or None)
1150 yield 'file', (afile, bfile, h, gp)
1150 yield 'hunk', h
1151 yield 'hunk', h
1151 elif x.startswith('diff --git'):
1152 elif x.startswith('diff --git'):
1152 m = gitre.match(x)
1153 m = gitre.match(x)
1153 if not m:
1154 if not m:
1154 continue
1155 continue
1155 if not git:
1156 if gitpatches is None:
1156 # scan whole input for git metadata
1157 # scan whole input for git metadata
1157 git = True
1158 gitpatches = [('b/' + gp.path, gp) for gp
1158 gitpatches = scangitpatch(lr, x)
1159 in scangitpatch(lr, x)]
1159 for gp in gitpatches:
1160 yield 'git', [g[1] for g in gitpatches]
1160 changed['b/' + gp.path] = gp
1161 gitpatches.reverse()
1161 yield 'git', gitpatches
1162 afile = 'a/' + m.group(1)
1162 afile = 'a/' + m.group(1)
1163 bfile = 'b/' + m.group(2)
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 # copy/rename + modify should modify target, not source
1168 # copy/rename + modify should modify target, not source
1166 if gp.op in ('COPY', 'DELETE', 'RENAME', 'ADD') or gp.mode:
1169 if gp.op in ('COPY', 'DELETE', 'RENAME', 'ADD') or gp.mode:
1167 afile = bfile
1170 afile = bfile
@@ -1198,6 +1201,10 b' def iterhunks(fp):'
1198 state = BFILE
1201 state = BFILE
1199 hunknum = 0
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 def applydiff(ui, fp, changed, backend, strip=1, eolmode='strict'):
1208 def applydiff(ui, fp, changed, backend, strip=1, eolmode='strict'):
1202 """Reads a patch from fp and tries to apply it.
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 elif state == 'file':
1236 elif state == 'file':
1230 if current_file:
1237 if current_file:
1231 rejects += current_file.close()
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 try:
1256 try:
1257 mode = gp and gp.mode or None
1234 current_file, missing = selectfile(backend, afile, bfile,
1258 current_file, missing = selectfile(backend, afile, bfile,
1235 first_hunk, strip)
1259 first_hunk, strip)
1236 current_file = patcher(ui, current_file, backend, mode,
1260 current_file = patcher(ui, current_file, backend, mode,
@@ -1247,32 +1271,12 b' def _applydiff(ui, fp, patcher, backend,'
1247 gp.oldpath = pathstrip(gp.oldpath, strip - 1)[1]
1271 gp.oldpath = pathstrip(gp.oldpath, strip - 1)[1]
1248 if gp.op in ('COPY', 'RENAME'):
1272 if gp.op in ('COPY', 'RENAME'):
1249 backend.copy(gp.oldpath, gp.path)
1273 backend.copy(gp.oldpath, gp.path)
1250 changed[gp.path] = gp
1251 else:
1274 else:
1252 raise util.Abort(_('unsupported parser state: %s') % state)
1275 raise util.Abort(_('unsupported parser state: %s') % state)
1253
1276
1254 if current_file:
1277 if current_file:
1255 rejects += current_file.close()
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 if rejects:
1280 if rejects:
1277 return -1
1281 return -1
1278 return err
1282 return err
@@ -1386,18 +1390,21 b' def changedfiles(ui, repo, patchpath, st'
1386 if state == 'hunk':
1390 if state == 'hunk':
1387 continue
1391 continue
1388 elif state == 'file':
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 current_file, missing = selectfile(backend, afile, bfile,
1400 current_file, missing = selectfile(backend, afile, bfile,
1391 first_hunk, strip)
1401 first_hunk, strip)
1392 changed.add(current_file)
1402 changed.add(current_file)
1393 elif state == 'git':
1403 elif state == 'git':
1394 for gp in values:
1404 for gp in values:
1395 gp.path = pathstrip(gp.path, strip - 1)[1]
1405 gp.path = pathstrip(gp.path, strip - 1)[1]
1396 changed.add(gp.path)
1397 if gp.oldpath:
1406 if gp.oldpath:
1398 gp.oldpath = pathstrip(gp.oldpath, strip - 1)[1]
1407 gp.oldpath = pathstrip(gp.oldpath, strip - 1)[1]
1399 if gp.op == 'RENAME':
1400 changed.add(gp.oldpath)
1401 else:
1408 else:
1402 raise util.Abort(_('unsupported parser state: %s') % state)
1409 raise util.Abort(_('unsupported parser state: %s') % state)
1403 return changed
1410 return changed
General Comments 0
You need to be logged in to leave comments. Login now