Now git-topic is a bit more usable and close enough to TO script.
Junio C Hamano committed
Dec 8, 2006 at 14:16 UTC
606e7205a3ff52247a0925fe5836b732836396c3
2 files changed
+50
-11
TO
+3
-2
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
git-topic.perl
+47
-9
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 (<REVS>) {
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('',<CONF>);
+ 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 (<TOPIC>) {
chomp;
my ($sha1, $date, $topic) = m|^([0-9a-f]{40})\s(.*?)\srefs/heads/(.+)$|
@@ -78,18 +113,21 @@ while (<TOPIC>) {
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]");
}
}