| Differences between
and this patch
- a/WebKitTools/ChangeLog +16 lines
Lines 1-3 a/WebKitTools/ChangeLog_sec1
1
2009-10-22  Eric Seidel  <eric@webkit.org>
2
3
        Reviewed by NOBODY (OOPS!).
4
5
        svn-apply's fixChangeLogPatch function seems broken
6
        https://bugs.webkit.org/show_bug.cgi?id=30683
7
8
        Share fixChangeLogPatch between svn-apply and svn-create-patch using VCSUtils.pm.
9
        Change fixChangeLogPatch's algorithm to be able to handle patches starting on a line other than 1.
10
11
        * Scripts/VCSUtils.pm:
12
        * Scripts/resolve-ChangeLogs:
13
        * Scripts/svn-apply:
14
        * Scripts/svn-create-patch:
15
        * Scripts/svn-unapply:
16
1
2009-10-23  Eric Seidel  <eric@webkit.org>
17
2009-10-23  Eric Seidel  <eric@webkit.org>
2
18
3
        Reviewed by Eric Carlson.
19
        Reviewed by Eric Carlson.
- a/WebKitTools/Scripts/VCSUtils.pm +62 lines
Lines 53-58 BEGIN { a/WebKitTools/Scripts/VCSUtils.pm_sec1
53
        &makeFilePathRelative
53
        &makeFilePathRelative
54
        &pathRelativeToSVNRepositoryRootForPath
54
        &pathRelativeToSVNRepositoryRootForPath
55
        &svnRevisionForDirectory
55
        &svnRevisionForDirectory
56
        &fixChangeLogPatch
56
    );
57
    );
57
    %EXPORT_TAGS = ( );
58
    %EXPORT_TAGS = ( );
58
    @EXPORT_OK   = ();
59
    @EXPORT_OK   = ();
Lines 268-271 sub makeFilePathRelative($) a/WebKitTools/Scripts/VCSUtils.pm_sec2
268
    return $gitRoot . $path;
269
    return $gitRoot . $path;
269
}
270
}
270
271
272
# The diff(1) command is greedy when matching lines, so a new ChangeLog entry will
273
# have lines of context at the top of a patch when the existing entry has the same
274
# date and author as the new entry.  Alter the ChangeLog patch so
275
# that the added lines ("+") in the patch always start at the beginning of the
276
# patch and there are no initial lines of context.
277
sub fixChangeLogPatch($)
278
{
279
    my $patch = shift; # $patch will only contain patch fragments for ChangeLog.
280
    print "\n\n$patch\n\n";
281
282
    $patch =~ /(\r?\n)/;
283
    my $lineEnding = $1;
284
    my @patchLines = split(/$lineEnding/, $patch);
285
286
    # e.g. 2009-06-03  Eric Seidel  <eric@webkit.org>
287
    my $dateLineRegexpString = '^\+(\d{4}-\d{2}-\d{2})' # Consume the leading '+' and the date.
288
                             . '\s+(.+)\s+' # Consume the name.
289
                             . '<([^<>]+)>$'; # And finally the email address.
290
291
    # Figure out where the patch contents start and stop.
292
    my $patchHeaderIndex;
293
    my $firstContentIndex;
294
    my $trailingContextIndex;
295
    my $dateIndex;
296
    my $patchEndIndex = scalar(@patchLines);
297
    for (my $index = 4; $index < @patchLines; ++$index) { # Start at 4, no need to scan the @@, Index, +++ or --- header lines.
298
        my $line = $patchLines[$index];
299
        if ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@$/) { # e.g. @@ -1,5 +1,18 @@
300
            if ($patchHeaderIndex) {
301
                $patchEndIndex = $index; # We only bother to fix up the first patch fragment.
302
                last;
303
            }
304
            $patchHeaderIndex = $index;
305
        }
306
        $firstContentIndex = $index if (!$firstContentIndex && $line =~ /^\+/); # Important that we skipped +++ so that this doesn't match it.
307
        $dateIndex = $index if ($line =~ /$dateLineRegexpString/);
308
        $trailingContextIndex = $index if ($firstContentIndex && !$trailingContextIndex && $line =~ /^ /);
309
    }
