});
}
-sub committ_date ($) {
+sub commit_date ($) {
my ($ref) = @_;
my $l = run_git_1line(qw(git-log --date=raw -n1 --pretty=format:%cd), $ref);
$l =~ m/^(\d+)\s/ or die;
return $l;
}
+sub compare_source_ages ($$) {
+ my ($r,$s) = @_; # refs, returns something like age($r) cmp age($s)
+ our %memos;
+ return memo(\%memos, "$r $s", sub {
+ my $mb = merge_base($r, $s);
+ return -($mb eq $r) cmp ($mb eq $s)
+ # if merge base is $a then $a must be before $b
+ # ie the commit equal to the merge base is earlier
+ or (commit_date($r) cmp commit_date($s));
+ });
+}
+
sub update_base ($) {
my ($patch) = @_;
push @sources, {
Name => $depline,
Ref => "$tiprefs/$depline",
- Kind => 'tb',
+ Kind => 'topbloke',
};
}
}
# ie we are ahead of the source. Skip those sources.
@sources = grep { $source->{MergeBase} ne $source->{Head} } @sources;
- our %cmp_memos;
- @sources = sort {
- memo(\%cmp_memos, "$a->{Name} $b->{Name}", sub {
- my $mb = merge_base($a->{Ref}, $b->{Ref});
- return -($mb eq $a->{Ref}) cmp ($mb eq $b->{Ref})
- # if merge base is $a then $a must be before $b
- # ie the commit equal to the merge base is earlier
- or (committ_date($a->{Ref}) cmp committ_date($b->{Ref}));
- })
- } @sources;
- fixme we do not need to sort, only find best, and then do again
-
- # Now we run git-rev-list to walk the graph back to those
- # sources so we can tell which is the most recent.
- foreach my $source (@sources) {
-
+ if (!@sources) {
+ print "$patch base is up to date\n" or die $!;
+ last;
+ }
-
- $source->{MergeBase} = $mergebase;
-
- bad_metadata("$patch base topgit $obj") unless $obj eq 'blob';
-
- # ok
- } elsif ($obk
+ 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 };
+ run_git(sub {
+ my ($cand, @parents) = split;
+ return if dep_included_in($dep, $cand);
+ return if grep { !dep_included_in($dep, $_) } @parents;
+ # OK, it's missing from $cand but included in
+ # all of $cand's parents.
+
+ },
+ qw(git-rev-list --date-order --remove-empty)
+ '--pretty=format:%H %P%n',
+ $dep, '--', '.topbloke/+included');
+
+
+ push @unwanted_dr, { Name => $dep };
+
sub done ($) {
our %done;