And here's another pair:

[[[
harmonia,0:~% /root/bin/dump-noderev.pl /x1/svn/asf /subversion r965497
id: 0-836401.0.r965497/8198
type: dir
pred: 0-836401.0.r965496/3747
count: 47068
text: 965497 7817 368 368 e18a7fbe8bedde647c30c288bbc02c1d
props: 866503 8246 73 0 d34667037ecfd7bab466410a1c52bda6
cpath: /subversion
copyroot: 0 /
minfo-cnt: 310

harmonia,0:~% 
]]]

[[[
eris,0:~% /root/bin/dump-noderev.pl /x1/svn/asf /subversion r965497
id: 0-836401.0.r965497/8197
type: dir
pred: 0-836401.0.r965495/2287
count: 47066
text: 965497 7816 368 368 3b2cd1fe800d754c84d91313ec246c04
props: 866503 8246 73 0 d34667037ecfd7bab466410a1c52bda6
cpath: /subversion
copyroot: 0 /
minfo-cnt: 34417865054

eris,0:~% 
]]]


This time the mergeinfo is correct --- on both eris and harmonia the
minfo-cnt value is the same in r965497 and in r965496, and is (properly)
one greater than the minfo-cnt in r965495.  It is again eris(svn-master.a.o)
which is corrupted --- which skips a predecessor.
#!/usr/local/bin/perl

use warnings;
use strict;

$ENV{uc $_} ||= lc $_ for qw/svn svnlook svnadmin/;

sub open_pack_or_rev_file {
  my ($FS, $REVISION, $OFFSET) = @_;
  my $shard = int ($REVISION / 1000);
  my $remainder = $REVISION % 1000;

  if (-e "$FS/revs/$shard/$REVISION") {
    return  "$FS/revs/$shard/$REVISION", $OFFSET;
  } elsif (-e "$FS/revs/$REVISION") {
    return  "$FS/revs/$REVISION", $OFFSET;
  } elsif (-e "$FS/revs/$shard.pack") {
    my $lineno = $remainder+1;
    my $rev_offset = `cat $FS/revs/$shard.pack/manifest | sed -ne ${lineno}p`;
    return  "$FS/revs/$shard.pack/pack", $rev_offset + $OFFSET;
  }
}

sub main {
  my ($REPOS, $FSPATH, $REV) = @_;
  my $FS = "$REPOS/db";
  $REV =~ s/^r*// if defined $REV;

  die "USAGE: $0 /path/to/repos /path/in/repos [revnum]" if @_ != 2 and @_ != 3;

  die "Unknown repos format: $REPOS/format" if `cat $REPOS/format` != 5;
  die "Not FSFS: $FS/fs-type" if `cat $FS/fs-type` ne "fsfs\n";
  die "Unknown FSFS format: $FS/format" if `head -n1 $FS/format` !~ /^[346]$/;

  my ($revision, $offset) = do {
    my $REV_ARG = defined($REV) ? "-r$REV" : "";
    # silence "broken pipe" error
    my $line = `$ENV{SVNLOOK} tree --full-paths --show-ids $REV_ARG $REPOS $FSPATH 2>&1 | head -n1`; 
    my ($noderev_id) = $line =~ /\S* <(.*)>$/;
    my ($node_id, $copy_id, $txn_id) = split /\./, $noderev_id;
    die if $txn_id =~ /\./;
    $txn_id =~ m#^r(\d+)/(\d+)$#;
  };

  my ($file, $file_offset) = open_pack_or_rev_file $FS, $revision, $offset;

  # Magic number 1024; assumes node-revs will be shorter than that.
  system("<$file xxd -s $file_offset -l 1024 | xxd -r | sed -e '/^\$/q'") == 0
    or die;
}

main @ARGV;


__END__

=head1 NAME

dump-noderev.pl - dump a node-revision from a FSFS-backed Subversion repository

=head1 SYNOPSIS

    % $0 /srv/repos/recipes /trunk
    % $0 /srv/repos/recipes /trunk r42

=head1 OPTIONS

None.

=head1 SEE ALSO

https://svn.apache.org/repos/asf/subversion/trunk/tools/dev/

=head1 COPYRIGHT

Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements.  See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Reply via email to