Codementor Events

Importance of composer.lock in git

Published Mar 25, 2020
Importance of composer.lock in git

Since Composer is a dependency manager in PHP and its frameworks like Laravel, we know every dependency is managed in the composer.json file of the project, but do you know there is one more important file which handles the dependency more finely.

It is a composer.lock file.

What is composer.lock ?

The file composer.lock maintains dependency in more depth i.e it points to the actual commit of the version of the package we include in our software.

Let’s take an example and understand.

composer.json

{
"require":{
            "laravel/framework": "5.8.*",
          }
}

Here, Suppose a lead developer is telling the composer to install laravel 5.8 with whatever latest minor version, for example 37 that is, the composer will install laravel 5.8.37 locally on the lead developer’s machine. At the same time a composer.lock file will be generated sometime like this:

Composer.lock

...
{
            "name": "laravel/framework",
            "version": "v5.8.37",
            "source": {
                "type": "git",
                "url": "https://github.com/laravel/framework.git",
                "reference": "ce08aaee3a0b8bb58b459b2decf7f25ba7b10fa4"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/laravel/framework/zipball/ce08aaee3a0b8bb58b459b2decf7f25ba7b10fa4",
                "reference": "ce08aaee3a0b8bb58b459b2decf7f25ba7b10fa4",
                "shasum": ""
            },

...

Second part would be more interesting when this lead developer commits only composer.json but not composer.lock. Now when a junior developer clones the repository, it will contain obviously composer.json only and meanwhile there is another stable minor version comes suppose v5.8.40 in laravel main repository, so as soon as junior developer runs composer install / composer update command, the composer will read composer.json file and install Laravel v5.8.40 and generates the  composer.lock locally.

In core essence, there might be many differences in code between laravel v5.8.37 and v5.8.40 though no breaking changes but it obviously defies the concept of version control system because Lead developer working on laravel v5.8.37 while junior developer working on laravel v5.8.40.

So if none of them commits and pushes the composer.lock there may be catastrophic conflicts on both side in future.

Why should we commit composer.lock as well ?

That’s because a locally installed composer will give first preference to composer.lock file over composer.json.

If lock file is not available in vcs the composer will point to composer.json file to install latest dependencies or versions.

The lock file actually points to the commit reference to download code so that originating code and target code remains the same if working in teams. Here you can see composer.lock refers to the actual commit id  ce08aaee3a0b8bb58b459b2decf7f25ba7b10fa4  to download laravel v.5.8.*.

So when lead developer commits this file to the version control system, junior developers would also automatically be using the same code base as the lead developer.

That’s the power of composer.lock, to prevent conflicts among the teams.

Pro tip

If your are at the receiving end, i.e at junior level developer in a team, always use composer install instead composer update because composer install will only install dependencies as per the originating end i.e Lead developer and no modifications will be done in composer.lock file.

Just ask your lead developer if you are having issue in composer install command and tempted to use composer update command just because some random answer on stackoverflow suggests to do so.

Discover and read more posts from Decode Web
get started
post comments2Replies
Lars Moelleken
5 years ago

If you maintain a php library or a helper thingy that you use in different projects, then please don’t commit your “composer.lock”, because it does not really make a lot of sense. You would usually provide a range of versions for each package for which your code works and let the user deal with sorting out the dependency map. Since you have to be able to support that range via testing through some CI anyway, a lock file would get constantly changed, which seems quite redundant.

PS: only the top level lock file defines which version gets installed

Decode Web
5 years ago

Thanks for pointing out I shall update my post accordingly…