How to undo a wrong ‘bundle install’

Sometimes I inadvertently run ´$ bundle install´ before setting to the right gemset through rvm, and thus messing up the current (and wrong) gemset.

$ gem list

*** LOCAL GEMS ***

actionmailer (3.2.12)
actionpack (3.2.12)
active_utils (1.0.5)
activemerchant (1.31.1)
activemodel (3.2.12)
activerecord (3.2.12)
activerecord-import (0.3.1)
activeresource (3.2.12)
activesupport (4.0.4, 3.2.12)
acts_as_list (0.2.0)
airbrake (3.1.8)
allison (2.0.3)
ansi (1.4.3)
ar-extensions (0.9.2)
archive-tar-minitar (0.5.2)
arel (3.0.2)
atomic (1.1.16)
attr_required (0.0.5)
authlogic (3.2.0, 2.1.6)
authlogic_rpx (1.2.0)
aws-sdk (1.8.5)
bourne (1.1.2)
builder (3.2.2, 3.0.4)
bundler (1.2.3)
cane (2.6.1)
childprocess (0.3.9)
chronic (0.9.1)
ci_reporter (1.9.1)
climate_control (0.0.3)
cocaine (0.5.1)
coderay (1.1.0, 1.0.9)
columnize (0.3.6)
contacts19 (1.2.4)
coveralls (0.7.0)
daemon_controller (1.1.1)
daemons (1.1.9)
docile (1.1.3)
echoe (4.6.3)
elasticsearch (1.0.1)
elasticsearch-api (1.0.1)
elasticsearch-extensions (0.0.14)
elasticsearch-transport (1.0.1)
erubis (2.7.0)
eventmachine (1.0.1)
factory_girl (4.2.0)
faraday (0.9.0, 0.8.6)
fastthread (1.0.7)
fattr (2.2.1)
ffi (1.4.0)
gdata_19 (1.1.5)
gem-wrappers (1.2.4)
gemcutter (0.7.1)
guard (1.6.2)
guard-spork (1.5.0)
guard-test (0.7.0)
has_many_polymorphs (2.13)
hashie (2.0.5, 2.0.2)
highline (1.6.15)
hike (1.2.1)
hominid (3.0.5)
hpricot (0.8.6)
httmultiparty (0.3.8)
httparty (0.10.2)
httpauth (0.2.0)
httpclient (2.3.3)
i18n (0.6.9, 0.6.4)
itunes-search (0.4.1)
journey (1.0.4)
json (1.7.7)
json_pure (1.7.7)
jwt (0.1.6)
linecache19 (0.5.13)
listen (0.7.3)
lumberjack (1.0.2)
macaddr (1.6.1)
mail (2.4.4)
metaclass (0.0.4, 0.0.1)
method_source (0.8.2, 0.8.1)
mime-types (2.2, 1.21)
minitest (4.7.5)
mocha (1.0.0, 0.10.5)
money (5.1.1)
multi_json (1.9.0, 1.6.1)
multi_xml (0.5.3)
multipart-post (2.0.0, 1.2.0)
music_xray_api (0.3.0)
mysql2 (0.3.11)
newrelic_rpm (3.5.8.72)
nokogiri (1.5.6)
oauth (0.4.7)
oauth-plugin (0.4.1)
oauth2 (0.9.1)
options (2.3.0)
paperclip (3.4.1)
parallel (0.9.2)
passenger (3.0.19)
paypal-express (0.5.3)
polyglot (0.3.3)
pr_geohash (1.0.0)
progress_bar (0.4.0)
pry (0.9.12.6, 0.9.12)
pusher (0.11.3)
rack (1.5.2, 1.4.5)
rack-cache (1.2)
rack-protection (1.4.0)
rack-ssl (1.3.3)
rack-test (0.6.2)
rails (3.2.12)
railties (3.2.12)
rake (10.1.1, 10.0.3)
rb-fsevent (0.9.3)
rb-inotify (0.9.0)
rdiscount (2.0.7.1)
rdoc (3.12.2, 3.12.1)
rdoc-data (3.12)
redis (3.0.3)
redis-namespace (1.2.1)
require-prof (0.0.1)
resque (1.23.0)
resque-retry (1.0.0)
resque-scheduler (2.0.0)
resque_unit (0.4.4)
rest-client (1.6.7)
restclient_with_cert (0.0.8)
rmagick (2.13.2)
rpx_now (0.6.23)
rsolr (1.0.8)
ruby-debug-base19x (0.11.30.pre10)
ruby-debug-ide (0.4.17.beta17, 0.4.17.beta16)
ruby-mp3info (0.8)
ruby-mysql (2.9.10)
ruby-prof (0.14.2)
ruby_core_source (0.1.5)
rubyforge (2.0.4)
rubygems-bundler (1.1.0)
rufus-scheduler (2.0.18)
rvm (1.11.3.5)
sanitize (2.0.3)
shoulda (3.3.2)
shoulda-context (1.1.6, 1.0.2)
shoulda-matchers (1.4.2)
signature (0.1.6)
simplecov (0.8.2)
simplecov-html (0.8.0)
simplecov-rcov (0.2.3)
sinatra (1.3.5)
slop (3.5.0, 3.4.3)
soundcloud (0.3.1)
spork (0.9.2)
spork-testunit (0.0.8)
sprockets (2.2.2)
sunspot (2.0.0)
sunspot_rails (2.0.0)
systemu (2.5.2)
term-ansicolor (1.3.0)
terminal-table (1.4.5)
test-unit (2.5.4)
thin (1.5.0)
thor (0.18.1, 0.17.0)
thread_safe (0.3.0)
tilt (1.3.4)
tins (1.0.0)
treetop (1.4.12)
turn (0.9.7)
tzinfo (0.3.39, 0.3.36)
useragent (0.4.16)
uuid (2.3.7)
uuidtools (2.1.3)
validatable (1.6.7)
vegas (0.1.11)
will_paginate (3.0.4)
xml-simple (1.1.2)
yard (0.8.7.3)
yui-on-rails (0.1.16)

