Nix Flakes and Line Endings

Q:

My colleague has checked out the same git commit of a nix flake repo as I have, they have no local changes, their git hashes are the same yet their nix hashes aren’t the same as mine. What’s the cause?

I should probably point out that stdenv/setup was complaining about $'\r' but that wasn’t when I realised, it should have been a big hint though.

A (given away by the title):

Their git was configured with core.eol=crlf and core.autocrlf=true

To avoid others scratching their heads, I have a couple of suggestions:

  • add a check in nix when using flakes+git that EOL is LF for all .nix files? (E.g. as reported by git ls-files)
  • add a warning to nix regardless of flakes or git, if the first line-ending in the file is CRLF?
  • add the following .gitattributes file to Nix flake templates:
    *.nix text eol=lf
    

Of course these won’t catch all cases, e.g. when the .nix files are LF but files it pulls in (e.g. scripts) are CRLF. That’s also why I’m posting here instead of just filing potential improvements in said repos, so that maybe one of you reading this will subconsciously remember and if you come across this you’ll spot it.

I was able to spot it because said colleague had vi as the basic vi editor (I have it as a symlink to nvim) so when I did vi flake.nix I saw the ^M characters representing \r but otherwise I could imagine it would have been a real headscratcher.

6 Likes

Oof. Git config affecting the reproducibility of nix isn’t good. While those are reasonable workarounds, maybe nix could override whatever behavior git is configured to follow?

1 Like

It is pretty common for Linux things to fall apart when using CRLF line endings.

That’s true, and if Nix would have fallen over with “unknown character ‘\r’ in line 1 column 3” or similar the problem would have been a lot easier to spot (essentially a warning for this is one of my suggestions) :slight_smile: But as far as I knew there were no CRLF line-endings in the repo (and we were both using Linux). What I was focused at is their git repo (which was the same branch, no local changes according to git status) gave different hashes to my git repo for no apparent reason. I got lucky in spotting the problem reasonably quickly but it could have easily taken a lot longer and probably given quite a bad impression of Nix.

I don’t think Nix was wrong, just that the UX here was not great.

2 Likes

What I’m wondering is whether nix respects user git config for this. Nix flakes are supposed to clone repositories into the nix store, so I would expect inconsistencies due to git settings to disappear - autocrlf is supposed to happen at checkout time, after all, otherwise it would affect the git hashes.

So these symptoms can only appear if nix respects the user’s autocrlf setting, which I don’t think it should for reproducibility’s sake?

3 Likes

This isn’t good. Nix should definitely just ignore any custom git config and stick to the defaults, or perhaps even a minimal pinned configuration to ensure values don’t change after a git version bump?

4 Likes

So I have good news, after a bit of experimentation, I think this was possible because my colleague had Nix installed via single-user mode, I’ll need to have a play with a single-user mode installation to confirm.

I still think that should be considered a bug. Nix goes to great lengths to make sure you are building exactly what you’re expecting from your git repo, to the point that it annoys people with its insistence on having files checked in. The main reason and benefit of this is that you will always build what others get if they check out your branch (and nix can avoid copying dev artefacts, but that’s secondary according to docs I’ve seen). That git config can still somehow break your builds is very unexpected.

If it only breaks in single user installs that’s even worse, because now the way you installed nix is somehow an input into your builds.

That said, as far as bugs go, I imagine this one is relatively straightforward, so it’s hardly the end of the world. Just another quirk of the nix v3 UX that needs to be ironed out (and recorded in an issue in the mean time, if you do get a minimal reproduction up that’d probably be very appreciated).

1 Like

add the following .gitattributes file to Nix flake templates:

I like this, I wish git init added a sensible .gitattributes file by default, it would save a lot of pain for people who don’t know about it.

1 Like

I hit this in WSL2. I’ve filed a bug at nix flakes: git CRLF line endings are not handled · Issue #10640 · NixOS/nix · GitHub.