How I resolve conflicts in yarn.lock

David Mason
4 min readSep 19, 2017

--

So it has happened again. Merge conflicts!

Merge conflicts are rarely fun to resolve. You have to understand what the other author was doing, what you were doing, and how to make the two play nicely together. What do you do if the other author is a machine?

yarn.lock is generated by Yarn. It is Yarn’s business and no one else has business touching it. Not developers, and not other tools, not even Git. In an ideal world Git would call out to Yarn any time yarn.lock needs to be merged. In reality I only hear about it if Git can’t handle it, and that’s when I have a chance to let Yarn fix it… if I can just remember the set of commands I used last time.

The concept sounds straightforward: start with the yarn.lock of the other branch, and have Yarn update it based on the current (merged)package.json. The execution, well… maybe if I did it more often… but I always forget the commands.

So here you are Future David (and maybe some other future people). You’re welcome :)

Overview

Here’s the full process, with a few options at the beginning and end. See sections below for more detail.

# if rebasing (or merging your branch *into* master)
git checkout --ours yarn.lock
# if merging master into your feature branch
git checkout --theirs yarn.lock
# look at the changes in package.json
# (make sure they make sense)
git diff --cached package.json
# if it works, run
yarn
# if `yarn` gives you a frozen lockfile error,
# you need to add the packages from package.json
yarn add <package1>@<version> <package2>@<version> ...
# then commit the fixed yarn.lock
git add yarn.lock

1. Get the base yarn.lock

This is the part I always have to look up. I always forget which way around to do it. I know I need to checkout either “ours” or “theirs”. Which one? It depends whether I’m doing a merge or rebase, and what is merging to where.

Most often I am rebasing my branch onto master, ready to create a Pull Request. In that case the LOCAL commit (“ours”) is master + already-rebased-commits and the REMOTE commit (“theirs”) is my conflicting commit. Confused yet? Essentially it boils down to the following:

# if rebasing your branch onto master,
# or merging your branch into master
git checkout --ours yarn.lock
# if your branch is checked out, and you are merging in master
git checkout --theirs yarn.lock

2. Look at package.json

If package.json has conflicts, you need to fix those so that Yarn can work from the right file. Even if package.json has no conflicts, I still like to see what dependencies have changed — something should be different since yarn.lock is based on package.json. In my case I also need the updated packages and versions for the next step.

git diff --cached package.json

3. Run yarn to update yarn.lock

For most projects you can use the basic yarn command. It will pick up the changes in package.json and add those packages to yarn.lock.

yarn

This fails for me, since I have configured Yarn with --frozen-lockfile. This is to prevent someone updating package.json without updating yarn.lock. We have a larger team and it is inevitable someone will run npm install instead of yarn add, and things start breaking for other team members.

Unfortunately I have created the above scenario myself by checking out the older yarn.lock and having my merged package.json around.

There are 2 ways to update yarn.lock with a frozen lockfile:

  1. Run yarn add <package>@<version> for each change in package.json. You can combine them all to one command. For example, I just ran yarn add babel-jest@21.0.0 jest-cli@21.0.1 jest@21.0.1. This is only a good option with a small number of dependencies. Make sure this does not modify package.json — if it does, something went wrong and you should discard those changes.
  2. Change the config in .yarnrc to say --frozen-lockfile false and remember to change it back after! I don’t like this option because the cost of human error here is too high. I could accidentally leave frozen lockfile disabled, plunging my team back into anarchy!

3. Add yarn.lock and commit

If you have no more conflicts, you can now commit the change. If you have other conflicts you can quickly fix them now (don’t worry, I won’t know you didn’t fix them earlier).

git add yarn.lock
# resolve other conflicts if needed
# if rebasing
git rebase --continue
# if merging
git merge --continue

--

--