310
    my $contentLineCount = $trailingContextIndex - $firstContentIndex;
311
    my $trailingContextLineCount = $patchEndIndex - $trailingContextIndex;
312
313
    # If we didn't find a date line in the content then this is not a patch we should try and fix.
314
    return if (!$dateIndex);
315
316
    # We only need to do anything if the date line is not the first content line.
317
    return if ($dateIndex == $firstContentIndex);
318
319
    # Write the new patch.
320
    my $totalNewContentLines = $contentLineCount + $trailingContextLineCount;
321
    $patchLines[$patchHeaderIndex] = "@@ -1,$trailingContextLineCount +1,$totalNewContentLines @@"; # Write a new header.
322
    my @repeatedLines = splice(@patchLines, $dateIndex, $trailingContextIndex - $dateIndex); # The date line and all the content after it that diff saw as repeated.
323
    splice(@patchLines, $firstContentIndex, 0, @repeatedLines); # Move the repeated content to the top.
324
    foreach my $line (@repeatedLines) {
325
        $line =~ s/^\+/ /;
326
    }
327
    splice(@patchLines, $trailingContextIndex, $patchEndIndex, @repeatedLines); # Replace trailing context with the repeated content.
328
    splice(@patchLines, $patchHeaderIndex + 1, $firstContentIndex - $patchHeaderIndex - 1); # Remove any leading context.
329
330
    return join($lineEnding, @patchLines) . "\n"; # patch(1) expects an extra trailing newline.
331
}
332
271
1;
333
1;
- a/WebKitTools/Scripts/resolve-ChangeLogs -52 lines
Lines 44-50 sub canonicalRelativePath($); a/WebKitTools/Scripts/resolve-ChangeLogs_sec1
44
sub conflictFiles($);
44
sub conflictFiles($);
45
sub findChangeLog($);
45
sub findChangeLog($);
46
sub findUnmergedChangeLogs();
46
sub findUnmergedChangeLogs();
47
sub fixChangeLogPatch($);
48
sub fixMergedChangeLogs($;@);
47
sub fixMergedChangeLogs($;@);
49
sub fixOneMergedChangeLog($);
48
sub fixOneMergedChangeLog($);
50
sub hasGitUnmergedFiles();
49
sub hasGitUnmergedFiles();
Lines 281-337 sub findUnmergedChangeLogs() a/WebKitTools/Scripts/resolve-ChangeLogs_sec2
281
    return @results;
280
    return @results;
