It is not possible to resolve conflicts of package-lock.json in GitHub's merge tool and you need to do a manual merge.
- Update the
masterbranch with the latest changes:git checkout master git pull - Merge your feature branch into
master:
You will see something like the following message:git merge mybranchAuto-merging package-lock.json CONFLICT (content): Merge conflict in package-lock.json Auto-merging package.json CONFLICT (content): Merge conflict in package.json Automatic merge failed; fix conflicts and then commit the result. - Open your editor (e.g. VSCode) and:
- Carefully resolve conflicts in
package.json(if there is any) - Ignore the conflicts in
package-lock.json
- Carefully resolve conflicts in
- Install packages, which will re-generate
package-lock.json:npm install - "Test drive" your application to make sure the conflicts in
package.jsonhave been resolved correctly. - If the application is able to start up (i.e. there are no missing dependencies), add all changes and finish the merge:
git add --update git commitโ ๏ธ Make sure not to commit the*.origfiles! - If everything looks fine, push to GitHub:
git push
Here is a step by step example, that should make it extra clear:
Problem
My library has three dependencies, package
a,bandc. Mypackage.jsonlooks like this:{ "a": "^1.0.0", "b": "^1.0.0", "c": "^1.0.0" }and my
package-lock.jsonlooks like this (notice missing^):{ "a": "1.0.0", "b": "1.0.0", "c": "1.0.0" }This means, that all three dependencies are "locked" at version
1.0.0.Now, some time has gone by and maintainers of my dependencies have published newer versions. In the npm repository the latest versions are now
a: 1.2.1,b: 1.3.4andc: 1.0.7.I need to bump package
cto version1.0.7to fix some bug. I runnpm install cand merge changes.package.jsonnow looks like this:{ "a": "^1.0.0", "b": "^1.0.0", "c": "^1.0.7" }and
pakcage-lock.jsonlike this:{ "a": "1.0.0", "b": "1.0.0", "c": "1.0.7" }Someone else decides to bump package
bto fix a different bug. They checkout their own branch and runnpm install b, which bumps pakcagebto1.3.4. Theirpackage.jsonlooks like this:{ "a": "^1.0.0", "b": "^1.3.4", "c": "^1.0.0" }and
pakcage-lock.jsonlike this:{ "a": "1.0.0", "b": "1.3.4", "c": "1.0.0" }They try to merge, but run into a conflict. They easily resolve conflict in
package.jsonlike this:{ "a": "^1.0.0", "b": "^1.3.4", "c": "^1.0.7" }So that both package
bandcare at the appropriate version. All that is left to do is to resolve conflict in thepackage-lock.json.And this is where we run into the problem, because the
package-lock.jsonthat we should have locks versions like this:{ "a": "1.0.0", "b": "1.3.4", "c": "1.0.7" }But if you were to run
npm installnow, thepakcage-lock.jsonyou'd end up with would lock these versions:{ "a": "1.2.1", "b": "1.3.4", "c": "1.0.7" }Notice that, while nobody bumped package
a, we ended up with a new version"a": "1.2.1".Explanation
Now why is that? Since the version in our
package.jsonis set to"a": "^1.0.0", the^symbols tells npm to keep both minor and patch version up to date, ie. if there is newer minor or patch version, it will be downloaded and updated inpackage-lock.json.Theoretically, this should not be a problem, because patch should never break anything and minor version update should always be backwards compatible, but since versioning is done by people and people are prone to making mistakes - this does not always hold true.
This is why running
npm installto resolvepackage-lock.jsonconflits is not a bulletproof strategy.I don't have a better solution and I do use this way of fixing the conflicts, but you should be aware of potential problems this may introduce.