mercurial/patch.py
branchstable
changeset 16506 fc4e0fecf403
parent 16475 1f75c1decdeb
child 16522 a8065323c003
equal deleted inserted replaced
16505:db85c24dcdea 16506:fc4e0fecf403
   287         other.oldpath = self.oldpath
   287         other.oldpath = self.oldpath
   288         other.mode = self.mode
   288         other.mode = self.mode
   289         other.op = self.op
   289         other.op = self.op
   290         other.binary = self.binary
   290         other.binary = self.binary
   291         return other
   291         return other
       
   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)
   292 
   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 
   296 def readgitpatch(lr):
   309 def readgitpatch(lr):
  1178             (not context and x[0] == '@')
  1191             (not context and x[0] == '@')
  1179             or (context is not False and x.startswith('***************'))
  1192             or (context is not False and x.startswith('***************'))
  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:
  1188                 if context is None and x.startswith('***************'):
  1201                 if context is None and x.startswith('***************'):
  1189                     context = True
  1202                     context = True
  1195             yield 'hunk', h
  1208             yield 'hunk', h
  1196         elif x.startswith('diff --git'):
  1209         elif x.startswith('diff --git'):
  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
  1219             l2 = lr.readline()
  1231             l2 = lr.readline()
  1220             if not l2.startswith('+++'):
  1232             if not l2.startswith('+++'):
  1245             emitfile = True
  1257             emitfile = True
  1246             state = BFILE
  1258             state = BFILE
  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'):
  1254     """Reads a patch from fp and tries to apply it.
  1266     """Reads a patch from fp and tries to apply it.
  1255 
  1267