Skip to content

Instantly share code, notes, and snippets.

@atimb
Forked from mfn/find-empty-dir-in-svn.rb
Last active May 10, 2018 22:52
Show Gist options
  • Save atimb/4496313 to your computer and use it in GitHub Desktop.
Save atimb/4496313 to your computer and use it in GitHub Desktop.
Ruby script to find top-level empty directories in a working SVN directory tree (forked and fixed because original script was not properly working for more complicated directory structure)
##
# Ruby script to find top-level empty directories in a working SVN directory tree
#
# A directory is considered empty, if there are zero files reachable through this directory (excluding
# files under .svn directories). That means that a directory containing other empty directories is
# also empty (recursively). The algorithm will consolidate the output so that it only contains
# top-level empty directories, but not their sub-directories.
#
# The output of this script can be used, for example to remove non-used parts of a SVN repository:
# ruby empty_dirs.rb | xargs svn del
##
require 'find'
dir_to_scan = '.'
dir_to_scan = ARGV[0] if ARGV.count == 1
dirs = []
# First collect all directories, but ignore anything with .svn in it
Find.find( dir_to_scan ) do |entry|
next if entry =~ /\.svn/
next if not File.directory?(entry)
dirs << entry
end
dirs_count = {}
# Fetch the dirs and count number of entries(dirs, files), excluding .svn again
dirs.each do |dir|
dirs_count[dir] =
Dir.entries(dir).collect { |e|
case e
when '.svn'
nil
when '.'
nil
when '..'
nil
else
e
end
}.compact.count
end
# Traverse the directory tree and adjust the number of entries for each directory
dirs_count_copy = dirs_count.dup
dirs_count_copy.each do |dir,count|
if count == 0
depth = dir.count('/');
while depth > 1
depth = depth - 1
dir = dir[0..(dir.length-dir.split('/').last.length-2)]
dirs_count[dir] = dirs_count[dir] - 1;
if (dirs_count[dir] > 0)
break
end
end
end
end
# Filter the hashmap to only contain all empty directories
empty_dirs = {}
dirs_count.each do |dir,count|
if count == 0
empty_dirs[dir] = 1;
end
end
# Consolidate the list to only top-level empty directories
empty_dirs.each do |parent,c|
empty_dirs.each do |possible_child,c|
if possible_child.index(parent+'/')
empty_dirs.delete(possible_child)
end
end
end
# Output empty top-level directories one-by-one
empty_dirs.each do |dir,c|
puts dir.gsub(' ', '\\ ')
end
@alex-vas
Copy link

Nice, thanks! I only suggest adding shebang at the top, so you could run it as a script on linux and mac.

#!/usr/bin/env ruby

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment