Changeset 45153 in webkit


Ignore:
Timestamp:
Jun 25, 2009 12:45:30 AM (15 years ago)
Author:
eric@webkit.org
Message:

2009-06-25 Eric Seidel <eric@webkit.org>

Reviewed by Tor Arne Vestbø.

Make svn-apply work with Git too
https://bugs.webkit.org/show_bug.cgi?id=26299

Add an --force option to svn-apply and otherwise make svn-apply
exit non-zero when patch application fails.
https://bugs.webkit.org/show_bug.cgi?id=26300

I did not update svn-unapply, because it makes no sense in a Git world.
You don't roll in and out patch files. You make commits and deal with those.
Git users can just git reset --hard to get the same functionality.

  • Scripts/svn-apply:
Location:
trunk/WebKitTools
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebKitTools/ChangeLog

    r45152 r45153  
     12009-06-25  Eric Seidel  <eric@webkit.org>
     2
     3        Reviewed by Tor Arne Vestbø.
     4
     5        Make svn-apply work with Git too
     6        https://bugs.webkit.org/show_bug.cgi?id=26299
     7       
     8        Add an --force option to svn-apply and otherwise make svn-apply
     9        exit non-zero when patch application fails.
     10        https://bugs.webkit.org/show_bug.cgi?id=26300
     11
     12        I did not update svn-unapply, because it makes no sense in a Git world.
     13        You don't roll in and out patch files.  You make commits and deal with those.
     14        Git users can just git reset --hard to get the same functionality.
     15
     16        * Scripts/svn-apply:
     17
    1182009-06-25  Eric Seidel  <eric@webkit.org>
    219
  • trunk/WebKitTools/Scripts/svn-apply

    r39907 r45153  
    88#
    99# 1.  Redistributions of source code must retain the above copyright
    10 #     notice, this list of conditions and the following disclaimer. 
     10#     notice, this list of conditions and the following disclaimer.
    1111# 2.  Redistributions in binary form must reproduce the above copyright
    1212#     notice, this list of conditions and the following disclaimer in the
     
    1414# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
    1515#     its contributors may be used to endorse or promote products derived
    16 #     from this software without specific prior written permission. 
     16#     from this software without specific prior written permission.
    1717#
    1818# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
     
    6060use warnings;
    6161
    62 use Cwd;
    6362use Digest::MD5;
    6463use File::Basename;
     
    6766use MIME::Base64;
    6867use POSIX qw(strftime);
     68
     69use FindBin;
     70use lib $FindBin::Bin;
     71use VCSUtils;
    6972
    7073sub addDirectoriesIfNeeded($);
     
    8083sub svnStatus($);
    8184
     85# These should be replaced by an scm class/module:
     86sub scmKnowsOfFile($);
     87sub scmCopy($$);
     88sub scmAdd($);
     89sub scmRemove($);
     90
     91
    8292# Project time zone for Cupertino, CA, US
    8393my $changeLogTimeZone = "PST8PDT";
     
    8696my $showHelp = 0;
    8797my $reviewer;
    88 if (!GetOptions("merge!" => \$merge, "help!" => \$showHelp, "reviewer=s" => \$reviewer) || $showHelp) {
    89     print STDERR basename($0) . " [-h|--help] [-m|--merge] [-r|--reviewer name] patch1 [patch2 ...]\n";
     98my $force = 0;
     99
     100my $optionParseSuccess = GetOptions(
     101    "merge!" => \$merge,
     102    "help!" => \$showHelp,
     103    "reviewer=s" => \$reviewer,
     104    "force!" => \$force
     105);
     106
     107if (!$optionParseSuccess || $showHelp) {
     108    print STDERR basename($0) . " [-h|--help] [--force] [-m|--merge] [-r|--reviewer name] patch1 [patch2 ...]\n";
    90109    exit 1;
    91110}
     111
     112my $isGit = isGitDirectory(".");
     113my $isSVN = isSVNDirectory(".");
     114$isSVN || $isGit || die "Couldn't determine your version control system.";
    92115
    93116my %removeDirectoryIgnoreList = (
    94117    '.' => 1,
    95118    '..' => 1,
     119    '.git' => 1,
    96120    '.svn' => 1,
    97121    '_svn' => 1,
     
    149173
    150174if ($merge) {
     175    die "--merge is currently only supported for SVN" unless $isSVN;
     176    # How do we handle Git patches applied to an SVN checkout here?
    151177    for my $file (sort keys %versions) {
    152178        print "Getting version $versions{$file} of $file\n";
     
    158184for my $file (keys %copiedFiles) {
    159185    addDirectoriesIfNeeded(dirname($file));
    160     system "svn", "copy", $copiedFiles{$file}, $file;
     186    scmCopy($copiedFiles{$file}, $file);
    161187}
    162188
     
    179205        if (! -e $dir) {
    180206            mkdir $dir or die "Failed to create required directory '$dir' for path '$path'\n";
    181             system "svn", "add", $dir;
     207            scmAdd($dir);
    182208            $checkedDirectories{$dir} = 1;
    183209        }
    184210        elsif (-d $dir) {
    185             my $svnOutput = svnStatus($dir);
    186             if ($svnOutput && $svnOutput =~ m#\?\s+$dir\n#) {
    187                 system "svn", "add", $dir;
     211            # SVN prints "svn: warning: 'directory' is already under version control"
     212            # if you try and add a directory which is already in the repository.
     213            # Git will ignore the add, but re-adding large directories can be sloooow.
     214            # So we check first to see if the directory is under version control first.
     215            if (!scmKnowsOfFile($dir)) {
     216                scmAdd($dir);
    188217            }
    189218            $checkedDirectories{$dir} = 1;
    190219        }
    191220        else {
    192             die "'$dir' is not a directory";
     221            die "'$dir' exists, but is not a directory";
    193222        }
    194223    }
     
    203232    print PATCH $patch;
    204233    close PATCH;
     234
     235    my $exitCode = $? >> 8;
     236    if ($exitCode != 0) {
     237        print "patch -p0 \"$fullPath\" returned $exitCode.  Pass --force to ignore patch failures.\n";
     238        exit($exitCode);
     239    }
    205240}
    206241
     
    291326        print FILE decode_base64($1);
    292327        close FILE;
    293         my $svnOutput = svnStatus($fullPath);
    294         if ($svnOutput && substr($svnOutput, 0, 1) eq "?") {
     328        if (!scmKnowsOfFile($fullPath)) {
    295329            # Addition
    296             system "svn", "add", $fullPath;
    297         } else {
    298             # Modification
    299             print $svnOutput if $svnOutput;
     330            scmAdd($fullPath);
    300331        }
    301332    } else {
    302333        # Deletion
    303         system "svn", "rm", $fullPath;
     334        scmRemove($fullPath);
    304335    }
    305336}
     
    315346            $directoryIsEmpty = 0;
    316347        } else {
    317             my $svnOutput = svnStatus(File::Spec->catdir($dir, $item));
    318             next if $svnOutput && substr($svnOutput, 0, 1) eq "D";
     348            next if (scmWillDeleteFile(File::Spec->catdir($dir, $item)));
    319349            $directoryIsEmpty = 0;
    320350        }
     
    364394            # Deletion
    365395            applyPatch($patch, $fullPath, ["--force"]);
    366             system "svn", "rm", "--force", $fullPath;
     396            scmRemove($fullPath);
    367397        } else {
    368398            # Addition
     
    370400            applyPatch($patch, $fullPath);
    371401            unlink("$fullPath.orig") if -e "$fullPath.orig" && checksum($fullPath) eq checksum("$fullPath.orig");
    372             system "svn", "add", $fullPath;
    373             system "svn", "stat", "$fullPath.orig" if -e "$fullPath.orig";
     402            scmAdd($fullPath);
     403            # What is this for?
     404            system "svn", "stat", "$fullPath.orig" if $isSVN && -e "$fullPath.orig";
    374405        }
    375406    }
     
    380411    foreach my $dir (reverse sort keys %checkedDirectories) {
    381412        if (isDirectoryEmptyForRemoval($dir)) {
    382             my $svnOutput;
    383             open SVN, "svn rm '$dir' |" or die;
    384             # Only save the last line since Subversion lists all changed statuses below $dir
    385             while (<SVN>) {
    386                 $svnOutput = $_;
    387             }
    388             close SVN;
    389             print $svnOutput if $svnOutput;
     413            scmRemove($dir);
    390414        }
    391415    }
     
    442466    return $svnStatus;
    443467}
     468
     469# This could be made into a more general "status" call, except svn and git
     470# have different ideas about "moving" files which might get confusing.
     471sub scmWillDeleteFile($)
     472{
     473    my ($path) = @_;
     474    if ($isSVN) {
     475        my $svnOutput = svnStatus($path);
     476        return 1 if $svnOutput && substr($svnOutput, 0, 1) eq "D";
     477    } elsif ($isGit) {
     478        my $gitOutput = `git diff-index --name-status head -- $path`;
     479        return 1 if $gitOutput && substr($gitOutput, 0, 1) eq "D";
     480    }
     481    return 0;
     482}
     483
     484sub scmKnowsOfFile($)
     485{
     486    my ($path) = @_;
     487    if ($isSVN) {
     488        my $svnOutput = svnStatus($path);
     489        # This will match more than intended.  ? might not be the first field in the status
     490        if ($svnOutput && $svnOutput =~ m#\?\s+$path\n#) {
     491            return 0;
     492        }
     493        # This does not handle errors well.
     494        return 1;
     495    } elsif ($isGit) {
     496        `git ls-files --error-unmatch -- $path`;
     497        my $exitCode = $? >> 8;
     498        return $exitCode == 0;
     499    }
     500}
     501
     502sub scmCopy($$)
     503{
     504    my ($source, $destination) = @_;
     505    if ($isSVN) {
     506        system "svn", "copy", $source, $destination;
     507    } elsif ($isGit) {
     508        system "cp", $source, $destination;
     509        system "git", "add", $destination;
     510    }
     511}
     512
     513sub scmAdd($)
     514{
     515    my ($path) = @_;
     516    if ($isSVN) {
     517        system "svn", "add", $path;
     518    } elsif ($isGit) {
     519        system "git", "add", $path;
     520    }
     521}
     522
     523sub scmRemove($)
     524{
     525    my ($path) = @_;
     526    if ($isSVN) {
     527        # SVN is very verbose when removing directories.  Squelch all output except the last line.
     528        my $svnOutput;
     529        open SVN, "svn rm --force '$path' |" or die "svn rm --force '$path' failed!";
     530        # Only print the last line.  Subversion outputs all changed statuses below $dir
     531        while (<SVN>) {
     532            $svnOutput = $_;
     533        }
     534        close SVN;
     535        print $svnOutput if $svnOutput;
     536    } elsif ($isGit) {
     537        system "git", "rm", "--force", $path;
     538    }
     539}
Note: See TracChangeset for help on using the changeset viewer.