Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
When you import movies into iMovie 10 libraries, the file is always copied, wasting space and hindering editability. This script replaces the copy with a hardlink, reclaiming disk space.
#!/usr/bin/env ruby
# Usage: dedup-imovie-library LIBRARY ORIGINALS
# Goes through an iMovie 10 library and replaces all the "Original Media" with
# symlinks to the actual original media, in order to conserve disk space. Note
# that because they're symlinks, if the path to the originals changes (e.g. you
# rename the external drive they are on) then the links will be broken.
# This assumes you've already imported the files into iMovie and waited for them
# all to be copied.
# This also assumes movie files in LIBRARY have unique matches in ORIGINALS with
# the same filename!
# This script will also check that the file is indeed a duplicate before deleting it and creating a link
require 'fileutils'
library = ARGV.shift
originals = ARGV.shift
fail "Library #{library} does not exist" unless library && File.exist?(library)
fail "You must use an absolute path for the originals directory" if originals.start_with?( '..')
fail "Originals folder #{originals} does not exist" unless originals && File.exist?(originals)
# For each original file in the imovie library
Dir.glob(File.join(library, '**', 'Original Media', '*')) do |library_file|
next unless File.file? library_file
# Skip it if we've already replaced it with a symlink
next if File.lstat(library_file).symlink?
# Look for a file in the originals path with the same filename (case-insensitive)
original = Dir.glob(File.join(originals, '**', File.basename(library_file)), File::FNM_CASEFOLD).first
next unless original
# Make sure file contents are identical
next unless FileUtils.compare_file library_file, original
puts "Linking #{library_file} => #{original}"
FileUtils.rm_f library_file, verbose: true
# Replace with a symlink
FileUtils.ln_s original, library_file, verbose: true
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment