my $want = "topbloke-".$drvname->($file);
$attrs .= "$pat\tmerge=$want\n";
my $current = run_git_1line(qw(check-attr merge), $check);
- $current =~ s#^\Q$path\E: merge: ## or die "$file $current ?";
+ $current =~ s#^\Q$check\E: merge: ## or die "$file $current ?";
next if $current eq $want;
die "$file $current ?" unless $current eq 'unspecified';
- push @needupdate, $file;
+ push @needupdate, "$file=$current";
}
if (@needupdate) {
my $newattrsf = new IO::File "$attrsfile.tmp", 'w'
or die "$attrsfile.tmp: $!";
- die "@needupdate $current ?" if $iteration;
+ die "@needupdate ?" if $iteration;
$attrsfile = git_dir()."/info/attributes";
if (!open OA, '<', "$attrsfile") {
die "$attrsfile $!" unless $!==ENOENT;
sub foreach_patch ($$$$) {
my ($spec, $deleted_ok, $want, $body) = @_;
- # runs $body->($patch, $parsedname, \%props)
- # where $props{<metadata filename>} is, for <metadata filename> in @$want:
+ # runs $body->($patch, $parsedname, \%meta)
+ # where $meta{<metadata filename>} is, for <metadata filename> in @$want:
# undefined if metadata file doesn't exist
# defined with contents of file
# and $parsedname is only valid if $spec is not undef
# (say $spec { } if you want the name parsed but no restrictions)
# entries in want may also be "<metadata filename>_"
- # which means "strip trailing newlines" (result key in %props is the same)
+ # which means "strip trailing newlines" (result key in %meta is the same)
+ # <metadata filename> may instead be "B_<metadata filename>"
+ # which means to look in the corresponding base branch
my @want = @$want;
my $atfront = sub {
my $thing = @_;
debug("foreach_patch considering $_");
m/ / or die "$_ ?";
my $objname = $`;
- my %props;
+ my %meta;
my $parsedname;
my $patch = substr($',19); #');
my $wantix = 0;
foreach my $wantent (@want) {
my $file = $wantent;
my $stripnl = ($file =~ s/_$//);
+ my $inbase = ($file =~ s/^B_//);
if ($file eq ' patch') {
if ($spec) {
$parsedname = parse_patch_name($patch);
- debug("foreach_patch mismatch"), return
- unless patch_matches_spec($parsedname, $spec);
+ if (!patch_matches_spec($parsedname, $spec)) {
+ debug("foreach_patch mismatch");
+ return;
+ }
}
next;
}
- my ($got, $data) = git_get_object("$objname:.topbloke/$file");
-
-xxx up to here new foreach_patch api
-xxx up to here new metadata in this function
-
- die "$patch $file ?" unless defined $data;
- my %data;
- if ($file !~ m/props/) {
- $data{$_}=1 foreach split /\n/, $data;
- } elseif {
- foreach (split /\n/, $data) {
- m/ / or m/$/;
- $data{$`} = $'; #';
+ my $objkey = (!$inbase ? "$objname" :
+ "refs/topbloke-bases/$patch").":.topbloke/$file";
+ my ($got, $data) = git_get_object($objkey);
+ if ($got eq 'missing') {
+ $meta{$file} = undef;
+ } elsif ($got eq 'blob') {
+ $meta{$file} = $data;
+ if ($file eq 'deleted' && !$deleted_ok) {
+ debug("foreach_patch Deleted");
+ return;
}
+ } else {
+ warn "patch $patch object $objkey has unexpected type $got!\n";
+ return;
}
-
- if ($file eq 'props') {
- debug("foreach_patch Deleted"), return
- if !$deleted_ok && $data{Deleted};
- }
-
- push @out, \%data;
}
- debug("foreach_patch YES ".(join '', map { 0+defined } @out)), return
- $body->($patch, @out);
+ debug("foreach_patch YES $patch");
+ $body->($patch, $parsedname, \%meta);
},
qw(for-each-ref --format), '%(objectname) %(refname)',
qw(refs/topbloke-tips));
#----- updating topbloke metadata -----
-xxx this section needs updating for new metadata
-
-sub propsfile_set_prop ($$$) {
- # set $value to undef to delete; returns old value
- my ($propsfile, $prop, $value) = @_;
- my $wf = wf_start(".topbloke/$propsfile");
- my $oldvalue;
- open FI, '<', ".topbloke/$propsfile" or die $!;
- while (<FI>) {
- chomp or die;
- m/ / or m/$/;
- if ($` eq $prop) {
- die "prop $prop repeated in $propsfile ?!" if defined $oldvalue;
- $oldvalue = $'; #';
- } else {
- wf($wf, "$_\n");
- }
- }
- FI->error and die $!;
- close FI or die $!;
- wf($wf, "$prop $value\n") if defined $value;
- wf_done($wf);
- return $oldvalue;
-}
-
sub depssfile_add_dep ($$) {
my ($depsfile, $depspec) = @_;
my $wf = wf_start(".topbloke/$depsfile");
# usage: tb-list [<patch-spec>]
# lists all patches matching <patch-spec> and other criteria
-xxx needs updating for new metadata and new theory
-
use warnings;
use strict;
our %patches;
foreach_patch($relatedto || $leaves || !$spec ? { } : $spec,
-xxx new api for foreach_patch
$deleted || $deleted_only,
- [0, !!$leaves, 0, $toposort || !!$relatedto],
+ [qw(B_deps +included)],
sub {
- my ($patch,$parsedname,@info) = @_;
- $patches{$patch}{Info} = \@info;
+ my ($patch,$parsedname,$meta) = @_;
+ $patches{$patch}{Meta} = $meta;
$patches{$patch}{ParsedName} = $parsedname;
+ $patches{$patch}{Deps} =
+ grep { m/^[^-]/ } split /\n/, $meta->{'B_deps'};
+ $patches{$patch}{Included} = { };
+ $patches{$patch}{Included}{$_} = 1
+ foreach split /\n/, $meta->{'+included'};
});
#----- selection -----
foreach my $p (keys %patches) {
debug("leaves $p");
my $v = $patches{$p};
- next if $v->{Info}[0]{Deleted};
- foreach my $dep (keys %{ $v->{Info}[1] }) {
+ next if defined $v->{Meta}{'deleted'};
+ foreach my $dep (@{ $v->{Deps} }) {
debug("leaves $p $dep");
next unless exists $patches{$dep};
$patches{$dep}{NotLeaf} = 1;
foreach my $p (keys %patches) {
my $v = $patches{$p};
# mark Related=1 if any patch matching $relatedto includes us
- foreach my $dep (keys %{ $v->{Info}[3] }) {
+ foreach my $dep (keys %{ $v->{Included} }) {
next unless exists $patches{$dep};
my $depv = $patches{$dep};
next unless patch_matches_spec($depv->{ParsedName}, $relatedto);
}
if (patch_matches_spec($v->{ParsedName}, $relatedto)) {
# if we match $relatedto, mark all our inclusions as Related=1
- foreach my $dep (keys %{ $v->{Info}[3] }) {
+ foreach my $dep (keys %{ $v->{Included} }) {
next unless exists $patches{$dep};
$patches{$dep}{Related} = 1;
}
foreach my $p (keys %patches) {
my $v = $patches{$p};
- next if !$deleted && $v->{Info}[0]{Deleted};
- next if $deleted_only && !$v->{Info}[0]{Deleted};
+ next if !$deleted && defined $v->{Meta}{'deleted'};
+ next if $deleted_only && !defined $v->{Meta}{'deleted'};
next if $leaves && $v->{NotLeaf};
next if $relatedto && !$v->{Related};
next if $spec && !patch_matches_spec($v->{ParsedName}, $spec);
my $ab = (qw(a b))[$ix];
my $ba = (qw(b a))[$ix];
my $r = (qw(1 -1))[$ix];
- $txt .= " return $r if \$v${ab}->{Info}[3]{\$$ba};\n";
+ $txt .= " return $r if \$v${ab}->{Included}{\$$ba};\n";
}
} else {
die $sort;
? $1 : "[no subject]";
printf("%1s%1s %s\@%s/%s/%-20s %s\n",
$p eq $current_patch ? $ifcurrent : '',
- $v->{Info}[0]{Deleted} ? 'D' : '',
+ defined $v->{Meta}{'deleted'} ? 'D' : '',
$pa->{Email}, $pa->{Domain}, $pa->{Date}, $pa->{Nick},
$subject)
or die $!;