Why should you include Podfile.lock under version control?

First of all, I would like to reference the official doc:

What is Podfile.lock

This file is generated after the first run of pod install, and tracks the version of each Pod that was installed. For example, imagine the following dependency specified in the Podfile:

pod 'RestKit'

Running pod install will install the current version of RestKit, causing a Podfile.lock to be generated that indicates the exact version installed (e.g. RestKit 0.10.3). Thanks to the Podfile.lock, running pod install on this hypothetical project at a later point in time on a different machine will still install RestKit 0.10.3 even if a newer version is available. CocoaPods will honour the Pod version in Podfile.lock unless the dependency is updated in the Podfile or pod update is called (which will cause a new Podfile.lock to be generated).


Back to your question:

As you mentioned above, if you're in a setup where everyone is only using pod install command and every dependency version is specified strictly in the podfile and the related podspec, then Podfile.lock seems redundant.

However, I argue this is rare, and not the common usage case of Cocoapods.

For example, we can

  • Ignore specifying version to always use the latest version of the pod, like pod 'RestKit'
  • Use operator ~> 0.1.2 to specify version 0.1.2 and the versions up to 0.2, not including 0.2
  • Add 3rd party pods, which podspecs are not under the control
  • etc

In these case, committing Podfile.lock will be pretty useful.


btw, I think the question title is better changed from

Why should you include Podfile.lock under version control?

to

Why should I include Podfile.lock under version control in this scenario?


The problem is that you have to care about changes in the dependencies.

While semantic versioning should make sure that no breaking change is introduced in minor or patch versions, it can still happen (some commonly used pods are still in version 0.x!)

When that happens and a dependency introduces a breaking change, your application can start crashing or won't even build. And you won't know about it unless you have good automatic tests.

Or, a new developer clones your repository and it won't compile because of a change in dependency.

Or the other way around. Your customer reports a bug for a version and you cannot reproduce it on the current version. Therefore you return to a previous commit from which the version was build. And you cannot reproduce it either because a bug was fixed in a dependency patch.

Actually, it's entirely possible that when you return to a previous commit and reinstall pods, your project won't even compile (fairly common in javascript world if you don't lock your dependencies).

In summary, locking dependencies is a way to achieve deterministic build which does not depend on external changes. With cocoapods it's also fairly common to commit installed pods to your repository (discussion whether this is a good or bad idea is another thing, there are good arguments for both).


Your Podfile specifies the versions of your direct dependencies, but it can allow a bit of ambiguity. For instance, maybe you need version 2.2 of a library, but you don't care if you get 2.2.1 or 2.2.2. The first time you do a pod install, Cocoapods will just get the latest version of 2.2.x.

However, maybe 2.2.2 has a bug that you unknowingly depend on in your app. The maintainer releases 2.2.3, and if you haven't checked in your lock file one of your co-workers or maybe your CI system builds a crashing version of the app and causes all sorts of confusion. (It still works on your machine!)

In addition to locking down the exact versions of your direct dependencies, locking down your transitive dependencies is just as important.

In summary, Podfile.lock makes sure you don't accidentally upgrade the libraries you pull in, while keeping your Podfile concerned only with your direct dependencies.

Tags:

Ios

Cocoapods