X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=topbloke.git;a=blobdiff_plain;f=tb-update.pl;h=58e7d602470c23c11766b39edd1322ba44584694;hp=6005d9e034846bbea47c260020d4712b0a0961f6;hb=97ed131fce2ba8de7454b00eef6a9adcd09e7fa0;hpb=0329eb76d525c6a7cd8a331697cd1d6b969314ea diff --git a/tb-update.pl b/tb-update.pl index 6005d9e..58e7d60 100755 --- a/tb-update.pl +++ b/tb-update.pl @@ -91,7 +91,7 @@ sub update_base ($) { push @sources, { Name => $depline, Ref => "$tiprefs/$depline", - Kind => 'tb', + Kind => 'topbloke', }; } } @@ -120,14 +120,82 @@ sub update_base ($) { # ie we are ahead of the source. Skip those sources. @sources = grep { $source->{MergeBase} ne $source->{Head} } @sources; + if (!@sources) { + print "$patch base is up to date\n" or die $!; + last; + } + my $best = $sources[0]; foreach my $source (@sources[1..$#sources]) { next if compare_source_ages($best->{Ref}, $source->{Ref}) <= 0; $best = $source; - } - + my $sref = $source->{Ref}; + + if ($source->{Kind} eq 'topbloke') { + # Check for unwanted dependency removals + my (%source_inc,%anc_inc); + $source_inc{$_}=1 foreach split /\n/, + git_get_object("$sref:.topbloke/+included"); + $anc_inc{$_}=1 foreach split /\n/, + git_get_object("$source->{MergeBase}:.topbloke/+included"); + my @unwanted_dr; + foreach my $dep (keys %desired) { + next if $source_inc{$dep}; + unless unless $anc_inc{$dep}; + my $unw_dr = { Name => $dep }; + + + # Algorithm + # We do a history graph walk. + # In each iteration we get git-rev-list to find us + # one commit. + + # We get git-rev-list to find us + send us a series of commits + # We look up each one. + my @prune; + my $pruned = sub { + my ($commit) = @_; + return grep { commit_has_ancestor($_, $cand) } @prune; + }; + my $prune = sub { + my ($commit) = @_; + return if $pruned->($commit); + push @prune, $commit; + }; + run_git(sub { + my ($cand, @parents) = split; + if (dep_included_in($dep, $cand)) { + $prune->($cand); + return; + } + my @parents_with = + grep { dep_included_in($dep, $_) } @parents; + return if !@parents_with; # irrelevant merge + return if $pruned->($cand); # not interesting any more + $prune->($_) foreach @parents_with; + + + PROBLEM @prune is bad we want to know why + we have found thing not just whether found + + # + return if dep_included_in($dep, $cand); + return if + # OK, it's missing from $cand but included in + # all of $cand's parents. + + }, + qw(git-rev-list --date-order --full-history + --remove-empty) + '--pretty=format:%H %P%n', + $dep, '--', '.topbloke/+included'); + + + push @unwanted_dr, { Name => $dep }; + sub done ($) { our %done;