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 aPodfile.lock
to be generated that indicates the exact version installed (e.g.RestKit 0.10.3
). Thanks to thePodfile.lock
, runningpod 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 inPodfile.lock
unless the dependency is updated in the Podfile orpod update
is called (which will cause a newPodfile.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.