X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?p=dupemerge;a=blobdiff_plain;f=dm6;fp=dm6;h=ff3a9eb2b57244eed3ac9c8d071ebf58c5afcbf9;hp=8c1e3e964f6711ecc7c6f0ec4e9ad32634c7ebe8;hb=0c34a3856f509e8b615afc0fed52b7399fee21df;hpb=c75590d6bcfd8cb83a348a3b066a1b26c16fd316 diff --git a/dm6 b/dm6 index 8c1e3e9..ff3a9eb 100755 --- a/dm6 +++ b/dm6 @@ -41,7 +41,7 @@ sub usage { Usage: $0 link-dir Hashes a NUL-separated list of files on stdin into link-dir. -Version: 0.20100522 +Version: 0.20101024 USAGE } @@ -216,13 +216,44 @@ while () { } # Garbage collection -print STDERR "\nGarbage collection in '$link_dir'..."; +print STDERR "\nGarbage collection in '$link_dir'...\n"; chdir($link_dir) || die "chdir: $link_dir: $!"; -print STDERR "\nRemoving files with link count < 3 and temporary links..."; -system('find . -type f \( -links -3 -o -name ".*" \) -print0 | xargs -0rt rm -f') and die "system: exit status $?"; -print STDERR "\nRemoving empty directories..."; + +my ($last_inode) = ''; +my @last_links; + +sub handle_gc_file { + my ($line) = @_; + my ($inode, $link) = ($line =~ /^(\S+) (.+)\0$/os); + $inode ||= ''; + if ($inode ne $last_inode) { + my ($dev, $ino, $links) = ($last_inode =~ /^(\d+):(\d+):(\d+)$/os); + if (defined($links)) { + if ($links && $links == @last_links) { + print STDERR "rm -f @last_links\n"; + for my $unlink (@last_links) { + unlink($unlink) or warn "unlink: $unlink: $!"; + } + } + } else { + warn "Could not parse '$last_inode' in '$line'" unless $last_inode eq ''; + } + @last_links = (); + } + $last_inode = $inode; + push(@last_links, $link); +} + +print STDERR "Removing files contained entirely in '$link_dir'...\n"; +open(FIND, "find . -type f -printf '%D:%i:%n %p\\0' | sort -z --compress-program=gzip |") or die "open: find: $!"; +while () { + handle_gc_file($_); +} +handle_gc_file(''); + +print STDERR "Removing empty directories...\n"; system("find . -type d -empty -print0 | xargs -0rt rmdir -p --ignore-fail-on-non-empty") and die "system: exit status $?"; -print STDERR "\nDone.\n"; +print STDERR "Done.\n"; exit(0);