[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.16-1409-g5afdf4d
hamaji at chromium.org
hamaji at chromium.org
Thu Dec 3 13:33:23 UTC 2009
The following commit has been merged in the webkit-1.1 branch:
commit 24802fa97a525985227726af2fedb241e56ebb17
Author: hamaji at chromium.org <hamaji at chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Thu Nov 12 04:19:07 2009 +0000
2009-11-11 Shinichiro Hamaji <hamaji at chromium.org>
Reviewed by Darin Adler.
svn-apply can not handle git binary diffs
https://bugs.webkit.org/show_bug.cgi?id=26830
Support "literal" type git binary diffs.
* Scripts/VCSUtils.pm:
* Scripts/modules/scm_unittest.py:
* Scripts/svn-apply:
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@50863 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebKitTools/ChangeLog b/WebKitTools/ChangeLog
index 0bac779..7c3bb22 100644
--- a/WebKitTools/ChangeLog
+++ b/WebKitTools/ChangeLog
@@ -1,3 +1,16 @@
+2009-11-11 Shinichiro Hamaji <hamaji at chromium.org>
+
+ Reviewed by Darin Adler.
+
+ svn-apply can not handle git binary diffs
+ https://bugs.webkit.org/show_bug.cgi?id=26830
+
+ Support "literal" type git binary diffs.
+
+ * Scripts/VCSUtils.pm:
+ * Scripts/modules/scm_unittest.py:
+ * Scripts/svn-apply:
+
2009-11-11 Dmitry Titov <dimich at chromium.org>
Not reviewed, removing duplicate entry for myself in committers.py.
diff --git a/WebKitTools/Scripts/VCSUtils.pm b/WebKitTools/Scripts/VCSUtils.pm
index abf7335..7638102 100644
--- a/WebKitTools/Scripts/VCSUtils.pm
+++ b/WebKitTools/Scripts/VCSUtils.pm
@@ -44,6 +44,7 @@ BEGIN {
&changeLogEmailAddress
&changeLogName
&chdirReturningRelativePath
+ &decodeGitBinaryPatch
&determineSVNRoot
&determineVCSRoot
&fixChangeLogPatch
@@ -345,8 +346,6 @@ sub gitdiff2svndiff($)
$_ = shift @_;
if (m#^diff --git a/(.+) b/(.+)#) {
return "Index: $1";
- } elsif (m/^new file.*/) {
- return "";
} elsif (m#^index [0-9a-f]{7}\.\.[0-9a-f]{7} [0-9]{6}#) {
return "===================================================================";
} elsif (m#^--- a/(.+)#) {
@@ -474,4 +473,98 @@ sub changeLogEmailAddress()
return $emailAddress;
}
+# http://tools.ietf.org/html/rfc1924
+sub decodeBase85($)
+{
+ my ($encoded) = @_;
+ my %table;
+ my @characters = ('0'..'9', 'A'..'Z', 'a'..'z', '!', '#', '$', '%', '&', '(', ')', '*', '+', '-', ';', '<', '=', '>', '?', '@', '^', '_', '`', '{', '|', '}', '~');
+ for (my $i = 0; $i < 85; $i++) {
+ $table{$characters[$i]} = $i;
+ }
+
+ my $decoded = '';
+ my @encodedChars = $encoded =~ /./g;
+
+ for (my $encodedIter = 0; defined($encodedChars[$encodedIter]);) {
+ my $digit = 0;
+ for (my $i = 0; $i < 5; $i++) {
+ $digit *= 85;
+ my $char = $encodedChars[$encodedIter];
+ $digit += $table{$char};
+ $encodedIter++;
+ }
+
+ for (my $i = 0; $i < 4; $i++) {
+ $decoded .= chr(($digit >> (3 - $i) * 8) & 255);
+ }
+ }
+
+ return $decoded;
+}
+
+sub decodeGitBinaryChunk($$)
+{
+ my ($contents, $fullPath) = @_;
+
+ # Load this module lazily in case the user don't have this module
+ # and won't handle git binary patches.
+ require Compress::Zlib;
+
+ my $encoded = "";
+ my $compressedSize = 0;
+ while ($contents =~ /^([A-Za-z])(.*)$/gm) {
+ my $line = $2;
+ next if $line eq "";
+ die "$fullPath: unexpected size of a line: $&" if length($2) % 5 != 0;
+ my $actualSize = length($2) / 5 * 4;
+ my $encodedExpectedSize = ord($1);
+ my $expectedSize = $encodedExpectedSize <= ord("Z") ? $encodedExpectedSize - ord("A") + 1 : $encodedExpectedSize - ord("a") + 27;
+
+ die "$fullPath: unexpected size of a line: $&" if int(($expectedSize + 3) / 4) * 4 != $actualSize;
+ $compressedSize += $expectedSize;
+ $encoded .= $line;
+ }
+
+ my $compressed = decodeBase85($encoded);
+ $compressed = substr($compressed, 0, $compressedSize);
+ return Compress::Zlib::uncompress($compressed);
+}
+
+sub decodeGitBinaryPatch($$)
+{
+ my ($contents, $fullPath) = @_;
+
+ # Git binary patch has two chunks. One is for the normal patching
+ # and another is for the reverse patching.
+ #
+ # Each chunk a line which starts from either "literal" or "delta",
+ # followed by a number which specifies decoded size of the chunk.
+ # The "delta" type chunks aren't supported by this function yet.
+ #
+ # Then, content of the chunk comes. To decode the content, we
+ # need decode it with base85 first, and then zlib.
+ my $gitPatchRegExp = '(literal|delta) ([0-9]+)\n([A-Za-z0-9!#$%&()*+-;<=>?@^_`{|}~\\n]*?)\n\n';
+ if ($contents !~ m"\nGIT binary patch\n$gitPatchRegExp$gitPatchRegExp\Z") {
+ die "$fullPath: unknown git binary patch format"
+ }
+
+ my $binaryChunkType = $1;
+ my $binaryChunkExpectedSize = $2;
+ my $encodedChunk = $3;
+ my $reverseBinaryChunkType = $4;
+ my $reverseBinaryChunkExpectedSize = $5;
+ my $encodedReverseChunk = $6;
+
+ my $binaryChunk = decodeGitBinaryChunk($encodedChunk, $fullPath);
+ my $binaryChunkActualSize = length($binaryChunk);
+ my $reverseBinaryChunk = decodeGitBinaryChunk($encodedReverseChunk, $fullPath);
+ my $reverseBinaryChunkActualSize = length($reverseBinaryChunk);
+
+ die "$fullPath: unexpected size of the first chunk (expected $binaryChunkExpectedSize but was $binaryChunkActualSize" if ($binaryChunkExpectedSize != $binaryChunkActualSize);
+ die "$fullPath: unexpected size of the second chunk (expected $reverseBinaryChunkExpectedSize but was $reverseBinaryChunkActualSize" if ($reverseBinaryChunkExpectedSize != $reverseBinaryChunkActualSize);
+
+ return ($binaryChunkType, $binaryChunk, $reverseBinaryChunkType, $reverseBinaryChunk);
+}
+
1;
diff --git a/WebKitTools/Scripts/modules/scm_unittest.py b/WebKitTools/Scripts/modules/scm_unittest.py
index a6a3b71..3f86ef5 100644
--- a/WebKitTools/Scripts/modules/scm_unittest.py
+++ b/WebKitTools/Scripts/modules/scm_unittest.py
@@ -29,6 +29,7 @@
import base64
import os
+import os.path
import re
import stat
import subprocess
@@ -203,6 +204,83 @@ class SCMTest(unittest.TestCase):
self.assertTrue(re.search('test2', r3_patch))
self.assertTrue(re.search('test2', self.scm.diff_for_revision(2)))
+ def _shared_test_svn_apply_git_patch(self):
+ self._setup_webkittools_scripts_symlink(self.scm)
+ git_binary_addition = """diff --git a/fizzbuzz7.gif b/fizzbuzz7.gif
+new file mode 100644
+index 0000000000000000000000000000000000000000..64a9532e7794fcd791f6f12157406d90
+60151690
+GIT binary patch
+literal 512
+zcmZ?wbhEHbRAx|MU|?iW{Kxc~?KofD;ckY;H+&5HnHl!!GQMD7h+sU{_)e9f^V3c?
+zhJP##HdZC#4K}7F68@!1jfWQg2daCm-gs#3|JREDT>c+pG4L<_2;w##WMO#ysPPap
+zLqpAf1OE938xAsSp4!5f-o><?VKe(#0jEcwfHGF4%M1^kRs14oVBp2ZEL{E1N<-zJ
+zsfLmOtKta;2_;2c#^S1-8cf<nb!QnGl>c!Xe6RXvrEtAWBvSDTgTO1j3vA31Puw!A
+zs(87q)j_mVDTqBo-P+03-P5mHCEnJ+x}YdCuS7#bCCyePUe(ynK+|4b-3qK)T?Z&)
+zYG+`tl4h?GZv_$t82}X4*DTE|$;{DEiPyF@)U-1+FaX++T9H{&%cag`W1|zVP@`%b
+zqiSkp6{BTpWTkCr!=<C6Q=?#~R8^JfrliAF6Q^gV9Iup8RqCXqqhqC`qsyhk<-nlB
+z00f{QZvfK&|Nm#oZ0TQl`Yr$BIa6A at 16O26ud7H<QM=xl`toLKnz-3h at 9c9q&wm|X
+z{89I|WPyD!*M?gv?q`;L=2YFeXrJQNti4?}s!zFo=5CzeBxC69xA<zrjP<wUcCRh4
+ptUl-ZG<%a~#LwkIWv&q!KSCH7tQ8cJDiw+|GV?MN)RjY50RTb-xvT&H
+
+literal 0
+HcmV?d00001
+
+"""
+ self.scm.apply_patch(self._create_patch(git_binary_addition))
+ added = read_from_path('fizzbuzz7.gif')
+ self.assertEqual(512, len(added))
+ self.assertTrue(added.startswith('GIF89a'))
+ self.assertTrue('fizzbuzz7.gif' in self.scm.changed_files())
+
+ # The file already exists.
+ self.assertRaises(ScriptError, self.scm.apply_patch, self._create_patch(git_binary_addition))
+
+ git_binary_modification = """diff --git a/fizzbuzz7.gif b/fizzbuzz7.gif
+index 64a9532e7794fcd791f6f12157406d9060151690..323fae03f4606ea9991df8befbb2fca7
+GIT binary patch
+literal 7
+OcmYex&reD$;sO8*F9L)B
+
+literal 512
+zcmZ?wbhEHbRAx|MU|?iW{Kxc~?KofD;ckY;H+&5HnHl!!GQMD7h+sU{_)e9f^V3c?
+zhJP##HdZC#4K}7F68@!1jfWQg2daCm-gs#3|JREDT>c+pG4L<_2;w##WMO#ysPPap
+zLqpAf1OE938xAsSp4!5f-o><?VKe(#0jEcwfHGF4%M1^kRs14oVBp2ZEL{E1N<-zJ
+zsfLmOtKta;2_;2c#^S1-8cf<nb!QnGl>c!Xe6RXvrEtAWBvSDTgTO1j3vA31Puw!A
+zs(87q)j_mVDTqBo-P+03-P5mHCEnJ+x}YdCuS7#bCCyePUe(ynK+|4b-3qK)T?Z&)
+zYG+`tl4h?GZv_$t82}X4*DTE|$;{DEiPyF@)U-1+FaX++T9H{&%cag`W1|zVP@`%b
+zqiSkp6{BTpWTkCr!=<C6Q=?#~R8^JfrliAF6Q^gV9Iup8RqCXqqhqC`qsyhk<-nlB
+z00f{QZvfK&|Nm#oZ0TQl`Yr$BIa6A at 16O26ud7H<QM=xl`toLKnz-3h at 9c9q&wm|X
+z{89I|WPyD!*M?gv?q`;L=2YFeXrJQNti4?}s!zFo=5CzeBxC69xA<zrjP<wUcCRh4
+ptUl-ZG<%a~#LwkIWv&q!KSCH7tQ8cJDiw+|GV?MN)RjY50RTb-xvT&H
+
+"""
+ self.scm.apply_patch(self._create_patch(git_binary_modification))
+ modified = read_from_path('fizzbuzz7.gif')
+ self.assertEqual('foobar\n', modified)
+ self.assertTrue('fizzbuzz7.gif' in self.scm.changed_files())
+
+ # Applying the same modification should fail.
+ self.assertRaises(ScriptError, self.scm.apply_patch, self._create_patch(git_binary_modification))
+
+ git_binary_deletion = """diff --git a/fizzbuzz7.gif b/fizzbuzz7.gif
+deleted file mode 100644
+index 323fae0..0000000
+GIT binary patch
+literal 0
+HcmV?d00001
+
+literal 7
+OcmYex&reD$;sO8*F9L)B
+
+"""
+ self.scm.apply_patch(self._create_patch(git_binary_deletion))
+ self.assertFalse(os.path.exists('fizzbuzz7.gif'))
+ self.assertFalse('fizzbuzz7.gif' in self.scm.changed_files())
+
+ # Cannot delete again.
+ self.assertRaises(ScriptError, self.scm.apply_patch, self._create_patch(git_binary_deletion))
+
class SVNTest(SCMTest):
@@ -387,6 +465,8 @@ Q1dTBx0AAAB42itg4GlgYJjGwMDDyODMxMDw34GBgQEAJPQDJA==
def test_diff_for_revision(self):
self._shared_test_diff_for_revision()
+ def test_svn_apply_git_patch(self):
+ self._shared_test_svn_apply_git_patch()
class GitTest(SCMTest):
@@ -477,5 +557,8 @@ class GitTest(SCMTest):
def test_diff_for_revision(self):
self._shared_test_diff_for_revision()
+ def test_svn_apply_git_patch(self):
+ self._shared_test_svn_apply_git_patch()
+
if __name__ == '__main__':
unittest.main()
diff --git a/WebKitTools/Scripts/svn-apply b/WebKitTools/Scripts/svn-apply
index 4204625..0373aa5 100755
--- a/WebKitTools/Scripts/svn-apply
+++ b/WebKitTools/Scripts/svn-apply
@@ -55,7 +55,7 @@
# Notice a patch that's being applied at the "wrong level" and make it work anyway.
# Do a dry run on the whole patch and don't do anything if part of the patch is
# going to fail (probably too strict unless we exclude ChangeLog).
-# Handle git-diff patches with binary changes
+# Handle git-diff patches with binary delta
use strict;
use warnings;
@@ -75,6 +75,7 @@ sub addDirectoriesIfNeeded($);
sub applyPatch($$;$);
sub checksum($);
sub handleBinaryChange($$);
+sub handleGitBinaryChange($$);
sub isDirectoryEmptyForRemoval($);
sub patch($);
sub removeDirectoriesIfNeeded();
@@ -276,6 +277,39 @@ sub handleBinaryChange($$)
}
}
+sub handleGitBinaryChange($$)
+{
+ my ($fullPath, $contents) = @_;
+
+ my ($binaryChunkType, $binaryChunk, $reverseBinaryChunkType, $reverseBinaryChunk) = decodeGitBinaryPatch($contents, $fullPath);
+ # FIXME: support "delta" type.
+ die "only literal type is supported now" if ($binaryChunkType ne "literal" || $reverseBinaryChunkType ne "literal");
+
+ my $isFileAddition = $contents =~ /\nnew file mode \d+\n/;
+ my $isFileDeletion = $contents =~ /\ndeleted file mode \d+\n/;
+
+ my $originalContents = "";
+ if (open FILE, $fullPath) {
+ die "$fullPath already exists" if $isFileAddition;
+
+ $originalContents = join("", <FILE>);
+ close FILE;
+ }
+ die "Original content of $fullPath mismatches" if $originalContents ne $reverseBinaryChunk;
+
+ if ($isFileDeletion) {
+ scmRemove($fullPath);
+ } else {
+ # Addition or Modification
+ open FILE, ">", $fullPath or die "Failed to open $fullPath.";
+ print FILE $binaryChunk;
+ close FILE;
+ if ($isFileAddition) {
+ scmAdd($fullPath);
+ }
+ }
+}
+
sub isDirectoryEmptyForRemoval($)
{
my ($dir) = @_;
@@ -310,12 +344,14 @@ sub patch($)
my $deletion = 0;
my $addition = 0;
my $isBinary = 0;
+ my $isGitBinary = 0;
$addition = 1 if ($patch =~ /\n--- .+\(revision 0\)\r?\n/ || $patch =~ /\n@@ -0,0 .* @@/) && !exists($copiedFiles{$fullPath});
$deletion = 1 if $patch =~ /\n@@ .* \+0,0 @@/;
$isBinary = 1 if $patch =~ /\nCannot display: file marked as a binary type\./;
+ $isGitBinary = 1 if $patch =~ /\nGIT binary patch\n/;
- if (!$addition && !$deletion && !$isBinary) {
+ if (!$addition && !$deletion && !$isBinary && !$isGitBinary) {
# Standard patch, patch tool can handle this.
if (basename($fullPath) eq "ChangeLog") {
my $changeLogDotOrigExisted = -f "${fullPath}.orig";
@@ -332,6 +368,9 @@ sub patch($)
if ($isBinary) {
# Binary change
handleBinaryChange($fullPath, $patch);
+ } elsif ($isGitBinary) {
+ # Git binary change
+ handleGitBinaryChange($fullPath, $patch);
} elsif ($deletion) {
# Deletion
applyPatch($patch, $fullPath, ["--force"]);
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list