Modified: trunk/Tools/Scripts/VCSUtils.pm (211542 => 211543)
--- trunk/Tools/Scripts/VCSUtils.pm 2017-02-02 01:23:37 UTC (rev 211542)
+++ trunk/Tools/Scripts/VCSUtils.pm 2017-02-02 01:41:24 UTC (rev 211543)
@@ -1736,6 +1736,51 @@
return $patch;
}
+# Removes a leading Subversion header without an associated diff if one exists.
+#
+# This subroutine dies if the specified patch does not begin with an "Index:" line.
+#
+# In SVN 1.9 or newer, "svn diff" of a moved/copied file without post changes always
+# emits a leading header without an associated diff:
+# Index: B.txt
+# ===================================================================
+# (end of file or next header)
+#
+# If the same file has a property change then the patch has the form:
+# Index: B.txt
+# ===================================================================
+# Index: B.txt
+# ===================================================================
+# --- B.txt (revision 1)
+# +++ B.txt (working copy)
+#
+# Property change on B.txt
+# ___________________________________________________________________
+# Added: svn:executable
+# ## -0,0 +1 ##
+# +*
+# \ No newline at end of property
+#
+# We need to apply this function to the ouput of "svn diff" for an addition with history
+# to remove a duplicate header so that svn-apply can apply the resulting patch.
+sub fixSVNPatchForAdditionWithHistory($)
+{
+ my ($patch) = @_;
+
+ $patch =~ /(\r?\n)/;
+ my $lineEnding = $1;
+ my @lines = split(/$lineEnding/, $patch);
+
+ if ($lines[0] !~ /$svnDiffStartRegEx/) {
+ die("First line of SVN diff does not begin with \"Index \": \"$lines[0]\"");
+ }
+ if (@lines <= 2) {
+ return "";
+ }
+ splice(@lines, 0, 2) if $lines[2] =~ /$svnDiffStartRegEx/;
+ return join($lineEnding, @lines);
+}
+
# If possible, returns a ChangeLog patch equivalent to the given one,
# but with the newest ChangeLog entry inserted at the top of the
# file -- i.e. no leading context and all lines starting with "+".
Modified: trunk/Tools/Scripts/svn-create-patch (211542 => 211543)
--- trunk/Tools/Scripts/svn-create-patch 2017-02-02 01:23:37 UTC (rev 211542)
+++ trunk/Tools/Scripts/svn-create-patch 2017-02-02 01:41:24 UTC (rev 211543)
@@ -225,7 +225,8 @@
}
my $patch = "";
- if ($fileData->{modificationType} eq "additionWithHistory") {
+ my $isAdditionWithHistory = $fileData->{modificationType} eq "additionWithHistory";
+ if ($isAdditionWithHistory) {
manufacturePatchForAdditionWithHistory($fileData);
}
@@ -232,21 +233,11 @@
my $diffOptions = diffOptionsForFile($file);
my $escapedFile = escapeSubversionPath($file);
open DIFF, "svn diff --diff-cmd diff -x -$diffOptions '$escapedFile' |" or die;
- my $numTextChunks = 0;
while (<DIFF>) {
- $numTextChunks += 1 if parseChunkRange($_);
$patch .= $_;
}
close DIFF;
- if (!$numTextChunks) {
- # For moved/copied files without post changes SVN 1.9 or greater emits a diff with an empty
- # body as opposed to emitting nothing as in earlier versions of SVN. For example, move file
- # A.txt to B.txt then the diff of B.txt in SVN 1.9 or greater is:
- # Index: B.txt
- # ===================================================================
- # Therefore we ignore emitting such a diff.
- $patch = "";
- }
+ $patch = fixSVNPatchForAdditionWithHistory($patch) if $patch && $isAdditionWithHistory;
if (basename($file) eq "ChangeLog") {
my $changeLogHash = fixChangeLogPatch($patch);
$patch = $changeLogHash->{patch};
Added: trunk/Tools/Scripts/webkitperl/VCSUtils_unittest/fixSVNPatchForAdditionWithHistory.pl (0 => 211543)
--- trunk/Tools/Scripts/webkitperl/VCSUtils_unittest/fixSVNPatchForAdditionWithHistory.pl (rev 0)
+++ trunk/Tools/Scripts/webkitperl/VCSUtils_unittest/fixSVNPatchForAdditionWithHistory.pl 2017-02-02 01:41:24 UTC (rev 211543)
@@ -0,0 +1,288 @@
+#!/usr/bin/perl
+#
+# Copyright (C) 2017 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Unit tests of VCSUtils::fixSVNPatchForAdditionWithHistory().
+
+use strict;
+use warnings;
+
+use Test::More;
+use VCSUtils;
+
+my @testCaseHashRefs = (
+###
+# Test cases that should have no change
+##
+{ # New test
+ diffName => "fixSVNPatchForAdditionWithHistory: [no change] modify file",
+ inputText => <<'END',
+Index: test_file.txt
+===================================================================
+--- test_file.txt (revision 1)
++++ test_file.txt (working copy)
+@@ -1 +1 @@
+-A
++A2
+END
+ expectedReturn => <<'END'
+Index: test_file.txt
+===================================================================
+--- test_file.txt (revision 1)
++++ test_file.txt (working copy)
+@@ -1 +1 @@
+-A
++A2
+END
+},
+{ # New test
+ diffName => "fixSVNPatchForAdditionWithHistory: [no change] delete file",
+ inputText => <<'END',
+Index: test_file.txt
+===================================================================
+--- test_file.txt (revision 1)
++++ test_file.txt (nonexistent)
+@@ -1 +0,0 @@
+-A
+END
+ expectedReturn => <<'END'
+Index: test_file.txt
+===================================================================
+--- test_file.txt (revision 1)
++++ test_file.txt (nonexistent)
+@@ -1 +0,0 @@
+-A
+END
+},
+{ # New test
+ diffName => "fixSVNPatchForAdditionWithHistory: [no change] add svn:executable property",
+ inputText => <<'END',
+Index: test_file.txt
+===================================================================
+--- test_file.txt (revision 1)
++++ test_file.txt (working copy)
+
+Property changes on: test_file.txt
+___________________________________________________________________
+Added: svn:executable
+## -0,0 +1 ##
++*
+\ No newline at end of property
+END
+ expectedReturn => <<'END'
+Index: test_file.txt
+===================================================================
+--- test_file.txt (revision 1)
++++ test_file.txt (working copy)
+
+Property changes on: test_file.txt
+___________________________________________________________________
+Added: svn:executable
+## -0,0 +1 ##
++*
+\ No newline at end of property
+END
+},
+{ # New test
+ diffName => "fixSVNPatchForAdditionWithHistory: [no change] remove svn:executable property",
+ inputText => <<'END',
+Index: test_file.txt
+===================================================================
+--- test_file.txt (revision 1)
++++ test_file.txt (working copy)
+
+Property changes on: test_file.txt
+___________________________________________________________________
+Deleted: svn:executable
+## -1 +0,0 ##
+-*
+\ No newline at end of property
+END
+ expectedReturn => <<'END'
+Index: test_file.txt
+===================================================================
+--- test_file.txt (revision 1)
++++ test_file.txt (working copy)
+
+Property changes on: test_file.txt
+___________________________________________________________________
+Deleted: svn:executable
+## -1 +0,0 ##
+-*
+\ No newline at end of property
+END
+},
+###
+# Moved/copied file using SVN 1.9 syntax
+##
+{ # New test
+ diffName => "fixSVNPatchForAdditionWithHistory: moved/copied file",
+ inputText => <<'END',
+Index: test_file.txt
+===================================================================
+END
+ expectedReturn => ""
+},
+{ # New test
+ diffName => "fixSVNPatchForAdditionWithHistory: moved/copied file with added svn:executable property",
+ inputText => <<'END',
+Index: test_file.txt
+===================================================================
+Index: test_file.txt
+===================================================================
+--- test_file.txt (revision 1)
++++ test_file.txt (working copy)
+
+Property changes on: test_file.txt
+___________________________________________________________________
+Added: svn:executable
+## -0,0 +1 ##
++*
+\ No newline at end of property
+END
+ expectedReturn => <<'END'
+Index: test_file.txt
+===================================================================
+--- test_file.txt (revision 1)
++++ test_file.txt (working copy)
+
+Property changes on: test_file.txt
+___________________________________________________________________
+Added: svn:executable
+## -0,0 +1 ##
++*
+\ No newline at end of property
+END
+},
+{ # New test
+ diffName => "fixSVNPatchForAdditionWithHistory: moved/copied file with removed svn:executable property",
+ inputText => <<'END',
+Index: test_file.txt
+===================================================================
+Index: test_file.txt
+===================================================================
+--- test_file.txt (revision 1)
++++ test_file.txt (working copy)
+
+Property changes on: test_file.txt
+___________________________________________________________________
+Deleted: svn:executable
+## -1 +0,0 ##
+-*
+\ No newline at end of property
+END
+ expectedReturn => <<'END'
+Index: test_file.txt
+===================================================================
+--- test_file.txt (revision 1)
++++ test_file.txt (working copy)
+
+Property changes on: test_file.txt
+___________________________________________________________________
+Deleted: svn:executable
+## -1 +0,0 ##
+-*
+\ No newline at end of property
+END
+},
+{ # New test
+ diffName => "fixSVNPatchForAdditionWithHistory: moved/copied file with added multi-line property",
+ inputText => <<'END',
+Index: test_file.txt
+===================================================================
+Index: test_file.txt
+===================================================================
+--- test_file.txt (revision 1)
++++ test_file.txt (working copy)
+
+Property changes on: test_file.txt
+___________________________________________________________________
+Added: documentation
+## -0,0 +1,3 ##
++A
++long sentence that spans
++multiple lines.
+END
+ expectedReturn => <<'END'
+Index: test_file.txt
+===================================================================
+--- test_file.txt (revision 1)
++++ test_file.txt (working copy)
+
+Property changes on: test_file.txt
+___________________________________________________________________
+Added: documentation
+## -0,0 +1,3 ##
++A
++long sentence that spans
++multiple lines.
+END
+},
+{ # New test
+ diffName => "fixSVNPatchForAdditionWithHistory: moved/copied file with modified multi-line property",
+ inputText => <<'END',
+Index: test_file.txt
+===================================================================
+Index: test_file.txt
+===================================================================
+--- test_file.txt (revision 1)
++++ test_file.txt (working copy)
+
+Property changes on: test_file.txt
+___________________________________________________________________
+Modified: documentation
+## -1,3 +1,3 ##
+-A
++Another
+ long sentence that spans
+ multiple lines.
+END
+ expectedReturn => <<'END'
+Index: test_file.txt
+===================================================================
+--- test_file.txt (revision 1)
++++ test_file.txt (working copy)
+
+Property changes on: test_file.txt
+___________________________________________________________________
+Modified: documentation
+## -1,3 +1,3 ##
+-A
++Another
+ long sentence that spans
+ multiple lines.
+END
+},
+);
+
+my $testCasesCount = @testCaseHashRefs;
+plan(tests => $testCasesCount); # Total number of assertions.
+
+foreach my $testCase (@testCaseHashRefs) {
+ my $testNameStart = "fixSVNPatchForAdditionWithHistory(): $testCase->{diffName}: comparing";
+
+ my $got = VCSUtils::fixSVNPatchForAdditionWithHistory($testCase->{inputText});
+ chomp(my $expectedReturn = $testCase->{expectedReturn});
+
+ is_deeply($got, $expectedReturn, "$testNameStart return value.");
+}
Property changes on: trunk/Tools/Scripts/webkitperl/VCSUtils_unittest/fixSVNPatchForAdditionWithHistory.pl
___________________________________________________________________