For example, the above ´$ gem list´ shows old gems (normal text) from an old Rails 3 project mixed up with new gems (bold text) from a new Rails 4 project. At a certain point in my terminal session I had run ´$ rvm use ruby-1.9.3-p327@old-rails3-project´ and some time (days?) later I edited my new project’s Gemfile and ran ´$ bundle install´.

To fix the mess, I’ve written the following command line:

$ threshold="2d"; dir="`rvm gemdir`/gems"; find -X "$dir" -type d -maxdepth 1 -mindepth 1 -mtime -"$threshold" | xargs basename | sed -e 's/-(([0-9]{1,}.)*[0-9]{1,})$/ 1/g' -e 's/(.*) (.*)/gem uninstall 1 --version 2 --executables --ignore-dependencies &/g'

Which in my case generated the following command lines:

gem uninstall activesupport –version 4.0.4 –executables –ignore-dependencies &
gem uninstall ansi –version 1.4.3 –executables –ignore-dependencies &
gem uninstall atomic –version 1.1.16 –executables –ignore-dependencies &
gem uninstall builder –version 3.2.2 –executables –ignore-dependencies &
gem uninstall cane –version 2.6.1 –executables –ignore-dependencies &
gem uninstall ci_reporter –version 1.9.1 –executables –ignore-dependencies &
gem uninstall coderay –version 1.1.0 –executables –ignore-dependencies &
gem uninstall coveralls –version 0.7.0 –executables –ignore-dependencies &
gem uninstall docile –version 1.1.3 –executables –ignore-dependencies &
gem uninstall elasticsearch –version 1.0.1 –executables –ignore-dependencies &
gem uninstall elasticsearch-api –version 1.0.1 –executables –ignore-dependencies &
gem uninstall elasticsearch-extensions –version 0.0.14 –executables –ignore-dependencies &
gem uninstall elasticsearch-transport –version 1.0.1 –executables –ignore-dependencies &
gem uninstall faraday –version 0.9.0 –executables –ignore-dependencies &
gem uninstall hashie –version 2.0.5 –executables –ignore-dependencies &
gem uninstall i18n –version 0.6.9 –executables –ignore-dependencies &
gem uninstall metaclass –version 0.0.4 –executables –ignore-dependencies &
gem uninstall method_source –version 0.8.2 –executables –ignore-dependencies &
gem uninstall mime-types –version 2.2 –executables –ignore-dependencies &
gem uninstall minitest –version 4.7.5 –executables –ignore-dependencies &
gem uninstall mocha –version 1.0.0 –executables –ignore-dependencies &
gem uninstall multi_json –version 1.9.0 –executables –ignore-dependencies &
gem uninstall multipart-post –version 2.0.0 –executables –ignore-dependencies &
gem uninstall parallel –version 0.9.2 –executables –ignore-dependencies &
gem uninstall pry –version 0.9.12.6 –executables –ignore-dependencies &
gem uninstall rake –version 10.1.1 –executables –ignore-dependencies &
gem uninstall require-prof –version 0.0.1 –executables –ignore-dependencies &
gem uninstall ruby-prof –version 0.14.2 –executables –ignore-dependencies &
gem uninstall shoulda-context –version 1.1.6 –executables –ignore-dependencies &
gem uninstall simplecov –version 0.8.2 –executables –ignore-dependencies &
gem uninstall simplecov-html –version 0.8.0 –executables –ignore-dependencies &
gem uninstall simplecov-rcov –version 0.2.3 –executables –ignore-dependencies &
gem uninstall slop –version 3.5.0 –executables –ignore-dependencies &
gem uninstall term-ansicolor –version 1.3.0 –executables –ignore-dependencies &
gem uninstall thor –version 0.18.1 –executables –ignore-dependencies &
gem uninstall thread_safe –version 0.3.0 –executables –ignore-dependencies &
gem uninstall tins –version 1.0.0 –executables –ignore-dependencies &
gem uninstall turn –version 0.9.7 –executables –ignore-dependencies &
gem uninstall tzinfo –version 0.3.39 –executables –ignore-dependencies &
gem uninstall yard –version 0.8.7.3 –executables –ignore-dependencies &

