- grant "Allowed by: $acl_ops for $acl_n"
- if (
- ($acl_n eq $ref)
- || ($acl_n =~ m,/$, && substr($ref,0,length $acl_n) eq $acl_n)
- || ($acl_n =~ m,^\^, && $ref =~ m:$acl_n:)
- );
+ # Allow only if all changes against a single base are
+ # allowed by file path rules.
+ #
+ my @bad;
+ foreach my $p_bst (keys %pr) {
+ my $diff_ref = load_diff $p_bst;
+ deny "Cannot difference trees." unless ref $diff_ref;
+
+ my %fd = %$diff_ref;
+ foreach my $p_entry (@{$pr{$p_bst}}) {
+ my ($p_ops, $p_n, $p_ref, $p_bst) = @$p_entry;
+ next unless $p_ops =~ /^[AMD]+$/;
+ next unless $p_n;
+
+ foreach my $f_n (keys %fd) {
+ my $f_op = $fd{$f_n};
+ next unless $f_op;
+ next unless $f_op =~ /^[$p_ops]$/;
+ delete $fd{$f_n} if match_string $p_n, $f_n;
+ }
+ last unless %fd;
+ }
+
+ if (%fd) {
+ push @bad, [$p_bst, \%fd];
+ } else {
+ # All changes relative to $p_bst were allowed.
+ #
+ grant "Allowed by: $acl_ops for $acl_n diff $p_bst";
+ }
+ }
+
+ foreach my $bad_ref (@bad) {
+ my ($p_bst, $fd) = @$bad_ref;
+ print STDERR "\n";
+ print STDERR "Not allowed to make the following changes:\n";
+ print STDERR "(base: $p_bst)\n";
+ foreach my $f_n (sort keys %$fd) {
+ print STDERR " $fd->{$f_n} $f_n\n";
+ }
+ }
+ deny "You are not permitted to $op $ref";