Commit 8816a4ef authored by ddkilzer's avatar ddkilzer

WebKitTools:

        Reviewed by darin.

        http://bugzilla.opendarwin.org/show_bug.cgi?id=9299
        Teach svn-create-patch and friends to work with binary files

        * Scripts/svn-apply: Updated to use base64-encoded text for binary files when applying patches.
        * Scripts/svn-create-patch: Updated to include binary file content as base64-encoded text in patches.
        * Scripts/svn-unapply: Updated to recognize binary files when unapplying patches.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@14718 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 0315a98f
2006-06-04 David Kilzer <ddkilzer@kilzer.net>
Reviewed by darin.
http://bugzilla.opendarwin.org/show_bug.cgi?id=9299
Teach svn-create-patch and friends to work with binary files
* Scripts/svn-apply: Updated to use base64-encoded text for binary files when applying patches.
* Scripts/svn-create-patch: Updated to include binary file content as base64-encoded text in patches.
* Scripts/svn-unapply: Updated to recognize binary files when unapplying patches.
2006-06-03 David Kilzer <ddkilzer@kilzer.net>
Reviewed by Maciej.
......
......@@ -38,11 +38,11 @@
# makes patches generated by "cvs diff" work (increasingly unimportant since we
# use Subversion now).
# ChangeLog patches use --fuzz=3 to prevent rejects.
# Handles binary files (requires patches made by svn-create-patch).
#
# Missing features:
#
# Handle property changes.
# Handle binary files (requires patches made by svn-create-patch).
# Handle file moves (requires patches made by svn-create-patch).
# When doing a removal, check that old file matches what's being removed.
# Notice a patch that's being applied at the "wrong level" and make it work anyway.
......@@ -52,6 +52,7 @@
use strict;
use Cwd;
use Getopt::Long;
use MIME::Base64;
my $merge = 0;
GetOptions("merge" => \$merge);
......@@ -127,42 +128,46 @@ sub patch
my $deletion = 0;
my $addition = 0;
my $isBinary = 0;
$addition = 1 if $patch =~ /\n--- .+\(revision 0\)\n/;
$deletion = 1 if $patch =~ /\n@@ .* \+0,0 @@/;
$isBinary = 1 if $patch =~ /\nCannot display: file marked as a binary type\./;
if (!$addition && !$deletion) {
if (!$addition && !$deletion && !$isBinary) {
# Standard patch, patch tool can handle this.
if ($base eq "ChangeLog") {
my $changeLogDotOrigExisted = -f "${fullpath}.orig";
applyPatch($patch, $fullpath, ["--fuzz=3"]);
unlink("${fullpath}.orig") if (! $changeLogDotOrigExisted);
}
else {
} else {
applyPatch($patch, $fullpath);
}
} else {
# Either a deletion or an addition.
# Either a deletion, an addition or a binary change.
# Change directory down into the directory in question.
chdirAddingDirectoriesIfNeeded($prefix);
if ($deletion) {
if ($isBinary) {
# Binary change
handleBinaryChange($base, $patch);
} elsif ($deletion) {
# Deletion.
system "svn", "rm", $base;
} else {
# Addition.
my $file = $patch;
if ($file !~ s/^(.*\n)*@@[^\n]+@@\n//) {
# Empty file.
$file = "";
my $contents = $patch;
if ($contents !~ s/^(.*\n)*@@[^\n]+@@\n//) {
# Empty contents.
$contents = "";
} else {
# Non-empty file: Remove leading + signs.
$file =~ s/^\+//;
$file =~ s/\n\+/\n/g;
# Non-empty contents: Remove leading + signs.
$contents =~ s/^\+//;
$contents =~ s/\n\+/\n/g;
}
open FILE, ">", $base or die;
print FILE $file;
print FILE $contents;
close FILE;
system "svn", "add", "$base";
}
......@@ -171,6 +176,30 @@ sub patch
}
}
sub handleBinaryChange
{
my ($base, $contents) = @_;
if ($contents =~ m#((\n[A-Za-z0-9+/]{76})+\n[A-Za-z0-9+/=]{4,76}\n)\n#) {
# Addition or Modification
open FILE, ">", $base or die;
print FILE decode_base64($1);
close FILE;
open SVN, "svn stat '$base' |" or die;
my $svnStatus = <SVN>;
close SVN;
if (substr($svnStatus, 0 ,1) eq "?") {
# Addition
system "svn", "add", "$base";
} else {
# Modification
print $svnStatus;
}
} else {
# Deletion
system "svn", "rm", "$base";
}
}
sub chdirAddingDirectoriesIfNeeded
{
my $path = shift;
......
#!/usr/bin/perl -w
# Copyright (C) 2005 Apple Computer, Inc. All rights reserved.
# Copyright (C) 2005, 2006 Apple Computer, Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
......@@ -32,11 +32,11 @@
#
# Uses the real diff, not svn's built-in diff.
# Always passes "-p" to diff so it will try to include function names.
# Handles binary files (encoded as a base64 chunk of text).
#
# Missing features:
#
# Sort the diffs, since svn emits them in a seemingly-random order.
# Handle binary files (some text form of the binary file).
# Handle moved files.
use strict;
......@@ -44,8 +44,10 @@ use Cwd;
use Getopt::Long;
use Time::gmtime;
use File::stat;
use File::Spec;
use POSIX qw(:errno_h);
use Config;
use MIME::Base64;
my $startDir = getcwd();
my %paths;
......@@ -115,13 +117,18 @@ sub diff
chdir $dir or die;
open DIFF, "svn diff --diff-cmd diff -x -uNp '$base' |" or die;
my $indexPath;
my $binaryPath;
while (<DIFF>) {
if (/^Index: (.*)/) {
# New patch just started
$indexPath = $1;
if ($dir ne ".") {
$indexPath = "$dir/$indexPath";
s/Index: .*/Index: $indexPath/;
}
# Output encoded binary contents of last patch before beginning of next patch
outputBinaryContent(File::Spec->abs2rel($binaryPath, $dir)) if ($binaryPath);
undef $binaryPath;
}
if ($indexPath) {
# Fix paths on diff, ---, and +++ lines to match preceding Index: line.
......@@ -129,13 +136,36 @@ sub diff
s/^--- \S+/--- $indexPath/;
s/^\+\+\+ \S+/+++ $indexPath/ && undef $indexPath;
}
if ($binaryPath) {
# Fix path on "Property changes on:" line to match preceding Index: line.
s/^(Property changes on:) \S+/$1 $indexPath/;
}
$binaryPath = $indexPath if (/^Cannot display: file marked as a binary type\.$/);
print;
}
close DIFF;
# Output encoded binary contents if the last patch was binary
outputBinaryContent(File::Spec->abs2rel($binaryPath, $dir)) if ($binaryPath);
chdir $startDir or die;
print STDERR $errors;
}
# Outputs binary content as encoded text
sub outputBinaryContent
{
my ($path) = @_;
# Deletion
return if (! -e $path);
# Addition or Modification
my $buffer;
open BINARY, $path or die;
while (read(BINARY, $buffer, 60*57)) {
print encode_base64($buffer);
}
close BINARY;
print "\n";
}
# Generate the diff for each passed file or directory.
for my $path (sort keys %paths) {
diff($path);
......
......@@ -36,11 +36,11 @@
# makes patches generated by "cvs diff" work (increasingly unimportant since we
# use Subversion now).
# ChangeLog patches use --fuzz=3 to prevent rejects.
# Handles binary files (requires patches made by svn-create-patch).
#
# Missing features:
#
# Handle property changes.
# Handle binary files (requires patches made by svn-create-patch).
# Handle file moves (requires patches made by svn-create-patch).
# Use version numbers in the patch file and do a 3-way merge.
# When reversing an addition, check that the file matches what's being removed.
......@@ -97,35 +97,34 @@ sub patch
my $deletion = 0;
my $addition = 0;
my $isBinary = 0;
$addition = 1 if $patch =~ /\n--- .+\(revision 0\)\n/;
$deletion = 1 if $patch =~ /\n@@ .* \+0,0 @@/;
$isBinary = 1 if $patch =~ /\nCannot display: file marked as a binary type\./;
if (!$addition && !$deletion) {
if (!$addition && !$deletion && !$isBinary) {
# Standard patch, patch tool can handle this.
if ($base eq "ChangeLog") {
my $changeLogDotOrigExisted = -f "${fullpath}.orig";
unapplyPatch($patch, $fullpath, ["--fuzz=3"]);
unlink("${fullpath}.orig") if (! $changeLogDotOrigExisted);
}
else {
} else {
unapplyPatch($patch, $fullpath);
}
} else {
# Either a deletion or an addition.
# Either a deletion, an addition or a binary change.
# Change directory down into the directory in question.
if ($prefix) {
chdir $prefix or die "Failed to chdir to $prefix";
}
if ($deletion) {
# Reverse a deletion.
system "svn", "revert", "$base";
} else {
# Reverse an addition.
system "svn", "rm", "--force", $base;
}
# Reverse change by deleting current copy if it exists first
unlink($base) if (-e $base);
# Then run svn revert
system "svn", "revert", "$base";
chdir $startDir or die;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment