2525if (@custom_mark ) { @mark = @custom_mark ; }
2626
2727sub read_revs_short {
28- my ($bottom , $top ) = @_ ;
28+ my (@args ) = @_ ;
2929 my @revs ;
30- open (REVS, ' -|' , qw( git rev-list --no-merges) , " $bottom .. $top " )
30+ open (REVS, ' -|' , qw( git rev-list --no-merges) , @args )
3131 or die ;
3232 while (<REVS>) {
3333 chomp ;
@@ -52,12 +52,45 @@ sub read_revs {
5252 return @revs ;
5353}
5454
55+ sub rebase_marker {
56+ my ($topic , $stage , $in_next ) = @_ ;
57+ my @not_in_topic = read_revs_short(' ^master' , " ^$topic " , " $stage " );
58+
59+ # @$in_next is what is in $stage but not in $base.
60+ # @not_in_topic excludes what came from $topic from @$in_next.
61+ # $topic can be rebased if these two set matches, because
62+ # no commits in $topic has been merged to $stage yet.
63+ if (@not_in_topic != @$in_next ) {
64+ # we cannot rebase it anymore
65+ return ' ' ;
66+ }
67+ if (read_revs_short(' master' , " ^$topic " )) {
68+ # there is something that is in master but not in topic.
69+ return ' ^' ;
70+ }
71+ # topic is up to date.
72+ return ' *' ;
73+ }
74+
75+ sub describe_topic {
76+ my ($topic ) = @_ ;
77+ open (CONF, ' -|' , qw( git repo-config --get) ,
78+ " branch.$topic .description" )
79+ or die ;
80+ my $it = join (' ' ,<CONF>);
81+ close (CONF);
82+ chomp ($it );
83+ if ($it ) {
84+ wrap_print(" $it " );
85+ }
86+ }
87+
5588sub wrap_print {
56- my ($prefix , $ string ) = @_ ;
89+ my ($string ) = @_ ;
5790 format STDOUT =
58- @ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
59- $prefix , $ string
60- ~~^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
91+ ~ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
92+ $string
93+ ~~^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
6194 $string
6295.
6396 write ;
@@ -69,6 +102,8 @@ sub wrap_print {
69102 " refs/heads/$topic_pattern " )
70103 or die ;
71104
105+ my @in_next = read_revs_short(' ^master' , $stage [0]);
106+
72107while (<TOPIC>) {
73108 chomp ;
74109 my ($sha1 , $date , $topic ) = m | ^([0-9a-f]{40})\s (.*?)\s refs/heads/(.+)$ |
@@ -78,18 +113,21 @@ sub wrap_print {
78113
79114 my %revs = map { $_ ->[0] => $_ } @revs ; # fast index
80115 for (my $i = 0; $i < @stage ; $i ++) {
81- for my $item (read_revs_short($stage [$i ], $sha1 )) {
116+ for my $item (read_revs_short("^ $stage [$i ]" , $sha1 )) {
82117 if (exists $revs {$item }) {
83118 $revs {$item }[2] &= ~(1 << $i );
84119 }
85120 }
86121 }
87- print "* $topic ($date )\n ";
122+
123+ print '*' . rebase_marker($sha1 , $stage [0], \@ in_next);
124+ print " $topic ($date )\n ";
125+ describe_topic($topic );
88126 for my $item (@revs ) {
89127 my $mark = $item ->[2];
90128 if ($mark < @mark ) {
91129 $mark = $mark [$mark ];
92130 }
93- wrap_print($mark , $item ->[1]);
131+ wrap_print(" $mark $item ->[1]" );
94132 }
95133}
0 commit comments