Changeset 87641 in webkit


Ignore:
Timestamp:
May 29, 2011 12:38:46 PM (13 years ago)
Author:
dbates@webkit.org
Message:

2011-05-29 Daniel Bates <dbates@rim.com>

Reviewed by David Kilzer.

REGRESSION (r86515): svn-apply ignores diffs that omit line count in chunk range
https://bugs.webkit.org/show_bug.cgi?id=61162

Fixes an issue where svn-apply may ignore a diff that contains a chunk range line
that omits a line count. In particular, the chunk range regular expression does
not match a chunk range line that omits a line count. GNU diff(1) will omit the
line count in the chunk range if the line count is exactly 1. For example, appending
a new line to the end of an existing file F that contains exactly one line of text will
be represented in a diff with a chunk range line that omits the line count for F.

  • Scripts/VCSUtils.pm: (parseChunkRange): Added.
  • Scripts/webkitperl/VCSUtils_unittest/parseChunkRange.pl: Added.
  • Scripts/webkitperl/VCSUtils_unittest/parseDiff.pl:
    • Added unit test "Git: Append new line to the end of an existing file".
Location:
trunk/Tools
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Tools/ChangeLog

    r87626 r87641  
     12011-05-29  Daniel Bates  <dbates@rim.com>
     2
     3        Reviewed by David Kilzer.
     4
     5        REGRESSION (r86515): svn-apply ignores diffs that omit line count in chunk range
     6        https://bugs.webkit.org/show_bug.cgi?id=61162
     7
     8        Fixes an issue where svn-apply may ignore a diff that contains a chunk range line
     9        that omits a line count. In particular, the chunk range regular expression does
     10        not match a chunk range line that omits a line count. GNU diff(1) will omit the
     11        line count in the chunk range if the line count is exactly 1. For example, appending
     12        a new line to the end of an existing file F that contains exactly one line of text will
     13        be represented in a diff with a chunk range line that omits the line count for F.
     14
     15        * Scripts/VCSUtils.pm:
     16          (parseChunkRange): Added.
     17        * Scripts/webkitperl/VCSUtils_unittest/parseChunkRange.pl: Added.
     18        * Scripts/webkitperl/VCSUtils_unittest/parseDiff.pl:
     19          - Added unit test "Git: Append new line to the end of an existing file".
     20
    1212011-05-28  Adam Barth  <abarth@webkit.org>
    222
  • trunk/Tools/Scripts/VCSUtils.pm

    r86515 r87641  
    6969        &mergeChangeLogs
    7070        &normalizePath
     71        &parseChunkRange
    7172        &parseFirstEOL
    7273        &parsePatch
     
    99100my $changeLogTimeZone = "PST8PDT";
    100101
    101 my $chunkRangeRegEx = qr#^\@\@ -(\d+),(\d+) \+\d+,(\d+) \@\@#; # e.g. "@@ -2,6 +2,18 @@" or "@@ -2,6 +2,18 @@ foo()"
    102102my $gitDiffStartRegEx = qr#^diff --git (\w/)?(.+) (\w/)?([^\r\n]+)#;
    103103my $svnDiffStartRegEx = qr#^Index: ([^\r\n]+)#;
     
    484484    }
    485485    return $eol;
     486}
     487
     488# Parses a chunk range line into its components.
     489#
     490# A chunk range line has the form: @@ -L_1,N_1 +L_2,N_2 @@, where the pairs (L_1, N_1),
     491# (L_2, N_2) are ranges that represent the starting line number and line count in the
     492# original file and new file, respectively.
     493#
     494# Note, some versions of GNU diff may omit the comma and trailing line count (e.g. N_1),
     495# in which case the omitted line count defaults to 1. For example, GNU diff may output
     496# @@ -1 +1 @@, which is equivalent to @@ -1,1 +1,1 @@.
     497#
     498# This subroutine returns undef if given an invalid or malformed chunk range.
     499#
     500# Args:
     501#   $line: the line to parse.
     502#
     503# Returns $chunkRangeHashRef
     504#   $chunkRangeHashRef: a hash reference representing the parts of a chunk range, as follows--
     505#     startingLine: the starting line in the original file.
     506#     lineCount: the line count in the original file.
     507#     newStartingLine: the new starting line in the new file.
     508#     newLineCount: the new line count in the new file.
     509sub parseChunkRange($)
     510{
     511    my ($line) = @_;
     512    my $chunkRangeRegEx = qr#^\@\@ -(\d+)(,(\d+))? \+(\d+)(,(\d+))? \@\@#;
     513    if ($line !~ /$chunkRangeRegEx/) {
     514        return;
     515    }
     516    my %chunkRange;
     517    $chunkRange{startingLine} = $1;
     518    $chunkRange{lineCount} = defined($2) ? $3 : 1;
     519    $chunkRange{newStartingLine} = $4;
     520    $chunkRange{newLineCount} = defined($5) ? $6 : 1;
     521    return \%chunkRange;
    486522}
    487523
     
    906942        if ($line !~ $headerStartRegEx) {
    907943            # Then we are in the body of the diff.
    908             $numTextChunks += $line =~ /$chunkRangeRegEx/;
    909             if ($indexPathEOL && $line !~ /$chunkRangeRegEx/) {
     944            my $isChunkRange = defined(parseChunkRange($line));
     945            $numTextChunks += 1 if $isChunkRange;
     946            if ($indexPathEOL && !$isChunkRange) {
    910947                # The chunk range is part of the body of the diff, but its line endings should't be
    911948                # modified or patch(1) will complain. So, we only modify non-chunk range lines.
     
    15011538
    15021539    # Update the initial chunk range.
    1503     if ($lines[$chunkStartIndex - 1] !~ /$chunkRangeRegEx/) {
     1540    my $chunkRangeHashRef = parseChunkRange($lines[$chunkStartIndex - 1]);
     1541    if (!$chunkRangeHashRef) {
    15041542        # FIXME: Handle errors differently from ChangeLog files that
    15051543        # are okay but should not be altered. That way we can find out
     
    15081546        return \%changeLogHashRef;
    15091547    }
    1510     my $oldSourceLineCount = $2;
    1511     my $oldTargetLineCount = $3;
     1548    my $oldSourceLineCount = $chunkRangeHashRef->{lineCount};
     1549    my $oldTargetLineCount = $chunkRangeHashRef->{newLineCount};
    15121550
    15131551    my $sourceLineCount = $oldSourceLineCount + @overlappingLines - $deletedLineCount;
  • trunk/Tools/Scripts/webkitperl/VCSUtils_unittest/parseDiff.pl

    r86515 r87641  
    995995    expectedNextLine => undef,
    996996},
     997{
     998    # New test
     999    diffName => "Git: Append new line to the end of an existing file",
     1000    inputText => <<'END',
     1001diff --git a/foo b/foo
     1002index 863339f..db418b2 100644
     1003--- a/foo
     1004+++ b/foo
     1005@@ -1 +1,2 @@
     1006 Passed
     1007+
     1008END
     1009    expectedReturn => [
     1010[{
     1011    svnConvertedText =>  <<'END',
     1012Index: foo
     1013index 863339f..db418b2 100644
     1014--- foo
     1015+++ foo
     1016@@ -1 +1,2 @@
     1017 Passed
     1018+
     1019END
     1020    indexPath => "foo",
     1021    isGit => 1,
     1022    numTextChunks => 1,
     1023}],
     1024undef],
     1025    expectedNextLine => undef,
     1026},
    9971027{   # New test
    9981028    diffName => "Git: new file",
Note: See TracChangeset for help on using the changeset viewer.