Yarn: Should yarn.lock be treated as a binary file in git?

Created on 10 Nov 2016  路  19Comments  路  Source: yarnpkg/yarn

Most helpful comment

The approach that has worked for me so far is this:

git rebase origin/master

When the first conflict arises, I checkout the yarn.lock then re-perform the installation

git checkout origin/master -- yarn.lock
yarn install

This generates a new yarn.lock based on the origin/master version of yarn.lock, but including the changes I made to my package.json. Then it's just a matter of:

git add yarn.lock
git rebase --continue

And I'm back in business.

All 19 comments

No it shouldn't. The file is plain text and there can be merge conflicts in the file that you may need to resolve.

In the documentation is written that the yarn.lock file should not be touched to avoid problems and only yarn itself should deal with it. Then how I resolve a merge conflict?

@kittens is the right thing to do when there are conflicts to blow away the lock file and re-run yarn? Seems to me that'd get what you need?

@dbashford the problem with blowing it away and re-running yarn is that you'll get more changes than you wanted. For example, tilde versions will be upgraded, even though you didn't run yarn upgrade.

@dbashford then it's easier to just put the yarn. lock file in the gitignore

The approach that has worked for me so far is this:

git rebase origin/master

When the first conflict arises, I checkout the yarn.lock then re-perform the installation

git checkout origin/master -- yarn.lock
yarn install

This generates a new yarn.lock based on the origin/master version of yarn.lock, but including the changes I made to my package.json. Then it's just a matter of:

git add yarn.lock
git rebase --continue

And I'm back in business.

Note that even if you're not manually resolving the merge conflicts, having it be a non-binary file means you can see the merge conflicts, which is still valuable information.

Related, even if there are _no_ merge conflicts, can we always assume that git has merged two versions of a yarn.lock file in a way that results in a valid/correct file? It seems wrong to let git update the contents of the file at all if yarn is the only tool that is supposed to manage its content.

I'm not sure that automerging YAML will always result in a valid file, especially given:

  • Multiple major versions in the package that are right next to each other in the lockfile
  • The first line of two neighboring entries can change at the same time while resolving to the same or similar version:
readable-stream@^2.0.0, "readable-stream@^2.0.0 || ^1.1.13", readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.2.2:
  version "2.2.2"
  resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.2.tgz#a9e6fec3c7dda85f8bb1b3ba7028604556fc825e"
  dependencies:
    buffer-shims "^1.0.0"
    core-util-is "~1.0.0"
    inherits "~2.0.1"
    isarray "~1.0.0"
    process-nextick-args "~1.0.6"
    string_decoder "~0.10.x"
    util-deprecate "~1.0.1"

readable-stream@~2.1.4:
  version "2.1.5"
  resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.1.5.tgz#66fa8b720e1438b364681f2ad1a63c618448c9d0"
  dependencies:
    buffer-shims "^1.0.0"
    core-util-is "~1.0.0"
    inherits "~2.0.1"
    isarray "~1.0.0"
    process-nextick-args "~1.0.6"
    string_decoder "~0.10.x"
    util-deprecate "~1.0.1"

@IanVS Thanks for the walkthrough! But @idris's concern still applies to this solution. You will end up upgrading a lot of your dependencies this way, which may be unexpected.

@danny-andrews can you explain how?

When you wipe out yarn.lock and rerun yarn install, the entire yarn.lock gets rebuilt with the newest versions of dependencies that satisfy the version ranges specified in package.json, effectively upgrading any dependency which has changed since last running yarn install.

That's why I suggested git checkout origin/master -- yarn.lock instead of deleting the yarn.lock. That will reset your yarn.lock to the version on master, allowing the yarn install to update only the packages that have changed in your package.json (and their sub-deps, of course).

@IanVS yes, that is the correct way to do it.

Though I'd recommend git checkout -- yarn.lock, which is more general and just resets it to whatever is committed on your current branch.

Good point, @idris. I typically rebase onto master, which is the example I used above, but that won't always be the case.

@IanVS I didn't understand what that command did. That's much better than manually copying and pasting yarn.lock like I have been doing. Thanks for sharing!

This is related: #3544

Isn't @IanVS's approach compatible with having the lockfile be a binary file? If I understand correctly the idea is to never merge, just throw away what you have and replay your yarn install on top of whatever yarn.lock is already present in the branch you're merging into.

here is my approach, to add a bash script

#!/usr/bin/env bash
export GIT_TRACE=1
git checkout origin/master -- Pipfile.lock Pipfile
git commit -m "fetch to branch Pipfile.lock, Pipfile from origin/master" -- Pipfile.lock Pipfile
read  -n 1 -p "Do your changes in Pipfile and press Enter ..."
pipenv lock --clear
git commit -m "re-apply changes to Pipfile.lock, Pipfile" -- Pipfile.lock Pipfile
echo "Done"

Was this page helpful?
0 / 5 - 0 ratings