You have probably noticed a file called Gemfile.lock in your Rails application and have wondered how it works. The file may have even given you trouble when you attempted to push changes to source control. In this article we will discuss what exactly this
Gemfile.lock file is and how it helps your Rails application.
If you ever actually opened the Gemfile.lock file you probably saw a bunch of text that looks a bit like this:
GEM remote: https://rubygems.org/ specs: actionmailer (4.1.5) actionpack (= 4.1.5) actionview (= 4.1.5) mail (~> 2.5.4) actionpack (4.1.5) actionview (= 4.1.5) activesupport (= 4.1.5) rack (~> 1.5.2) rack-test (~> 0.6.2) actionview (4.1.5) activesupport (= 4.1.5) builder (~> 3.1) erubis (~> 2.7.0) activemodel (4.1.5) activesupport (= 4.1.5) builder (~> 3.1) activerecord (4.1.5) activemodel (= 4.1.5) activesupport (= 4.1.5) arel (~> 5.0.0) activesupport (4.1.5) i18n (~> 0.6, >= 0.6.9) json (~> 1.7, >= 1.7.7) minitest (~> 5.1) thread_safe (~> 0.1) tzinfo (~> 1.1) arel (126.96.36.19940414130214) builder (3.2.2) coffee-rails (4.0.1) coffee-script (>= 2.2.0) railties (>= 4.0.0, < 5.0) ... (more gems listed) ... PLATFORMS x86-mingw32 DEPENDENCIES coffee-rails (~> 4.0.0) font-awesome-sass (~> 4.2.0) jbuilder (~> 2.0) jquery-rails rails (= 4.1.5) sass-rails (~> 4.0.3) sdoc (~> 0.4.0) sqlite3 turbolinks tzinfo-data uglifier (>= 1.3.0)
The Gemfile.lock file stores a complete snapshot of every version of every gem your application uses. The reason for this is simple. Let's say you are using Rails 4.1.6 and Rails 5.0 comes out. You don't want this new version to be pushed to your application during the next update. Why? You developed your application using the old version, and the new version may not be compatible with your code. That is why it is also important to check your Gemfile.lock into source control with the rest of your application.
The Gemfile.lock file not only stores exact version information, but bundler USES that version information to rebuild the snapshot on production. If we take a look at our Gemfile (not Gemfile.lock) for example we will see the following line:
gem 'coffee-rails', '~> 4.0.0'
This line could mean 'coffee-rails' version 4.0.0, 4.0.1, etc. Bundler has no way of knowing what version of coffee-rails your application was using when you were developing it. To solve this, you'll see the following corresponding line in your Gemfile.lock:
Now bundler knows that you used version 4.0.1 during development. When this file is pushed to production and you run a bundle install --deployment, bundler will recreate a snapshot of all of the gems that you were using on your development machine. Pretty neat huh?
Now when does this file get updated? Any time you add a new gem to your gemfile (and run a bundle install) or type
bundle update [gem name] your Gemfile.lock will get updated. If you attempt to update the version of a Gem in your Gemfile, bundler will warn you to do a bundle update the next time you try to run a
bundle install. For example, let's say coffee-rails 4.0.2 comes out. changing coffee-rails from 4.0.1 to 4.0.2 will show the following message:
You have requested: coffee-rails ~> 4.0.2 The bundle currently has coffee-rails locked at 4.0.1. Try running `bundle update coffee-rails`
In this case, you would be unable to proceed until you ran
bundle update coffee-rails, which would then update your Gemfile.lock to include the new version of coffee-rails. This is also why it's disastrous to run a
bundle update without specifying a gem. Bundle update rebuilds the entire Gemfile.lock file from scratch, blowing away all of the old versions and replacing them with the latest ones allowed by the Gemfile.
The Gemfile.lock file is designed to save headache and frustration when deploying your application both across development machines as well as to production. It's always a good idea to make sure that you check this file into source control and be aware of how it works. That's it! Thanks for reading!