282
}
281
}
283
282
284
sub fixChangeLogPatch($)
285
{
286
    my $patch = shift;
287
    my $contextLineCount = 3;
288
289
    return $patch if $patch !~ /\n@@ -1,(\d+) \+1,(\d+) @@\n( .*\n)+(\+.*\n)+( .*\n){$contextLineCount}$/m;
290
    my ($oldLineCount, $newLineCount) = ($1, $2);
291
    return $patch if $oldLineCount <= $contextLineCount;
292
293
    # The diff(1) command is greedy when matching lines, so a new ChangeLog entry will
294
    # have lines of context at the top of a patch when the existing entry has the same
295
    # date and author as the new entry.  This nifty loop alters a ChangeLog patch so
296
    # that the added lines ("+") in the patch always start at the beginning of the
297
    # patch and there are no initial lines of context.
298
    my $newPatch;
299
    my $lineCountInState = 0;
300
    my $oldContentLineCountReduction = $oldLineCount - $contextLineCount;
301
    my $newContentLineCountWithoutContext = $newLineCount - $oldLineCount - $oldContentLineCountReduction;
302
    my ($stateHeader, $statePreContext, $stateNewChanges, $statePostContext) = (1..4);
303
    my $state = $stateHeader;
304
    foreach my $line (split(/\n/, $patch)) {
305
        $lineCountInState++;
306
        if ($state == $stateHeader && $line =~ /^@@ -1,$oldLineCount \+1,$newLineCount @\@$/) {
307
            $line = "@@ -1,$contextLineCount +1," . ($newLineCount - $oldContentLineCountReduction) . " @@";
308
            $lineCountInState = 0;
309
            $state = $statePreContext;
310
        } elsif ($state == $statePreContext && substr($line, 0, 1) eq " ") {
311
            $line = "+" . substr($line, 1);
312
            if ($lineCountInState == $oldContentLineCountReduction) {
313
                $lineCountInState = 0;
314
                $state = $stateNewChanges;
315
            }
316
        } elsif ($state == $stateNewChanges && substr($line, 0, 1) eq "+") {
317
            # No changes to these lines
318
            if ($lineCountInState == $newContentLineCountWithoutContext) {
319
                $lineCountInState = 0;
320
                $state = $statePostContext;
321
            }
322
        } elsif ($state == $statePostContext) {
323
            if (substr($line, 0, 1) eq "+" && $lineCountInState <= $oldContentLineCountReduction) {
324
                $line = " " . substr($line, 1);
325
            } elsif ($lineCountInState > $contextLineCount && substr($line, 0, 1) eq " ") {
326
                next; # Discard
327
            }
328
        }
329
        $newPatch .= $line . "\n";
330
    }
331
332
    return $newPatch;
333
}
334
335
sub fixMergedChangeLogs($;@)
283
sub fixMergedChangeLogs($;@)
336
{
284
{
337
    my $revisionRange = shift;
285
    my $revisionRange = shift;
- a/WebKitTools/Scripts/svn-apply -52 lines
Lines 74-80 use VCSUtils; a/WebKitTools/Scripts/svn-apply_sec1
74
sub addDirectoriesIfNeeded($);
74
sub addDirectoriesIfNeeded($);
75
sub applyPatch($$;$);
75
sub applyPatch($$;$);
76
sub checksum($);
76
sub checksum($);
77
sub fixChangeLogPatch($);
78
sub gitdiff2svndiff($);
77
sub gitdiff2svndiff($);
79
sub handleBinaryChange($$);
78
sub handleBinaryChange($$);
80
sub isDirectoryEmptyForRemoval($);
79
sub isDirectoryEmptyForRemoval($);
Lines 258-314 sub checksum($) a/WebKitTools/Scripts/svn-apply_sec2
258
    return $checksum;
257
    return $checksum;
259
}
258
}
260
259
261
sub fixChangeLogPatch($)
262
{
263
    my $patch = shift;
264
    my $contextLineCount = 3;
265
266
    return $patch if $patch !~ /\n@@ -1,(\d+) \+1,(\d+) @@\r?\n( .*\r?\n)+(\+.*\r?\n)+( .*\r?\n){$contextLineCount}$/m;
267
    my ($oldLineCount, $newLineCount) = ($1, $2);
268
    return $patch if $oldLineCount <= $contextLineCount;
269
270
    # The diff(1) command is greedy when matching lines, so a new ChangeLog entry will
271
    # have lines of context at the top of a patch when the existing entry has the same
272
    # date and author as the new entry.  This nifty loop alters a ChangeLog patch so
273
    # that the added lines ("+") in the patch always start at the beginning of the
274
    # patch and there are no initial lines of context.
275
    my $newPatch;
276
    my $lineCountInState = 0;
277
    my $oldContentLineCountReduction = $oldLineCount - $contextLineCount;
278
    my $newContentLineCountWithoutContext = $newLineCount - $oldLineCount - $oldContentLineCountReduction;
279
    my ($stateHeader, $statePreContext, $stateNewChanges, $statePostContext) = (1..4);
280
    my $state = $stateHeader;
281
    foreach my $line (split(/\n/, $patch)) {
282
        $lineCountInState++;
283
        if ($state == $stateHeader && $line =~ /^@@ -1,$oldLineCount \+1,$newLineCount @\@$/) {
284
            $line = "@@ -1,$contextLineCount +1," . ($newLineCount - $oldContentLineCountReduction) . " @@";
285
            $lineCountInState = 0;
286
            $state = $statePreContext;
287
        } elsif ($state == $statePreContext && substr($line, 0, 1) eq " ") {
288
            $line = "+" . substr($line, 1);
289
            if ($lineCountInState == $oldContentLineCountReduction) {
290
                $lineCountInState = 0;
291
                $state = $stateNewChanges;
292
            }
293
        } elsif ($state == $stateNewChanges && substr($line, 0, 1) eq "+") {
294
            # No changes to these lines
295
            if ($lineCountInState == $newContentLineCountWithoutContext) {
296
                $lineCountInState = 0;
297
                $state = $statePostContext;
298
            }
299
        } elsif ($state == $statePostContext) {
300
            if (substr($line, 0, 1) eq "+" && $lineCountInState <= $oldContentLineCountReduction) {
301
                $line = " " . substr($line, 1);
302
            } elsif ($lineCountInState > $contextLineCount && substr($line, 0, 1) eq " ") {
303
                next; # Discard
304
            }
305
        }
306
        $newPatch .= $line . "\n";
307
    }
308
309
    return $newPatch;
310
}
311
312
sub gitdiff2svndiff($)
260
sub gitdiff2svndiff($)
313
{
261
{
314
    $_ = shift @_;
262
    $_ = shift @_;
- a/WebKitTools/Scripts/svn-create-patch -52 lines
Lines 61-67 sub findBaseUrl($); a/WebKitTools/Scripts/svn-create-patch_sec1
61
sub findMimeType($;$);
61
sub findMimeType($;$);
62
sub findModificationType($);
62
sub findModificationType($);
63
sub findSourceFileAndRevision($);
63
sub findSourceFileAndRevision($);
64
sub fixChangeLogPatch($);
65
sub generateDiff($$);
64
sub generateDiff($$);
66
sub generateFileList($\%);
65
sub generateFileList($\%);
67
sub isBinaryMimeType($);
66
sub isBinaryMimeType($);
Lines 211-267 sub findSourceFileAndRevision($) a/WebKitTools/Scripts/svn-create-patch_sec2
211
    return ($sourceFile, $sourceRevision);
210
    return ($sourceFile, $sourceRevision);
212
}
211
}
213
212
214
sub fixChangeLogPatch($)
215
{
216
    my $patch = shift;
217
    my $contextLineCount = 3;
218
219
    return $patch if $patch !~ /\n@@ -1,(\d+) \+1,(\d+) @@\n( .*\n)+(\+.*\n)+( .*\n){$contextLineCount}$/m;
220
    my ($oldLineCount, $newLineCount) = ($1, $2);
221
    return $patch if $oldLineCount <= $contextLineCount;
222
223
    # The diff(1) command is greedy when matching lines, so a new ChangeLog entry will
224
    # have lines of context at the top of a patch when the existing entry has the same
225
    # date and author as the new entry.  This nifty loop alters a ChangeLog patch so
226
    # that the added lines ("+") in the patch always start at the beginning of the
227
    # patch and there are no initial lines of context.
228
    my $newPatch;
229
    my $lineCountInState = 0;
230
    my $oldContentLineCountReduction = $oldLineCount - $contextLineCount;
231
    my $newContentLineCountWithoutContext = $newLineCount - $oldLineCount - $oldContentLineCountReduction;
232
    my ($stateHeader, $statePreContext, $stateNewChanges, $statePostContext) = (1..4);
233
    my $state = $stateHeader;
234
    foreach my $line (split(/\n/, $patch)) {
235
        $lineCountInState++;
236
        if ($state == $stateHeader && $line =~ /^@@ -1,$oldLineCount \+1,$newLineCount @\@$/) {
237
            $line = "@@ -1,$contextLineCount +1," . ($newLineCount - $oldContentLineCountReduction) . " @@";
238
            $lineCountInState = 0;
239
            $state = $statePreContext;
240
        } elsif ($state == $statePreContext && substr($line, 0, 1) eq " ") {
241
            $line = "+" . substr($line, 1);
242
            if ($lineCountInState == $oldContentLineCountReduction) {
243
                $lineCountInState = 0;
244
                $state = $stateNewChanges;
245
            }
246
        } elsif ($state == $stateNewChanges && substr($line, 0, 1) eq "+") {
247
            # No changes to these lines
248
            if ($lineCountInState == $newContentLineCountWithoutContext) {
249
                $lineCountInState = 0;
250
                $state = $statePostContext;
251
            }
252
        } elsif ($state == $statePostContext) {
253
            if (substr($line, 0, 1) eq "+" && $lineCountInState <= $oldContentLineCountReduction) {
254
                $line = " " . substr($line, 1);
255
            } elsif ($lineCountInState > $contextLineCount && substr($line, 0, 1) eq " ") {
256
                next; # Discard
257
            }
258
        }
259
        $newPatch .= $line . "\n";
260
    }
261
262
    return $newPatch;
263
}
264
265
sub generateDiff($$)
213
sub generateDiff($$)
266
{
214
{
267
    my ($fileData, $prefix) = @_;
215
    my ($fileData, $prefix) = @_;
- a/WebKitTools/Scripts/svn-unapply -52 lines
Lines 71-77 use lib $FindBin::Bin; a/WebKitTools/Scripts/svn-unapply_sec1
71
use VCSUtils;
71
use VCSUtils;
72
72
73
sub checksum($);
73
sub checksum($);
74
sub fixChangeLogPatch($);
75
sub gitdiff2svndiff($);
74
sub gitdiff2svndiff($);
76
sub patch($);
75
sub patch($);
77
sub revertDirectories();
76
sub revertDirectories();
Lines 158-214 sub checksum($) a/WebKitTools/Scripts/svn-unapply_sec2
158
    return $checksum;
157
    return $checksum;
159
}
158
}
160
159
161
sub fixChangeLogPatch($)
162
{
163
    my $patch = shift;
164
    my $contextLineCount = 3;
165
166
    return $patch if $patch !~ /\n@@ -1,(\d+) \+1,(\d+) @@\n( .*\n)+(\+.*\n)+( .*\n){$contextLineCount}$/m;
167
    my ($oldLineCount, $newLineCount) = ($1, $2);
168
    return $patch if $oldLineCount <= $contextLineCount;
169
170
    # The diff(1) command is greedy when matching lines, so a new ChangeLog entry will
171
    # have lines of context at the top of a patch when the existing entry has the same
172
    # date and author as the new entry.  This nifty loop alters a ChangeLog patch so
173
    # that the added lines ("+") in the patch always start at the beginning of the
174
    # patch and there are no initial lines of context.
175
    my $newPatch;
176
    my $lineCountInState = 0;
177
    my $oldContentLineCountReduction = $oldLineCount - $contextLineCount;
178
    my $newContentLineCountWithoutContext = $newLineCount - $oldLineCount - $oldContentLineCountReduction;
179
    my ($stateHeader, $statePreContext, $stateNewChanges, $statePostContext) = (1..4);
180
    my $state = $stateHeader;
181
    foreach my $line (split(/\n/, $patch)) {
182
        $lineCountInState++;
183
        if ($state == $stateHeader && $line =~ /^@@ -1,$oldLineCount \+1,$newLineCount @\@$/) {
184
            $line = "@@ -1,$contextLineCount +1," . ($newLineCount - $oldContentLineCountReduction) . " @@";
185
            $lineCountInState = 0;
186
            $state = $statePreContext;
187
        } elsif ($state == $statePreContext && substr($line, 0, 1) eq " ") {
188
            $line = "+" . substr($line, 1);
189
            if ($lineCountInState == $oldContentLineCountReduction) {
190
                $lineCountInState = 0;
191
                $state = $stateNewChanges;
192
            }
193
        } elsif ($state == $stateNewChanges && substr($line, 0, 1) eq "+") {
194
            # No changes to these lines
195
            if ($lineCountInState == $newContentLineCountWithoutContext) {
196
                $lineCountInState = 0;
197
                $state = $statePostContext;
198
            }
199
        } elsif ($state == $statePostContext) {
200
            if (substr($line, 0, 1) eq "+" && $lineCountInState <= $oldContentLineCountReduction) {
201
                $line = " " . substr($line, 1);
202
            } elsif ($lineCountInState > $contextLineCount && substr($line, 0, 1) eq " ") {
203
                next; # Discard
204
            }
205
        }
206
        $newPatch .= $line . "\n";
207
    }
208
209
    return $newPatch;
210
}
211
212
sub gitdiff2svndiff($)
160
sub gitdiff2svndiff($)
213
{
161
{
214
    $_ = shift @_;
162
    $_ = shift @_;

Return to Bug 30683