chiark / gitweb /
Move old update algorith, which is very wrong according to new THEORY, into its own...
[topbloke.git] / tb-update.pl
index 6005d9e..58e7d60 100755 (executable)
@@ -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;