call merge tool properly
[xonotic/div0-gittools.git] / git-branch-manager
index cb6a3abb2b87cb0084a6d801798750e4bb8d68a3..2d319857a9024d2ef0e470442c09873601785af4 100755 (executable)
@@ -14,6 +14,16 @@ my %color =
        'previous' => "\e[34m",
 );
 
+my %html_style =
+(
+       '' => "color: black; background-color: black",
+       'outstanding' => "color: black; background-color: yellow",
+       'unmerge' => "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",
@@ -47,16 +57,20 @@ sub run(@)
 }
 
 my $width = ($ENV{COLUMNS} || backtick 'tput', 'cols' || 80);
-chomp(my $branch = backtick 'git', 'symbolic-ref', 'HEAD');
-       $branch =~ s/^refs\/heads\///
-               or die "Not in a branch";
+my $branch = $ENV{GIT_BRANCH};
+if(not $branch)
+{
+       chomp($branch = backtick 'git', 'symbolic-ref', 'HEAD');
+               $branch =~ s/^refs\/heads\///
+                       or die "Not in a branch";
+}
 chomp(my $master = (backtick 'git', 'config', '--get', "branch-manager.$branch.master" or 'master'));
 chomp(my $datefilter = (backtick 'git', 'config', '--get', "branch-manager.$branch.startdate" or ''));
 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 '')
@@ -64,6 +78,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($)
@@ -121,13 +138,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: $!";
+                       or (run 'git', 'mergetool'
+                               and run 'git', 'commit', '-F', '.commitmsg')
+                                       or die "git-commit: $!";
        }
 }
 
@@ -160,7 +182,7 @@ sub unmerge_commit($)
                }
                open my $fh, '>', '.commitmsg'
                        or die ">.commitmsg: $!";
-               print $fh "UNMERGE\n$cmsg" . "::stable-branch::merge=$r\n"
+               print $fh "UNMERGE\n$cmsg" . "::stable-branch::unmerge=$r\n"
                        or die ">.commitmsg: $!";
                close $fh
                        or die ">.commitmsg: $!";
@@ -168,13 +190,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: $!";
+                       or (run 'git', 'mergetool'
+                               and run 'git', 'commit', '-F', '.commitmsg')
+                                       or die "git-commit: $!";
        }
 }
 
@@ -257,7 +284,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+)/))
                {
@@ -467,7 +494,7 @@ 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";
@@ -492,7 +519,19 @@ sub opt_rebase($$)
        };
 }
 
+sub escapeHTML {
+         my ($toencode,$newlinestoo) = @_;
+         return undef unless defined($toencode);
+         $toencode =~ s{&}{&}gso;
+         $toencode =~ s{<}{&lt;}gso;
+         $toencode =~ s{>}{&gt;}gso;
+        $toencode =~ s{"}{&quot;}gso;
+         return $toencode;
+}
+
+
 my $histsize = 20;
+my $cgi_url = undef;
 sub opt_list($$)
 {
        ++$done;
@@ -537,13 +576,28 @@ sub opt_list($$)
                my %seen = ();
                @l = reverse grep { !$seen{$_->[1]}++ && !$l->{bitmap}->[$l->{order_h}->{$_->[1]}] } reverse map { [$_->[1], $_->[2]] } sort { $l->{order_h}{$a->[2]} <=> $l->{order_h}{$b->[2]} or $a->[0] <=> $b->[0] } map { [$_, $l[$_]->[0], $l[$_]->[1]] } 0..(@l-1);
        }
-       for(@l)
+       if(defined $cgi_url)
        {
-               my ($action, $r) = @$_;
-               my $m = $l->{logmsg}->{$r};
-               my $m_short = join ' ', map { s/^    (?!git-svn-id)(.)/$1/ ? $_ : () } split /\n/, $m;
-               $m_short = substr $m_short, 0, $width - 11 - 1 - 40 - 1;
-               printf "%s%-11s%s %s %s\n", $color{$action}, $name{$action}, $color{''}, $r, $m_short;
+               print "Content-Type: text/html\n\n<table border>\n";
+               for(@l)
+               {
+                       my ($action, $r) = @$_;
+                       my $m = $l->{logmsg}->{$r};
+                       my $m_short = join ' ', map { s/^    (?!git-svn-id)(.)/$1/ ? $_ : () } split /\n/, $m;
+                       printf "<tr style=\"%s\"><td>%s</td><td><a href=\"%s%s\">%s</a></td><td style=\"white-space: pre\">%s</td></tr>\n", $html_style{$action}, $name{$action}, escapeHTML($cgi_url), escapeHTML($r), escapeHTML($r), escapeHTML($m_short);
+               }
+               print "</table>\n";
+       }
+       else
+       {
+               for(@l)
+               {
+                       my ($action, $r) = @$_;
+                       my $m = $l->{logmsg}->{$r};
+                       my $m_short = join ' ', map { s/^    (?!git-svn-id)(.)/$1/ ? $_ : () } split /\n/, $m;
+                       $m_short = substr $m_short, 0, $width - 11 - 1 - 40 - 1;
+                       printf "%s%-11s%s %s %s\n", $color{$action}, $name{$action}, $color{''}, $r, $m_short;
+               }
        }
 }
 
@@ -591,12 +645,14 @@ my $result = GetOptions(
        "log|l:s", handler \&opt_list,
        "outstanding|o:s", handler \&opt_list,
        "rebase|b=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]]; },
        "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
+       "histsize|s=i", \$histsize,
+       "cgi=s", \$cgi_url
 );
 if(!$done)
 {