##// END OF EJS Templates
patch: add support for git delta hunks...
Nicolas Vigier -
r20137:9f1d4323 default
parent child Browse files
Show More
@@ -721,8 +721,9 b' class patchfile(object):'
721 if self.remove:
721 if self.remove:
722 self.backend.unlink(self.fname)
722 self.backend.unlink(self.fname)
723 else:
723 else:
724 self.lines[:] = h.new()
724 l = h.new(self.lines)
725 self.offset += len(h.new())
725 self.lines[:] = l
726 self.offset += len(l)
726 self.dirty = True
727 self.dirty = True
727 return 0
728 return 0
728
729
@@ -1016,9 +1017,10 b' class hunk(object):'
1016 return old, oldstart, new, newstart
1017 return old, oldstart, new, newstart
1017
1018
1018 class binhunk(object):
1019 class binhunk(object):
1019 'A binary patch file. Only understands literals so far.'
1020 'A binary patch file.'
1020 def __init__(self, lr, fname):
1021 def __init__(self, lr, fname):
1021 self.text = None
1022 self.text = None
1023 self.delta = False
1022 self.hunk = ['GIT binary patch\n']
1024 self.hunk = ['GIT binary patch\n']
1023 self._fname = fname
1025 self._fname = fname
1024 self._read(lr)
1026 self._read(lr)
@@ -1026,7 +1028,9 b' class binhunk(object):'
1026 def complete(self):
1028 def complete(self):
1027 return self.text is not None
1029 return self.text is not None
1028
1030
1029 def new(self):
1031 def new(self, lines):
1032 if self.delta:
1033 return [applybindelta(self.text, ''.join(lines))]
1030 return [self.text]
1034 return [self.text]
1031
1035
1032 def _read(self, lr):
1036 def _read(self, lr):
@@ -1035,14 +1039,19 b' class binhunk(object):'
1035 hunk.append(l)
1039 hunk.append(l)
1036 return l.rstrip('\r\n')
1040 return l.rstrip('\r\n')
1037
1041
1042 size = 0
1038 while True:
1043 while True:
1039 line = getline(lr, self.hunk)
1044 line = getline(lr, self.hunk)
1040 if not line:
1045 if not line:
1041 raise PatchError(_('could not extract "%s" binary data')
1046 raise PatchError(_('could not extract "%s" binary data')
1042 % self._fname)
1047 % self._fname)
1043 if line.startswith('literal '):
1048 if line.startswith('literal '):
1049 size = int(line[8:].rstrip())
1044 break
1050 break
1045 size = int(line[8:].rstrip())
1051 if line.startswith('delta '):
1052 size = int(line[6:].rstrip())
1053 self.delta = True
1054 break
1046 dec = []
1055 dec = []
1047 line = getline(lr, self.hunk)
1056 line = getline(lr, self.hunk)
1048 while len(line) > 1:
1057 while len(line) > 1:
@@ -1265,6 +1274,62 b' def iterhunks(fp):'
1265 gp = gitpatches.pop()
1274 gp = gitpatches.pop()
1266 yield 'file', ('a/' + gp.path, 'b/' + gp.path, None, gp.copy())
1275 yield 'file', ('a/' + gp.path, 'b/' + gp.path, None, gp.copy())
1267
1276
1277 def applybindelta(binchunk, data):
1278 """Apply a binary delta hunk
1279 The algorithm used is the algorithm from git's patch-delta.c
1280 """
1281 def deltahead(binchunk):
1282 i = 0
1283 for c in binchunk:
1284 i += 1
1285 if not (ord(c) & 0x80):
1286 return i
1287 return i
1288 out = ""
1289 s = deltahead(binchunk)
1290 binchunk = binchunk[s:]
1291 s = deltahead(binchunk)
1292 binchunk = binchunk[s:]
1293 i = 0
1294 while i < len(binchunk):
1295 cmd = ord(binchunk[i])
1296 i += 1
1297 if (cmd & 0x80):
1298 offset = 0
1299 size = 0
1300 if (cmd & 0x01):
1301 offset = ord(binchunk[i])
1302 i += 1
1303 if (cmd & 0x02):
1304 offset |= ord(binchunk[i]) << 8
1305 i += 1
1306 if (cmd & 0x04):
1307 offset |= ord(binchunk[i]) << 16
1308 i += 1
1309 if (cmd & 0x08):
1310 offset |= ord(binchunk[i]) << 24
1311 i += 1
1312 if (cmd & 0x10):
1313 size = ord(binchunk[i])
1314 i += 1
1315 if (cmd & 0x20):
1316 size |= ord(binchunk[i]) << 8
1317 i += 1
1318 if (cmd & 0x40):
1319 size |= ord(binchunk[i]) << 16
1320 i += 1
1321 if size == 0:
1322 size = 0x10000
1323 offset_end = offset + size
1324 out += data[offset:offset_end]
1325 elif cmd != 0:
1326 offset_end = i + cmd
1327 out += binchunk[i:offset_end]
1328 i += cmd
1329 else:
1330 raise PatchError(_('unexpected delta opcode 0'))
1331 return out
1332
1268 def applydiff(ui, fp, backend, store, strip=1, eolmode='strict'):
1333 def applydiff(ui, fp, backend, store, strip=1, eolmode='strict'):
1269 """Reads a patch from fp and tries to apply it.
1334 """Reads a patch from fp and tries to apply it.
1270
1335
@@ -320,6 +320,115 b' Multiple binary files:'
320 045c85ba38952325e126c70962cc0f9d9077bc67 644 mbinary1
320 045c85ba38952325e126c70962cc0f9d9077bc67 644 mbinary1
321 a874b471193996e7cb034bb301cac7bdaf3e3f46 644 mbinary2
321 a874b471193996e7cb034bb301cac7bdaf3e3f46 644 mbinary2
322
322
323 Binary file and delta hunk:
324
325 $ hg import -d "1000000 0" -m delta - <<'EOF'
326 > diff --git a/delta b/delta
327 > new file mode 100644
328 > index 0000000000000000000000000000000000000000..8c9b7831b231c2600843e303e66b521353a200b3
329 > GIT binary patch
330 > literal 3749
331 > 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
403 > P00000NkvXXu0mjfZ5|Er
404 >
405 > literal 0
406 > HcmV?d00001
407 >
408 > EOF
409 applying patch from stdin
410
411 $ hg manifest --debug | grep delta
412 9600f98bb60ce732634d126aaa4ac1ec959c573e 644 delta
413
414 $ hg import -d "1000000 0" -m delta - <<'EOF'
415 > diff --git a/delta b/delta
416 > index 8c9b7831b231c2600843e303e66b521353a200b3..0021dd95bc0dba53c39ce81377126d43731d68df 100644
417 > GIT binary patch
418 > delta 49
419 > zcmZ1~yHs|=21Z8J$r~9bFdA-lVv=EEw4WT$qRf2QSa5SIOAHI6(&k4T8H|kLo4vWB
420 > FSO9ZT4bA`n
421 >
422 > delta 49
423 > zcmV-10M7rV9i<(xumJ(}ld%Di0Xefm0vrMXpOaq%BLm9I%d>?9Tm%6Vv*HM70RcC&
424 > HOA1;9yU-AD
425 >
426 > EOF
427 applying patch from stdin
428
429 $ hg manifest --debug | grep delta
430 56094bbea136dcf8dbd4088f6af469bde1a98b75 644 delta
431
323 Filenames with spaces:
432 Filenames with spaces:
324
433
325 $ sed 's,EOL$,,g' <<EOF | hg import -d "1000000 0" -m spaces -
434 $ sed 's,EOL$,,g' <<EOF | hg import -d "1000000 0" -m spaces -
@@ -334,7 +443,7 b' Filenames with spaces:'
334 applying patch from stdin
443 applying patch from stdin
335
444
336 $ hg tip -q
445 $ hg tip -q
337 12:47500ce1614e
446 14:4b79479c9a6d
338
447
339 $ cat "foo bar"
448 $ cat "foo bar"
340 foo
449 foo
@@ -357,7 +466,7 b' Copy then modify the original file:'
357 applying patch from stdin
466 applying patch from stdin
358
467
359 $ hg tip -q
468 $ hg tip -q
360 13:6757efb07ea9
469 15:9cbe44af4ae9
361
470
362 $ cat foo3
471 $ cat foo3
363 foo
472 foo
@@ -392,8 +501,8 b' Move text file and patch as binary'
392 Invalid base85 content
501 Invalid base85 content
393
502
394 $ hg rollback
503 $ hg rollback
395 repository tip rolled back to revision 14 (undo import)
504 repository tip rolled back to revision 16 (undo import)
396 working directory now based on revision 14
505 working directory now based on revision 16
397 $ hg revert -aq
506 $ hg revert -aq
398 $ hg import -d "1000000 0" -m invalid-binary - <<"EOF"
507 $ hg import -d "1000000 0" -m invalid-binary - <<"EOF"
399 > diff --git a/text2 b/binary2
508 > diff --git a/text2 b/binary2
General Comments 0
You need to be logged in to leave comments. Login now