##// END OF EJS Templates
patch: fix patch hunk/metdata synchronization (issue3384)...
Patrick Mezard -
r16506:fc4e0fec stable
parent child Browse files
Show More
@@ -290,6 +290,19 b' class patchmeta(object):'
290 other.binary = self.binary
290 other.binary = self.binary
291 return other
291 return other
292
292
293 def _ispatchinga(self, afile):
294 if afile == '/dev/null':
295 return self.op == 'ADD'
296 return afile == 'a/' + (self.oldpath or self.path)
297
298 def _ispatchingb(self, bfile):
299 if bfile == '/dev/null':
300 return self.op == 'DELETE'
301 return bfile == 'b/' + self.path
302
303 def ispatching(self, afile, bfile):
304 return self._ispatchinga(afile) and self._ispatchingb(bfile)
305
293 def __repr__(self):
306 def __repr__(self):
294 return "<patchmeta %s %r>" % (self.op, self.path)
307 return "<patchmeta %s %r>" % (self.op, self.path)
295
308
@@ -1180,8 +1193,8 b' def iterhunks(fp):'
1180 or x.startswith('GIT binary patch')):
1193 or x.startswith('GIT binary patch')):
1181 gp = None
1194 gp = None
1182 if (gitpatches and
1195 if (gitpatches and
1183 (gitpatches[-1][0] == afile or gitpatches[-1][1] == bfile)):
1196 gitpatches[-1].ispatching(afile, bfile)):
1184 gp = gitpatches.pop()[2]
1197 gp = gitpatches.pop()
1185 if x.startswith('GIT binary patch'):
1198 if x.startswith('GIT binary patch'):
1186 h = binhunk(lr)
1199 h = binhunk(lr)
1187 else:
1200 else:
@@ -1197,22 +1210,21 b' def iterhunks(fp):'
1197 m = gitre.match(x)
1210 m = gitre.match(x)
1198 if not m:
1211 if not m:
1199 continue
1212 continue
1200 if not gitpatches:
1213 if gitpatches is None:
1201 # scan whole input for git metadata
1214 # scan whole input for git metadata
1202 gitpatches = [('a/' + gp.path, 'b/' + gp.path, gp) for gp
1215 gitpatches = scangitpatch(lr, x)
1203 in scangitpatch(lr, x)]
1216 yield 'git', [g.copy() for g in gitpatches
1204 yield 'git', [g[2].copy() for g in gitpatches
1217 if g.op in ('COPY', 'RENAME')]
1205 if g[2].op in ('COPY', 'RENAME')]
1206 gitpatches.reverse()
1218 gitpatches.reverse()
1207 afile = 'a/' + m.group(1)
1219 afile = 'a/' + m.group(1)
1208 bfile = 'b/' + m.group(2)
1220 bfile = 'b/' + m.group(2)
1209 while afile != gitpatches[-1][0] and bfile != gitpatches[-1][1]:
1221 while gitpatches and not gitpatches[-1].ispatching(afile, bfile):
1210 gp = gitpatches.pop()[2]
1222 gp = gitpatches.pop()
1211 yield 'file', ('a/' + gp.path, 'b/' + gp.path, None, gp.copy())
1223 yield 'file', ('a/' + gp.path, 'b/' + gp.path, None, gp.copy())
1212 gp = gitpatches[-1][2]
1224 if not gitpatches:
1213 # copy/rename + modify should modify target, not source
1225 raise PatchError(_('failed to synchronize metadata for "%s"')
1214 if gp.op in ('COPY', 'DELETE', 'RENAME', 'ADD') or gp.mode:
1226 % afile[2:])
1215 afile = bfile
1227 gp = gitpatches[-1]
1216 newfile = True
1228 newfile = True
1217 elif x.startswith('---'):
1229 elif x.startswith('---'):
1218 # check for a unified diff
1230 # check for a unified diff
@@ -1247,7 +1259,7 b' def iterhunks(fp):'
1247 hunknum = 0
1259 hunknum = 0
1248
1260
1249 while gitpatches:
1261 while gitpatches:
1250 gp = gitpatches.pop()[2]
1262 gp = gitpatches.pop()
1251 yield 'file', ('a/' + gp.path, 'b/' + gp.path, None, gp.copy())
1263 yield 'file', ('a/' + gp.path, 'b/' + gp.path, None, gp.copy())
1252
1264
1253 def applydiff(ui, fp, backend, store, strip=1, eolmode='strict'):
1265 def applydiff(ui, fp, backend, store, strip=1, eolmode='strict'):
@@ -483,4 +483,28 b' Copy and changes with existing destinati'
483 ? b.rej
483 ? b.rej
484 ? linkb.rej
484 ? linkb.rej
485
485
486 Test corner case involving copies and multiple hunks (issue3384)
487
488 $ hg revert -qa
489 $ hg import --no-commit - <<EOF
490 > diff --git a/a b/c
491 > copy from a
492 > copy to c
493 > --- a/a
494 > +++ b/c
495 > @@ -1,1 +1,2 @@
496 > a
497 > +a
498 > @@ -2,1 +2,2 @@
499 > a
500 > +a
501 > diff --git a/a b/a
502 > --- a/a
503 > +++ b/a
504 > @@ -1,1 +1,2 @@
505 > a
506 > +b
507 > EOF
508 applying patch from stdin
509
486 $ cd ..
510 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now