Then it’s just a matter of (reviewing and) copy-and-pasting those lines (either individually or all at once) into the command prompt and the old gemset will return to its old state.

$ gem list

*** LOCAL GEMS ***

actionmailer (3.2.12)
actionpack (3.2.12)
active_utils (1.0.5)
activemerchant (1.31.1)
activemodel (3.2.12)
activerecord (3.2.12)
activerecord-import (0.3.1)
activeresource (3.2.12)
activesupport (3.2.12)
acts_as_list (0.2.0)
airbrake (3.1.8)
allison (2.0.3)
ar-extensions (0.9.2)
archive-tar-minitar (0.5.2)
arel (3.0.2)
attr_required (0.0.5)
authlogic (3.2.0, 2.1.6)
authlogic_rpx (1.2.0)
aws-sdk (1.8.5)
bourne (1.1.2)
builder (3.0.4)
bundler (1.2.3)
childprocess (0.3.9)
chronic (0.9.1)
climate_control (0.0.3)
cocaine (0.5.1)
coderay (1.0.9)
columnize (0.3.6)
contacts19 (1.2.4)
daemon_controller (1.1.1)
daemons (1.1.9)
echoe (4.6.3)
erubis (2.7.0)
eventmachine (1.0.1)
factory_girl (4.2.0)
faraday (0.8.6)
fastthread (1.0.7)
fattr (2.2.1)
ffi (1.4.0)
gdata_19 (1.1.5)
gem-wrappers (1.2.4)
gemcutter (0.7.1)
guard (1.6.2)
guard-spork (1.5.0)
guard-test (0.7.0)
has_many_polymorphs (2.13)
hashie (2.0.2)
highline (1.6.15)
hike (1.2.1)
hominid (3.0.5)
hpricot (0.8.6)
httmultiparty (0.3.8)
httparty (0.10.2)
httpauth (0.2.0)
httpclient (2.3.3)
i18n (0.6.4)
itunes-search (0.4.1)
journey (1.0.4)
json (1.7.7)
json_pure (1.7.7)
jwt (0.1.6)
linecache19 (0.5.13)
listen (0.7.3)
lumberjack (1.0.2)
macaddr (1.6.1)
mail (2.4.4)
metaclass (0.0.1)
method_source (0.8.1)
mime-types (1.21)
mocha (0.10.5)
money (5.1.1)
multi_json (1.6.1)
multi_xml (0.5.3)
multipart-post (1.2.0)
music_xray_api (0.3.0)
mysql2 (0.3.11)
newrelic_rpm (3.5.8.72)
nokogiri (1.5.6)
oauth (0.4.7)
oauth-plugin (0.4.1)
oauth2 (0.9.1)
options (2.3.0)
paperclip (3.4.1)
passenger (3.0.19)
paypal-express (0.5.3)
polyglot (0.3.3)
pr_geohash (1.0.0)
progress_bar (0.4.0)
pry (0.9.12)
pusher (0.11.3)
rack (1.5.2, 1.4.5)
rack-cache (1.2)
rack-protection (1.4.0)
rack-ssl (1.3.3)
rack-test (0.6.2)
rails (3.2.12)
railties (3.2.12)
rake (10.0.3)
rb-fsevent (0.9.3)
rb-inotify (0.9.0)
rdiscount (2.0.7.1)
rdoc (3.12.2, 3.12.1)
rdoc-data (3.12)
redis (3.0.3)
redis-namespace (1.2.1)
resque (1.23.0)
resque-retry (1.0.0)
resque-scheduler (2.0.0)
resque_unit (0.4.4)
rest-client (1.6.7)
restclient_with_cert (0.0.8)
rmagick (2.13.2)
rpx_now (0.6.23)
rsolr (1.0.8)
ruby-debug-base19x (0.11.30.pre10)
ruby-debug-ide (0.4.17.beta17, 0.4.17.beta16)
ruby-mp3info (0.8)
ruby-mysql (2.9.10)
ruby_core_source (0.1.5)
rubyforge (2.0.4)
rubygems-bundler (1.1.0)
rufus-scheduler (2.0.18)
rvm (1.11.3.5)
sanitize (2.0.3)
shoulda (3.3.2)
shoulda-context (1.0.2)
shoulda-matchers (1.4.2)
signature (0.1.6)
sinatra (1.3.5)
slop (3.4.3)
soundcloud (0.3.1)
spork (0.9.2)
spork-testunit (0.0.8)
sprockets (2.2.2)
sunspot (2.0.0)
sunspot_rails (2.0.0)
systemu (2.5.2)
terminal-table (1.4.5)
test-unit (2.5.4)
thin (1.5.0)
thor (0.17.0)
tilt (1.3.4)
treetop (1.4.12)
tzinfo (0.3.36)
useragent (0.4.16)
uuid (2.3.7)
uuidtools (2.1.3)
validatable (1.6.7)
vegas (0.1.11)
will_paginate (3.0.4)
xml-simple (1.1.2)
yui-on-rails (0.1.16)

How it works

First you set in my command above the threshold time that you consider safe for detecting all the wrong gems (´threshold=”2d”´). It can be anything from s-econds to w-eeks. Then, when you run my command

  1. it detects the current gemdir
    ´dir=”`rvm gemdir`/gems”´
  2. it finds all the directories contained in the gemdir which were modified after the threshold time
    ´find -X “$dir” -type d -maxdepth 1 -mindepth 1 -mtime -“$threshold”´
  3. for each directory, it removes the gemdir prefix
    ´xargs basename´
  4. for each directory, it detects the gem’s name and the gem’s version
    ´sed -e ‘s/-\(\([0-9]\{1,\}.\)*[0-9]\{1,\}\)$/ \1/g’´
  5. for each gem/version, it displays a command for uninstalling that version of that gem in background
    ´sed -e ‘s/\(.*\) \(.*\)/gem uninstall \1 –version \2 –executables –ignore-dependencies \&/g’´

REMEMBER that the current gemset MUST be the messed up one.