Created
January 27, 2010 08:16
-
-
Save torarnv/287646 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git i/WebKitTools/Scripts/update-webkit w/WebKitTools/Scripts/update-webkit | |
index 7602c41..fd1f3c1 100755 | |
--- i/WebKitTools/Scripts/update-webkit | |
+++ w/WebKitTools/Scripts/update-webkit | |
@@ -73,7 +73,7 @@ push @svnOptions, '-q' if $quiet; | |
# Don't prompt when using svn-1.6 or newer. | |
push @svnOptions, qw(--accept postpone) if isSVNVersion16OrNewer(); | |
-print "Updating OpenSource\n" unless $quiet; | |
+print "Updating from WebKit trunk...\n" unless $quiet; | |
runSvnUpdate() if $isSVN; | |
runGitUpdate() if $isGit; | |
@@ -92,29 +92,127 @@ setupAppleWinEnv() if isAppleWinWebKit(); | |
exit 0; | |
+sub resolveChangeLogs | |
+{ | |
+ my @conflictedChangeLogs = @_; | |
+ print "Attempting to automatically resolve conflicted ChangeLogs...\n"; | |
+ my $resolveChangeLogsPath = File::Spec->catfile(dirname($0), "resolve-ChangeLogs"); | |
+ (system($resolveChangeLogsPath, "--no-warnings", @conflictedChangeLogs) == 0) | |
+ or die "Could not open resolve-ChangeLogs script: $!.\n"; | |
+} | |
+ | |
sub runSvnUpdate() | |
{ | |
open UPDATE, "-|", "svn", "update", @svnOptions or die; | |
my @conflictedChangeLogs; | |
+ my @conflictedOtherFiles; | |
while (my $line = <UPDATE>) { | |
print $line; | |
- $line =~ m/^C\s+(.+?)[\r\n]*$/; | |
- if ($1) { | |
- my $filename = normalizePath($1); | |
- push @conflictedChangeLogs, $filename if basename($filename) eq "ChangeLog"; | |
+ if ($line =~ m/^C\s+(.+?)[\r\n]*$/) { | |
+ my $filename = normalizePath($1); | |
+ if (basename($filename) eq "ChangeLog") { | |
+ push @conflictedChangeLogs, $filename; | |
+ } else { | |
+ push @conflictedOtherFiles, $filename; | |
+ } | |
} | |
} | |
close UPDATE or die; | |
- if (@conflictedChangeLogs) { | |
- print "Attempting to merge conflicted ChangeLogs.\n"; | |
- my $resolveChangeLogsPath = File::Spec->catfile(dirname($0), "resolve-ChangeLogs"); | |
- (system($resolveChangeLogsPath, "--no-warnings", @conflictedChangeLogs) == 0) | |
- or die "Could not open resolve-ChangeLogs script: $!.\n"; | |
+ resolveChangeLogs(@conflictedChangeLogs) if @conflictedChangeLogs; | |
+ | |
+ # TODO: Deal with changelogs that could not be resolved, or other conflicting files | |
+} | |
+ | |
+sub runGitRebase | |
+{ | |
+ my ($ref, $continue) = @_; | |
+ | |
+ my @conflictedChangeLogs; | |
+ my @conflictedOtherFiles; | |
+ | |
+ open REBASE, "-|", "git", "rebase", ($continue ? "--continue" : $ref ) or die; | |
+ while (my $line = <REBASE>) { | |
+ print $line; | |
+ if ($line =~ m/: Merge conflict in (.+?)$/) { | |
+ my $filename = normalizePath($1); | |
+ print "file: $filename\n"; | |
+ if (basename($filename) eq "ChangeLog") { | |
+ push @conflictedChangeLogs, $filename; | |
+ } else { | |
+ push @conflictedOtherFiles, $filename; | |
+ } | |
+ } | |
} | |
+ close REBASE; | |
+ | |
+ return (\@conflictedChangeLogs, \@conflictedOtherFiles); | |
} | |
sub runGitUpdate() | |
{ | |
- system("git", "svn", "rebase") == 0 or die; | |
+ my $unstaged = `git update-index --ignore-submodules --refresh`; | |
+ die "You have unstaged changes, please stash before updating\n" if $?; | |
+ | |
+ my $staged = `git diff-index --cached --name-status -r --ignore-submodules HEAD --`; | |
+ die("You have staged changes, please stash before updating\n") if $staged; | |
+ | |
+ # Resolve the git-svn ref name | |
+ my @refspec = split(/:/, `git config --get svn-remote.svn.fetch`); | |
+ my $svn_ref = @refspec > 1 ? $refspec[1] : undef; | |
+ chomp($svn_ref) if $svn_ref; | |
+ | |
+ my $mirror_ref = undef; | |
+ | |
+ # Check the git config for a possible mirror remote we can use | |
+ my $remotes = `git config --get-regexp "^remote\..+\.url"`; | |
+ if ($remotes =~ /^remote\.(.*?)\.url .*?\/webkit\.git$/mi) { | |
+ my $mirror = $1; | |
+ @refspec = split(/:/, `git config --get remote.$mirror.fetch`); | |
+ if (@refspec > 1) { | |
+ $mirror_ref = $refspec[1]; | |
+ chomp($mirror_ref); | |
+ $mirror_ref =~ s/\*$/master/; | |
+ | |
+ # Fetch latest changes from the mirror first, since it's faster | |
+ system("git", "fetch", $mirror) == 0 or die; | |
+ | |
+ if ($svn_ref) { | |
+ # Fast forward the git-svn ref if the mirror is more recent | |
+ my $cherry = `git cherry $svn_ref $mirror_ref`; | |
+ | |
+ if ($cherry =~ /^[+|-]/) { | |
+ my $latest_mirror_sha = `git rev-parse $mirror_ref`; | |
+ chomp($latest_mirror_sha); | |
+ system("git", "update-ref", $svn_ref, $latest_mirror_sha) == 0 or die; | |
+ } | |
+ } | |
+ } | |
+ } | |
+ | |
+ if ($svn_ref) { | |
+ # Fetch latest changes from SVN (the mirror may be a few minutes old) | |
+ system("git", "svn", "fetch"); | |
+ } | |
+ | |
+ my $rebase_ref = $svn_ref ? $svn_ref : $mirror_ref; | |
+ if (!$rebase_ref) { | |
+ die "Could not find a suitable remote branch to rebase against.\n"; | |
+ } | |
+ | |
+ # Do rebase | |
+ my ($conflictedChangeLogs, $conflictedOtherFiles) = runGitRebase($rebase_ref); | |
+ if (@$conflictedChangeLogs) { | |
+ resolveChangeLogs(@$conflictedChangeLogs); | |
+ ($conflictedChangeLogs, $conflictedOtherFiles) = runGitRebase($rebase_ref, 1); | |
+ } | |
+ | |
+ # Deal with changelogs that failed to resolve, or other conflicting files | |
+ if (@$conflictedChangeLogs or @$conflictedOtherFiles) { | |
+ print "The following files need to be manually resolved:\n"; | |
+ foreach my $file (@$conflictedChangeLogs, @$conflictedOtherFiles) { | |
+ print "\t$file\n"; | |
+ } | |
+ print "\n"; | |
+ } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment