X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=git-branch-manager;h=42cea14ff012b56e9309e89b0ac1d27930f71e5d;hb=b45ef7feaffe07370ab0ccf84aead4d9e0eb7c4b;hp=43a80790c932612071974c5124d7ebd5bcff09cf;hpb=675f2d41effb6031f40088fedd6508d97370b84d;p=xonotic%2Fdiv0-gittools.git diff --git a/git-branch-manager b/git-branch-manager index 43a8079..42cea14 100755 --- a/git-branch-manager +++ b/git-branch-manager @@ -9,6 +9,8 @@ my %color = '' => "\e[m", 'outstanding' => "\e[1;33m", 'unmerge' => "\e[1;31m", + 'reject' => "\e[31m", + 'unreject' => "\e[31m", 'merge' => "\e[32m", 'base' => "\e[1;34m", 'previous' => "\e[34m", @@ -16,18 +18,22 @@ my %color = my %html_style = ( - '' => "color: white; background-color: black", - 'outstanding' => "color: white; background-color: yellow", - 'unmerge' => "color: white; background-color: red", - 'merge' => "color: white; background-color: green", - 'base' => "color: white; background-color: lightblue", - 'previous' => "color: white; background-color: blue", + '' => "color: black; background-color: black", + 'outstanding' => "color: black; background-color: yellow", + 'unmerge' => "color: black; background-color: lightred", + 'reject' => "color: black; background-color: red", + 'unreject' => "color: black; background-color: red", + 'merge' => "color: black; background-color: green", + 'base' => "color: black; background-color: lightblue", + 'previous' => "color: black; background-color: blue", ); my %name = ( 'outstanding' => "OUTSTANDING", 'unmerge' => "UNMERGED", + 'reject' => "REJECTED", + 'unreject' => "UNREJECTED", 'merge' => "MERGED", 'base' => "BASE", 'previous' => "PREVIOUS", @@ -70,7 +76,7 @@ my @datefilter = (); my $revprefix = ""; if($datefilter eq 'mergebase') { - chomp($revprefix = check_defined "git-merge-base: $!", backtick 'git', 'merge-base', $master, "HEAD"); + chomp($revprefix = check_defined "git-merge-base: $!", backtick 'git', 'merge-base', $master, $branch); $revprefix .= "^.."; } elsif($datefilter ne '') @@ -78,6 +84,9 @@ elsif($datefilter ne '') @datefilter = "--since=$datefilter"; } +# if set, don't actually merge/revert changes, just mark as such +my $skip = 0; + our $do_commit = 1; my $logcache = undef; sub reset_to_commit($) @@ -97,6 +106,98 @@ sub reset_to_commit($) } } +sub reject_commit($) +{ + # reject == merge but skip + my ($r) = @_; + my $cmsg = ""; + my $author = ""; + my $email = ""; + my $date = ""; + if($do_commit) + { + $logcache = undef; + my $msg = backtick 'git', 'log', '-1', '--pretty=fuller', $r + or die "git-log: $!"; + for(split /\n/, $msg) + { + if(/^Author:\s*(.*) <(.*)>/) + { + $author = $1; + $email = $2; + } + elsif(/^AuthorDate:\s*(.*)/) + { + $date = $1; + } + elsif(/^ (.*)/) + { + $cmsg .= "$1\n"; + } + } + open my $fh, '>', '.commitmsg' + or die ">.commitmsg: $!"; + print $fh "REJECT! $cmsg" . "::stable-branch::reject=$r\n" + or die ">.commitmsg: $!"; + close $fh + or die ">.commitmsg: $!"; + } + local $ENV{GIT_AUTHOR_NAME} = $author; + local $ENV{GIT_AUTHOR_EMAIL} = $email; + local $ENV{GIT_AUTHOR_DATE} = $date; + if($do_commit) + { + run 'git', 'commit', '--allow-empty', '-F', '.commitmsg' + or die "git-commit: $!"; + } +} + +sub unreject_commit($) +{ + # reject == merge but skip + my ($r) = @_; + my $cmsg = ""; + my $author = ""; + my $email = ""; + my $date = ""; + if($do_commit) + { + $logcache = undef; + my $msg = backtick 'git', 'log', '-1', '--pretty=fuller', $r + or die "git-log: $!"; + for(split /\n/, $msg) + { + if(/^Author:\s*(.*) <(.*)>/) + { + $author = $1; + $email = $2; + } + elsif(/^AuthorDate:\s*(.*)/) + { + $date = $1; + } + elsif(/^ (.*)/) + { + $cmsg .= "$1\n"; + } + } + open my $fh, '>', '.commitmsg' + or die ">.commitmsg: $!"; + print $fh "UNREJECT! $cmsg" . "::stable-branch::unreject=$r\n" + or die ">.commitmsg: $!"; + close $fh + or die ">.commitmsg: $!"; + } + local $ENV{GIT_AUTHOR_NAME} = $author; + local $ENV{GIT_AUTHOR_EMAIL} = $email; + local $ENV{GIT_AUTHOR_DATE} = $date; + if($do_commit) + { + run 'git', 'commit', '--allow-empty', '-F', '.commitmsg' + or die "git-commit: $!"; + } +} + sub merge_commit($) { my ($r) = @_; @@ -135,13 +236,18 @@ sub merge_commit($) local $ENV{GIT_AUTHOR_NAME} = $author; local $ENV{GIT_AUTHOR_EMAIL} = $email; local $ENV{GIT_AUTHOR_DATE} = $date; - run 'git', 'cherry-pick', '-n', $r - or run 'git', 'mergetool' - or die "git-mergetool: $!"; + if(!$skip) + { + run 'git', 'cherry-pick', '-n', $r + or run 'git', 'mergetool' + or die "git-mergetool: $!"; + } if($do_commit) { - run 'git', 'commit', '-F', '.commitmsg' - or die "git-commit: $!"; + run 'git', 'commit', '--allow-empty', '-F', '.commitmsg' + or (run 'git', 'mergetool' + and run 'git', 'commit', '--allow-empty', '-F', '.commitmsg') + or die "git-commit: $!"; } } @@ -159,9 +265,10 @@ sub unmerge_commit($) or die "git-log: $!"; for(split /\n/, $msg) { - if(/^Author:\s*(.*)/) + if(/^Author:\s*(.*) <(.*)>/) { $author = $1; + $email = $2; } elsif(/^AuthorDate:\s*(.*)/) { @@ -174,7 +281,7 @@ sub unmerge_commit($) } open my $fh, '>', '.commitmsg' or die ">.commitmsg: $!"; - print $fh "UNMERGE\n$cmsg" . "::stable-branch::unmerge=$r\n" + print $fh "UNMERGE! $cmsg" . "::stable-branch::unmerge=$r\n" or die ">.commitmsg: $!"; close $fh or die ">.commitmsg: $!"; @@ -182,13 +289,18 @@ sub unmerge_commit($) local $ENV{GIT_AUTHOR_NAME} = $author; local $ENV{GIT_AUTHOR_EMAIL} = $email; local $ENV{GIT_AUTHOR_DATE} = $date; - run 'git', 'revert', '-n', $r - or run 'git', 'mergetool' - or die "git-mergetool: $!"; + if(!$skip) + { + run 'git', 'revert', '-n', $r + or run 'git', 'mergetool' + or die "git-mergetool: $!"; + } if($do_commit) { - run 'git', 'commit', '-F', '.commitmsg' - or die "git-commit: $!"; + run 'git', 'commit', '--allow-empty', '-F', '.commitmsg' + or (run 'git', 'mergetool' + and run 'git', 'commit', '--allow-empty', '-F', '.commitmsg') + or die "git-commit: $!"; } } @@ -204,7 +316,11 @@ sub rebase_log($$) for(0..$newbase_id) { - if(!$log->{bitmap}[$_]) + if($log->{bitmap}[$_] < 0) + { + unshift @rlog, ['reject', $log->{order_a}[$_]]; + } + elsif($log->{bitmap}[$_] == 0) { unshift @rlog, ['unmerge', $log->{order_a}[$_]]; } @@ -212,10 +328,14 @@ sub rebase_log($$) for($newbase_id+1 .. @{$log->{order_a}}-1) { - if($log->{bitmap}[$_]) + if($log->{bitmap}[$_] > 0) { push @rlog, ['merge', $log->{order_a}[$_]]; } + elsif($log->{bitmap}[$_] < 0) + { + push @rlog, ['reject', $log->{order_a}[$_]]; + } else { push @outstanding, ['outstanding', $log->{order_a}[$_]]; @@ -271,7 +391,7 @@ sub parse_log() } $cur_commit = $cur_msg = undef; my @commits = (); - for((split /\n/, check_defined "git-log: $!", backtick 'git', 'log', '--topo-order', '--reverse', '--pretty=fuller', @datefilter, "$revprefix"."HEAD"), undef) + for((split /\n/, check_defined "git-log: $!", backtick 'git', 'log', '--topo-order', '--reverse', '--pretty=fuller', @datefilter, "$revprefix$branch"), undef) { if(defined $cur_commit and (not defined $_ or /^commit (\S+)/)) { @@ -296,19 +416,33 @@ sub parse_log() my $data = $logmsg{$_}; if($data =~ /::stable-branch::unmerge=(\S+)/) { + next if not defined $history{$1}; push @logdata, ['unmerge', $1]; } elsif($data =~ /::stable-branch::merge=(\S+)/) { + next if not defined $history{$1}; push @logdata, ['merge', $1]; } + elsif($data =~ /::stable-branch::reject=(\S+)/) + { + next if not defined $history{$1}; + push @logdata, ['reject', $1]; + } + elsif($data =~ /::stable-branch::unreject=(\S+)/) + { + next if not defined $history{$1}; + push @logdata, ['unreject', $1]; + } elsif($data =~ /::stable-branch::reset=(\S+)/) { + next if not defined $history{$1}; @logdata = (); $base = $1; } elsif($data =~ /::stable-branch::rebase=(\S+)/) { + next if not defined $history{$1}; $lastrebase->[0] = 'ignore' if defined $lastrebase; push @logdata, ($lastrebase = ['rebase', $1]); @@ -345,6 +479,14 @@ sub parse_log() { $bitmap[$history{$data}] = 0; } + elsif($cmd eq 'reject') + { + $bitmap[$history{$data}] = -1; + } + elsif($cmd eq 'unreject') + { + $bitmap[$history{$data}] = 0; + } elsif($cmd eq 'rebase') { # the bitmap is fine, but generate a new log from the bitmap @@ -436,7 +578,7 @@ sub run_script(@) { my $l = parse_log(); die "PEBKAC: invalid revision number, cannot reset" - unless defined $l->{order_h}{$r} and not $l->{bitmap}[$l->{order_h}{$r}]; + unless defined $l->{order_h}{$r} and $l->{bitmap}[$l->{order_h}{$r}] == 0; die "PEBKAC: not initialized" unless defined $l->{base}; } @@ -448,12 +590,36 @@ sub run_script(@) { my $l = parse_log(); die "PEBKAC: invalid revision number, cannot reset" - unless defined $l->{order_h}{$r} and $l->{bitmap}[$l->{order_h}{$r}]; + unless defined $l->{order_h}{$r} and $l->{bitmap}[$l->{order_h}{$r}] > 0; die "PEBKAC: not initialized" unless defined $l->{base}; } unmerge_commit $r; } + elsif($cmd eq 'reject') + { + if($pebkac) + { + my $l = parse_log(); + die "PEBKAC: invalid revision number, cannot reset" + unless defined $l->{order_h}{$r} and $l->{bitmap}[$l->{order_h}{$r}] == 0; + die "PEBKAC: not initialized" + unless defined $l->{base}; + } + reject_commit $r; + } + elsif($cmd eq 'unreject') + { + if($pebkac) + { + my $l = parse_log(); + die "PEBKAC: invalid revision number, cannot reset" + unless defined $l->{order_h}{$r} and $l->{bitmap}[$l->{order_h}{$r}] < 0; + die "PEBKAC: not initialized" + unless defined $l->{base}; + } + unreject_commit $r; + } elsif($cmd eq 'outstanding') { } @@ -481,20 +647,31 @@ sub opt_rebase($$) die "PEBKAC: not initialized" unless defined $l->{base}; } - my $msg = backtick 'git', 'log', '-1', '--pretty=fuller', @datefilter, 'HEAD' + my $msg = backtick 'git', 'log', '-1', '--pretty=fuller', @datefilter, $branch or die "git-log: $!"; $msg =~ /^commit (\S+)/s or die "Invalid git log output"; my $commit_id = $1; my $l = rebase_log $r, parse_log(); local $pebkac = 0; - local $do_commit = 0; eval { - reset_to_commit $r; - run_script @{$l->{log}}; - run 'git', 'commit', '--allow-empty', '-m', "::stable-branch::rebase=$r" - or die "git-commit: $!"; + if($cmd eq 'rebase') + { + local $do_commit = 0; + reset_to_commit $r; + run_script @{$l->{log}}; + run 'git', 'commit', '--allow-empty', '-m', "::stable-branch::rebase=$r" + or die "git-commit: $!"; + } + elsif($cmd eq 'resetrebase') + { + run_script ['reset', $r], @{$l->{log}}; + } + elsif($cmd eq 'hardresetrebase') + { + run_script ['hardreset', $r], @{$l->{log}}; + } 1; } or do @@ -570,7 +747,8 @@ sub opt_list($$) { my ($action, $r) = @$_; my $m = $l->{logmsg}->{$r}; - printf "%s%s%s\n", $html_style{$action}, $name{$action}, escapeHTML($r), escapeHTML($cgi_url), escapeHTML($r), escapeHTML($m); + my $m_short = join ' ', map { s/^ (?!git-svn-id)(.)/$1/ ? $_ : () } split /\n/, $m; + printf "%s%s%s\n", $html_style{$action}, $name{$action}, escapeHTML($cgi_url), escapeHTML($r), escapeHTML($r), escapeHTML($m_short); } print "\n"; } @@ -601,6 +779,8 @@ Usage: $0 {--reset|-R} revision-hash $0 {--hardreset|-H} revision-hash $0 {--rebase|-b} revision-hash + $0 {--resetrebase|-B} revision-hash + $0 {--hardresetrebase} revision-hash EOF exit 1; } @@ -631,13 +811,18 @@ my $result = GetOptions( "log|l:s", handler \&opt_list, "outstanding|o:s", handler \&opt_list, "rebase|b=s", handler \&opt_rebase, + "resetrebase|B=s", handler \&opt_rebase, + "hardresetrebase=s", handler \&opt_rebase, + "skip", handler \$skip, "merge|m=s{,}", handler sub { run_script ['merge', $_[1]]; }, "unmerge|u=s{,}", handler sub { run_script ['unmerge', $_[1]]; }, + "reject|r=s{,}", handler sub { run_script ['reject', $_[1]]; }, + "unreject|U=s{,}", handler sub { run_script ['unreject', $_[1]]; }, "reset|R=s", handler sub { run_script ['reset', $_[1]]; }, "hardreset|H=s", handler sub { run_script ['hardreset', $_[1]]; }, "help|h", handler \&opt_help, "histsize|s=i", \$histsize, - "cgi|c=s", \$cgi_url + "cgi=s", \$cgi_url ); if(!$done) {