From 606e7205a3ff52247a0925fe5836b732836396c3 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 8 Dec 2006 14:16:24 -0800 Subject: [PATCH] Now git-topic is a bit more usable and close enough to TO script. --- TO | 5 +++-- git-topic.perl | 56 ++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 50 insertions(+), 11 deletions(-) diff --git a/TO b/TO index 169f1fab29..ad00b30651 100755 --- a/TO +++ b/TO @@ -111,8 +111,9 @@ Using Topic Branches Some important disciplines first. - * Once a topic branch forks from "master", never merge "master" - updates into the topic branch. + * Once a topic branch forks from "master", avoid merging "master" + updates into the topic branch unless necessary to resolve conflicts + early. * Once a topic branch is fully cooked and merged into "master", delete it. If you need to build on top of it to correct diff --git a/git-topic.perl b/git-topic.perl index 4c2a83db16..2a9c70231f 100755 --- a/git-topic.perl +++ b/git-topic.perl @@ -25,9 +25,9 @@ if (@custom_stage) { @stage = @custom_stage; } if (@custom_mark) { @mark = @custom_mark; } sub read_revs_short { - my ($bottom, $top) = @_; + my (@args) = @_; my @revs; - open(REVS, '-|', qw(git rev-list --no-merges), "$bottom..$top") + open(REVS, '-|', qw(git rev-list --no-merges), @args) or die; while () { chomp; @@ -52,12 +52,45 @@ sub read_revs { return @revs; } +sub rebase_marker { + my ($topic, $stage, $in_next) = @_; + my @not_in_topic = read_revs_short('^master', "^$topic", "$stage"); + + # @$in_next is what is in $stage but not in $base. + # @not_in_topic excludes what came from $topic from @$in_next. + # $topic can be rebased if these two set matches, because + # no commits in $topic has been merged to $stage yet. + if (@not_in_topic != @$in_next) { + # we cannot rebase it anymore + return ' '; + } + if (read_revs_short('master', "^$topic")) { + # there is something that is in master but not in topic. + return '^'; + } + # topic is up to date. + return '*'; +} + +sub describe_topic { + my ($topic) = @_; + open(CONF, '-|', qw(git repo-config --get), + "branch.$topic.description") + or die; + my $it = join('',); + close(CONF); + chomp($it); + if ($it) { + wrap_print(" $it"); + } +} + sub wrap_print { - my ($prefix, $string) = @_; + my ($string) = @_; format STDOUT = - @ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - $prefix, $string - ~~^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< +~^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + $string + ~~^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< $string . write; @@ -69,6 +102,8 @@ open(TOPIC, '-|', qw(git for-each-ref), "refs/heads/$topic_pattern") or die; +my @in_next = read_revs_short('^master', $stage[0]); + while () { chomp; my ($sha1, $date, $topic) = m|^([0-9a-f]{40})\s(.*?)\srefs/heads/(.+)$| @@ -78,18 +113,21 @@ while () { my %revs = map { $_->[0] => $_ } @revs; # fast index for (my $i = 0; $i < @stage; $i++) { - for my $item (read_revs_short($stage[$i], $sha1)) { + for my $item (read_revs_short("^$stage[$i]", $sha1)) { if (exists $revs{$item}) { $revs{$item}[2] &= ~(1 << $i); } } } - print "* $topic ($date)\n"; + + print '*' . rebase_marker($sha1, $stage[0], \@in_next); + print " $topic ($date)\n"; + describe_topic($topic); for my $item (@revs) { my $mark = $item->[2]; if ($mark < @mark) { $mark = $mark[$mark]; } - wrap_print($mark, $item->[1]); + wrap_print("$mark $item->[1]"); } } -- 2.32.0.93.g670b81a890