Show More
@@ -290,6 +290,19 b' class patchmeta(object):' | |||
|
290 | 290 | other.binary = self.binary |
|
291 | 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 | 306 | def __repr__(self): |
|
294 | 307 | return "<patchmeta %s %r>" % (self.op, self.path) |
|
295 | 308 | |
@@ -1180,8 +1193,8 b' def iterhunks(fp):' | |||
|
1180 | 1193 | or x.startswith('GIT binary patch')): |
|
1181 | 1194 | gp = None |
|
1182 | 1195 | if (gitpatches and |
|
1183 |
|
|
|
1184 |
gp = gitpatches.pop() |
|
|
1196 | gitpatches[-1].ispatching(afile, bfile)): | |
|
1197 | gp = gitpatches.pop() | |
|
1185 | 1198 | if x.startswith('GIT binary patch'): |
|
1186 | 1199 | h = binhunk(lr) |
|
1187 | 1200 | else: |
@@ -1197,22 +1210,21 b' def iterhunks(fp):' | |||
|
1197 | 1210 | m = gitre.match(x) |
|
1198 | 1211 | if not m: |
|
1199 | 1212 | continue |
|
1200 |
if |
|
|
1213 | if gitpatches is None: | |
|
1201 | 1214 | # scan whole input for git metadata |
|
1202 |
gitpatches = |
|
|
1203 | in scangitpatch(lr, x)] | |
|
1204 | yield 'git', [g[2].copy() for g in gitpatches | |
|
1205 | if g[2].op in ('COPY', 'RENAME')] | |
|
1215 | gitpatches = scangitpatch(lr, x) | |
|
1216 | yield 'git', [g.copy() for g in gitpatches | |
|
1217 | if g.op in ('COPY', 'RENAME')] | |
|
1206 | 1218 | gitpatches.reverse() |
|
1207 | 1219 | afile = 'a/' + m.group(1) |
|
1208 | 1220 | bfile = 'b/' + m.group(2) |
|
1209 | while afile != gitpatches[-1][0] and bfile != gitpatches[-1][1]: | |
|
1210 |
gp = gitpatches.pop() |
|
|
1221 | while gitpatches and not gitpatches[-1].ispatching(afile, bfile): | |
|
1222 | gp = gitpatches.pop() | |
|
1211 | 1223 | yield 'file', ('a/' + gp.path, 'b/' + gp.path, None, gp.copy()) |
|
1212 |
|
|
|
1213 | # copy/rename + modify should modify target, not source | |
|
1214 | if gp.op in ('COPY', 'DELETE', 'RENAME', 'ADD') or gp.mode: | |
|
1215 | afile = bfile | |
|
1224 | if not gitpatches: | |
|
1225 | raise PatchError(_('failed to synchronize metadata for "%s"') | |
|
1226 | % afile[2:]) | |
|
1227 | gp = gitpatches[-1] | |
|
1216 | 1228 | newfile = True |
|
1217 | 1229 | elif x.startswith('---'): |
|
1218 | 1230 | # check for a unified diff |
@@ -1247,7 +1259,7 b' def iterhunks(fp):' | |||
|
1247 | 1259 | hunknum = 0 |
|
1248 | 1260 | |
|
1249 | 1261 | while gitpatches: |
|
1250 |
gp = gitpatches.pop() |
|
|
1262 | gp = gitpatches.pop() | |
|
1251 | 1263 | yield 'file', ('a/' + gp.path, 'b/' + gp.path, None, gp.copy()) |
|
1252 | 1264 | |
|
1253 | 1265 | def applydiff(ui, fp, backend, store, strip=1, eolmode='strict'): |
@@ -483,4 +483,28 b' Copy and changes with existing destinati' | |||
|
483 | 483 | ? b.rej |
|
484 | 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 | 510 | $ cd .. |
General Comments 0
You need to be logged in to leave comments.
Login now