Skip to content

Instantly share code, notes, and snippets.

@torarnv
Created January 27, 2010 08:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save torarnv/287646 to your computer and use it in GitHub Desktop.
Save torarnv/287646 to your computer and use it in GitHub Desktop.
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