Should composer.lock be committed to version control?
I’m a little confused with
composer.lock used in an application with a repository.
I saw many people saying that we should not
composer.lock from the repository.
If I update my libraries in my dev environment, I will have a new
composer.lock but I will not be able to update them into production, will I ?
Won’t it generate conflicts on this file ?
6 Solutions collect form web for “Should composer.lock be committed to version control?”
If you update your libs, you want to commit the lockfile too. It basically states that your project is locked to those specific versions of the libs you are using.
If you commit your changes, and someone pulls your code and updates the dependencies, the lockfile should be unmodified. If it is modified, it means that you have a new version of something.
Having it in the repository assures you that each developer is using the same versions.
For applications/projects: Definitely yes.
The composer documentation states on this (with emphasis):
Commit your application’s composer.lock (along with composer.json) into version control.
Like @meza said: You should commit the lock file so you and your collaborators are working on the same set of versions and prevent you from sayings like “But it worked on my computer”. 😉
For libraries: Probably not.
The composer documentation notes on this matter:
Note: For libraries it is not necessarily recommended to commit the lock file (…)
And states here:
For your library you may commit the composer.lock file if you want to. This can help your team to always test against the same dependency versions. However, this lock file will not have any effect on other projects that depend on it. It only has an effect on the main project.
For libraries I agree with @Josh Johnson’s answer.
After doing it both ways for a few projects my stance is that
composer.lock should not be committed as part of the project. I know that it is easier to do so but please bear with me while I make a case for this.
composer.lock is build metadata which is not part of the project. The state of dependencies should be controlled through how you’re versioning them (either manually or as part of your automated build process) and not arbitrarily by the last developer to update them and commit the lock file.
If you are concerned about your dependencies changing between composer updates then you have a lack of confidence in your versioning scheme. Versions (1.0, 1.1, 1.2, etc) should be immutable and you should avoid “dev-” and “X.*” wildcards outside of initial feature development.
Committing the lock file is a regression for your dependency management system as the dependency version has now gone back to being implicity defined.
Also, your project should never have to be rebuilt or have it’s dependencies reaquired in each environment, especially prod. Your deliverable (tar, zip, phar, a directory, etc) should be immutable and promoted through environments without changing state.
Edit: I knew going in that this wouldn’t be a popular answer, but if you down vote would you be kind enough to provide a reason in the comments that points out the flaw in the answer? Thanks!
- You shouldn’t update your dependencies directly on Production.
- You should version control your composer.lock file.
- You shouldn’t version control your actual dependencies.
1. You shouldn’t update your dependencies directly on Production, because you don’t know how this will affect the stability of your code. There could be bugs introduced with the new dependencies, it might change the way the code behaves affecting your own, it could be incompatible with other dependencies, etc. You should do this in a dev environment, following by proper QA and regression testing, etc.
2. You should version control your composer.lock file, because this stores information about your dependencies and about the dependencies of your dependencies that will allow you to replicate the current state of the code. This is important, because, all your testing and development has been done against specific code. Not caring about the actual version of the code that you have is similar to uploading code changes to your application and not testing them. If you are upgrading your dependencies versions, this should be a willingly act, and you should take the necessary care to make sure everything still works. Losing one or two hours of up time reverting to a previous release version might cost you a lot of money.
One of the arguments that you will see about not needing the composer.lock is that you can set the exact version that you need in your composer.json file, and that in this way, every time someone runs
composer install, it will install them the same code. This is not true, because, your dependencies have their own dependencies, and their configuration might be specified in a format that it allows updates to subversions, or maybe even entire versions.
This means that even when you specify that you want Laravel 4.1.31 in your composer.json, Laravel in its composer.json file might have its own dependencies required as Symfony event-dispatcher: 2.*.
With this kind of config, you could end up with Laravel 4.1.31 with Symfony event-dispatcher 2.4.1, and someone else on your team could have Laravel 4.1.31 with event-dispatcher 2.6.5, it would all depend on when was the last time you ran the composer install.
So, having your composer.lock file in the version system will store the exact version of this sub-dependencies, so, when you and your teammate does a composer install (this is the way that you will install your dependencies based on a composer.lock) you both will get the same versions.
What if you wanna update? Then in your dev environment run:
composer update, this will generate a new composer.lock file (if there is something new) and after you test it, and QA test and regression test it and stuff. You can push it for everyone else to download the new composer.lock, since its safe to upgrade.
3. You shouldn’t version control your actual dependencies, because it makes no sense. With the composer.lock you can install the exact version of the dependencies and you wouldn’t need to commit them. Why would you add to your repo 10000 files of dependencies, when you are not supposed to be updating them. If you require to change one of this, you should fork it and make your changes there. And if you are worried about having to fetch the actual dependencies each time of a build or release, composer has different ways to alleviate this issue, cache, zip files, etc.
You then commit the
composer.jsonto your project and everyone else on your team can run composer install to install your project dependencies.
The point of the lock file is to record the exact versions that are installed so they can be re-installed. This means that if you have a version spec of 1.* and your co-worker runs composer update which installs 1.2.4, and then commits the composer.lock file, when you composer install, you will also get 1.2.4, even if 1.3.0 has been released. This ensures everybody working on the project has the same exact version.
This means that if anything has been committed since the last time a composer install was done, then, without a lock file, you will get new third-party code being pulled down.
Again, this is a problem if you’re concerned about your code breaking. And it’s one of the reasons why it’s important to think about Composer as being centered around the composer.lock file.
Source: Composer: It’s All About the Lock File.
Commit your application’s composer.lock (along with composer.json) into version control. This is important because the install command checks if a lock file is present, and if it is, it downloads the versions specified there (regardless of what composer.json says). This means that anyone who sets up the project will download the exact same version of the dependencies. Your CI server, production machines, other developers in your team, everything and everyone runs on the same dependencies, which mitigates the potential for bugs affecting only some parts of the deployments. Even if you develop alone, in six months when reinstalling the project you can feel confident the dependencies installed are still working even if your dependencies released many new versions since then.
Source: Composer – Basic Usage.
If you’re concerned about your code breaking, you should commit the
composer.lock to your version control system to ensure all your project collaborators are using the same version of the code. Without a lock file, you will get new third-party code being pulled down each time.
The exception is when you use a meta apps, libraries where the dependencies should be updated on install (like the Zend Framework 2 Skeleton App). So the aim is to grab the latest dependencies each time when you want to start developing.
Source: Composer: It’s All About the Lock File
See also: What are the differences between composer update and composer install?