How do you migrate a Homebrew installation to a new location?

As suggested by Peter Eisentraut, I indeed ended up migrating my Homebrew installation by reinstalling it. You can script things a bit to retap all your extra taps, and reinstall all your previously installed kegs, without too much manual work:

#!/bin/sh

# save list of kegs for later reinstallation
brew list > kegs.txt

# back up old Homebrew installation
mv $HOME/brew $HOME/old-brew

# install Homebrew into /usr/local
ruby -e "$(curl -fsSL https://raw.github.com/mxcl/homebrew/go)"

# retap all the taps
# NB: It is not enough to move the tap repos to their new location,
# because Homebrew will not automatically recognize the new formulae.
# There might be a configuration file we could edit, but rather than
# risk an incomplete data structure, let's just retap everything.
for tapDir in $HOME/old-brew/Library/Taps/*
do (
  cd $tapDir
  tap=$(git remote -v | \
    grep '(fetch)' | \
    sed 's/.*github.com\///' | \
    sed 's/ (fetch)//')
  /usr/local/bin/brew tap $tap
) done

# reinstall all the kegs
/usr/local/bin/brew install $(cat kegs.txt)

# much later... ;-)
rm -rf kegs.txt $HOME/old-brew

Of course, customized Homebrew installations will have additional wrinkles. For example, if you have committed changes to any of your Homebrew-related Git repos, you may want to import that work before reinstalling your kegs or blowing away your old installation:

cd /usr/local
for f in $(find . -name '.git')
do (
  repoDir=$(dirname $f)
  cd $f/..
  git remote add old-brew-$f $(dirname $HOME/old-brew/$f/..)
  git fetch old-brew-$f
) done

Note that I only tested the second snippet above very lightly, as I personally have not customized my Homebrew in such a way.

Another aspect of Homebrew not addressed by this approach is custom flags using during your original installation. For example, to install wine you need to install various dependencies with the --universal flag, and the script above will not reinstall them with such flags enabled. See @xuhdev's answer for a solution that does so.


The modern way to do this is with homebrew-bundle.

brew tap Homebrew/bundle
brew bundle dump # Creates 'Brewfile' in the current directory
# later ...
brew bundle # Installs packages listed in 'Brewfile'

I just wrote a script to achieve the goal to migrate homebrew packages to a new system, which also applies for your case (named backup-homebrew.sh):

#!/bin/bash

echo '#!/bin/bash'
echo ''
echo 'failed_items=""'
echo 'function install_package() {'
echo 'echo EXECUTING: brew install $1 $2'
echo 'brew install $1 $2'
echo '[ $? -ne 0 ] && $failed_items="$failed_items $1"  # package failed to install.'
echo '}'

brew tap | while read tap; do echo "brew tap $tap"; done

brew list --formula | while read item;
do
  echo "install_package $item '$(brew info $item | /usr/bin/grep 'Built from source with:' | /usr/bin/sed 's/^[ \t]*Built from source with:/ /g; s/\,/ /g')'"
done

echo '[ ! -z $failed_items ] && echo The following items were failed to install: && echo $failed_items'

You should first run this script on your original system to generate a restore script:

./backup-homebrew.sh >restore-homebrew.sh && chmod +x restore-homebrew.sh

Then, after installing Homebrew on your new system (in your case the same system), simply run restore-homebrew.sh to install all those packages you have on your original system.

The benefits of this script over the one given by @ctrueden is that this script also tries to back up the installation options you used when you installed the packages.

A more detailed description is in my blog.

Tags:

Homebrew