#!/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
# Paths from Index: lines are used rather than the paths on the patch lines, which
# makes patches generated by "cvs diff" work (increasingly unimportant since we
# use Subversion now).
+# ChangeLog patches use --fuzz=3 to prevent rejects.
#
# Missing features:
#
# 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.
-# Do a smart merge on ChangeLog files instead of just doing a normal patch.
# 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 do the ChangeLog thing).
patch($patch);
}
+sub applyPatch
+{
+ my ($patch, $fullpath, $options) = @_;
+ $options = [] if (! $options);
+ my $command = "patch " . join(" ", "-p0", @{$options});
+ open PATCH, "| $command" or die "Failed to patch $fullpath\n";
+ print PATCH $patch;
+ close PATCH;
+}
+
sub patch
{
my ($patch) = @_;
if (!$addition && !$deletion) {
# Standard patch, patch tool can handle this.
- open PATCH, "| patch -p0" or die "Failed to patch $fullpath\n";
- print PATCH $patch;
- close PATCH;
+ if ($base eq "ChangeLog") {
+ my $changeLogDotOrigExisted = -f "${fullpath}.orig";
+ applyPatch($patch, $fullpath, ["--fuzz=3"]);
+ unlink("${fullpath}.orig") if (! $changeLogDotOrigExisted);
+ }
+ else {
+ applyPatch($patch, $fullpath);
+ }
} else {
# Either a deletion or an addition.
# Paths from Index: lines are used rather than the paths on the patch lines, which
# makes patches generated by "cvs diff" work (increasingly unimportant since we
# use Subversion now).
+# ChangeLog patches use --fuzz=3 to prevent rejects.
#
# Missing features:
#
# 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.
# Notice a patch that's being unapplied at the "wrong level" and make it work anyway.
-# Do a smart merge on ChangeLog files instead of just doing a normal patch.
# 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 do the ChangeLog thing).
}
patch($patch);
+sub unapplyPatch
+{
+ my ($patch, $fullpath, $options) = @_;
+ $options = [] if (! $options);
+ my $command = "patch " . join(" ", "-p0", "-R", @{$options});
+ open PATCH, "| $command" or die "Failed to patch $fullpath\n";
+ print PATCH $patch;
+ close PATCH;
+}
+
sub patch
{
my ($patch) = @_;
return if !$patch;
+ $patch =~ m|^Index: ((([^/\n]*/)*)([^/\n]+))| or die "Failed to find Index: in \"$patch\"\n";
+ my ($fullpath, $prefix, $base) = ($1, $2, $4);
+
my $deletion = 0;
my $addition = 0;
if (!$addition && !$deletion) {
# Standard patch, patch tool can handle this.
- open PATCH, "| patch -p0 -R" or die;
- print PATCH $patch;
- close PATCH;
+ if ($base eq "ChangeLog") {
+ my $changeLogDotOrigExisted = -f "${fullpath}.orig";
+ unapplyPatch($patch, $fullpath, ["--fuzz=3"]);
+ unlink("${fullpath}.orig") if (! $changeLogDotOrigExisted);
+ }
+ else {
+ unapplyPatch($patch, $fullpath);
+ }
} else {
# Either a deletion or an addition.
# Change directory down into the directory in question.
- $patch =~ m|^Index: (([^/\n]*/)*)([^/\n]+)| or die "Failed to find Index: in patch";
- my $prefix = $1;
- my $base = $3;
if ($prefix) {
chdir $prefix or die "Failed to chdir to $prefix";
}
if ($deletion) {
# Reverse a deletion.
- system "svn", "add", "$base";
- my $file = $patch;
- if ($file !~ s/^(.*\n)*@@[^\n]+@@\n//) {
- # Empty file.
- $file = "";
- } else {
- # Non-empty file: Remove leading - signs.
- $file =~ s/^-//;
- $file =~ s/\n-/\n/g;
- }
- open FILE, ">", $base or die;
- print FILE $file;
- close FILE;
+ system "svn", "revert", "$base";
} else {
# Reverse an addition.
system "svn", "rm", "--force", $base;