Re: Topic descriptions
From: Junio C Hamano <hidden>
Date: 2016-08-11 19:56:54
Andy Parkins [off-list ref] writes:
The actual place it's stored isn't really relevant, more that I could see a use for it. If it's going in the config I suppose all it needs is a magic "and so it shall be" hand wave.
I now have this in my .git/config:
-- >8 -- snippet from .git/config -- >8 --
[branch "ap/clone-origin"]
description = set up a cloned repository with friendlier defaults.
[branch "jc/3way"]
description = use three-way merge to preserve local changes upon branch switch and fast forward.
-- 8< --
and have the script attached at the end. I can say:
$ git-topic --base=master
to get something like that per-topic summary I sent out earlier.
The default $base is set to 'next' because usually I am
interested in keeping track of what could be merged but not yet
to next.
Hopefully gitweb (and perhaps gitk) can follow suit to read the
branch description from the same place.
-- >8 -- git-topic.perl -- >8 --
#!/usr/bin/perl -w
#
# Copyright (c) 2006 Junio C Hamano
#
use strict;
use Getopt::Long;
my $topic_pattern = '??/*';
my $base = 'next';
my @stage = qw(next pu);
my @mark = ('.', '?', '-', '+');
my $all = 0;
my @custom_stage;
my @custom_mark;
GetOptions("topic=s" => \$topic_pattern,
"base=s" => \$base,
"stage=s" => \@custom_stage,
"mark=s" => \@custom_mark,
"all!" => \$all)
or die;
if (@custom_stage) { @stage = @custom_stage; }
if (@custom_mark) { @mark = @custom_mark; }
sub read_revs_short {
my ($bottom, $top) = @_;
my @revs;
open(REVS, '-|', qw(git rev-list --no-merges), "$bottom..$top")
or die;
while (<REVS>) {
chomp;
push @revs, $_;
}
close(REVS);
return @revs;
}
sub read_revs {
my ($bottom, $top, $mask) = @_;
my @revs;
open(REVS, '-|', qw(git rev-list --pretty=oneline --no-merges),
"$bottom..$top")
or die;
while (<REVS>) {
chomp;
my ($sha1, $topic) = /^([0-9a-f]{40}) (.*)$/;
push @revs, [$sha1, $topic, $mask];
}
close(REVS);
return @revs;
}
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 ($string) = @_;
format STDOUT =
~^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$string
~~^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$string
.
write;
}
open(TOPIC, '-|', qw(git for-each-ref),
'--sort=-authordate',
'--format=%(objectname) %(authordate) %(refname)',
"refs/heads/$topic_pattern")
or die;
while (<TOPIC>) {
chomp;
my ($sha1, $date, $topic) = m|^([0-9a-f]{40})\s(.*?)\srefs/heads/(.+)$|
or next;
my @revs = read_revs($base, $sha1, (1<<@stage)-1);
next unless (@revs || $all);
my %revs = map { $_->[0] => $_ } @revs; # fast index
for (my $i = 0; $i < @stage; $i++) {
for my $item (read_revs_short($stage[$i], $sha1)) {
if (exists $revs{$item}) {
$revs{$item}[2] &= ~(1 << $i);
}
}
}
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]");
}
}