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.