If you've worked with composer on a project with more than one person, you’ve almost certainly run into the dreaded composer merge conflict with your composer.lock file (and if you haven’t, YOU WILL SOMEDAY).
Here’s a quick tutorial on how to “rapidly” fix this issue!
What does the issue look like?
Typically this crops up when you are running a command like:
$ git rebase upstream/develop
Your local git will attempt to rebase your code against the upstream, and will get confused with the composer.lock file. Here’s a “simple” example of the output:
Merge conflict in composer.lock
Auto-merging composer.json
error: Failed to merge in the changes.
Patch failed at <commit message>
Use 'git am --show-current-patch' to see the failed patch
Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".
If you open up the code and look at the diff, you’ll see things like this:
Now, in this example I’m really lucky because the only thing in the composer.lock file that is funky is the content-hash right at the top. So first we’ll talk about how to fix a “simple” problem and then we’ll dig into more complex ones.
What is the composer.lock file
The composer.lock file is how Composer stores all of the hashes for your specific versions of requirements. It is generated based on your requirements in composer.json.
Unfortunately, because of all the hashes, commit strings, etc. the composer.lock file is very susceptible to this sort of issue. In fact, I work pretty hard when I’m the architect to limit how many people are changing composer files at the same time just to avoid issues like this!
How to Fix a Simple Issue
The above screenshot represents about the simplest possible example.
In this case, all you have to do is:
Get rid of the Git confusion (the HEAD, == and << characters, and everything else on those lines.
Pick one of the two content-hash values (it doesn’t matter which)
Run this command:
$ composer update --lock
Composer will automatically regenerate the proper content hash. Now you can continue your rebase with a valid composer.lock file!
How to Fix a Comple issue
In more common situations, unfortunately, the lock file sometimes has so many different hash changes in it that it’s nearly impossible to straighten out the changes. In this situation, here are a few recommendations:
Instead of rebasing, instead create a new branch off of your upstream integration branch (e.g. upstream/develop) and cherry pick your work into that new branch. Sometimes (but not always) this results in a much cleaner process and the merge conflicts aren’t as bad (or present at all).
Deleting the composer.lock file and running composer update can also be attempted as a last ditch effort. If you’re a return user to my blog, you probably have seen me urge avoidance of a general composer update. This is one of the very rare scenarios where you may have no other choice. Just know that it may change a significant quantity of things in your codebase. Try the cherry picking option first!
In Conclusion
This is exactly why git is so critical! These types of mismatches happen regularly and having a strategy for fixing it when it does happen is the only way to deal. Hopefully you don’t run into it often. But! When you do, I hope this helps.
Dependency trees can be massive, and with the upcoming Drupal 10 release PHP 8.1 could have a significant impact on your project.