I’m experimenting with Nix in my development workflow. I work with lots of existing git repos that I clone to my local system. I’ve started creating flake.nix for various projects for my local development; however, I don’t want to commit them upstream as the rest of my team doesn’t use nix (and I’m not prepared to start convincing them, yet). I use the flake for the dev shell via direnv, not for building the projects (also, yet).
Is there any way that I can use flake.nix in these “third-party” git repos without committing/staging the file?
Yes, there is, the easiest way is to use path:/path/to/project as the flake ref, using path: schema explicitly overrides the heuristics nix usually uses to determine the flake type.
The major problem with that is, that everything will be copied to the store on each access to the flake, even stuff you usually .gitignore.
Tell git to track flake.nix but without adding it:
git add --intent-to-add flake.nix
Tell git to assume that flake.nix doesn’t have any changes:
git update-index --assume-unchanged flake.nix
This way you end up with a clean git status, but flake.nix still being tracked by git and therefore accessible to Nix. The only restriction is that you can’t do git operations which would modify/remove the flake.nix
Thanks both @NobbZ and @Infinisil! I found that the path:/path/to/project trick worked when when invoking nix develop. And, even better, the --intent-to-add/--assume-unchanged trick works perfectly with my local flow with flakes+direnv. Very exciting!
The workaround is to stash before you rebase and then pop the stash again. It’s annoying, but not too bad IME, as I usually have something I’m not ready to commit in my tree that’s getting stashed anyway.
Though this is why I usually use @NobbZpath: suggestion when working with codebases where I can’t commit my flake.nix.
For my specific use case (direnv with flake dev shells), I’ve found that I can point to a flake outside of the current directory. So, I keep all my local dev environment flakes in ~/projects/ and then my .envrc looks like:
use flake ~/projects/foo-project
watch_file ~/projects/foo-project/flake.nix
The external project flake directory doesn’t even have to be a git repository, which is convenient (but maybe a bad habit).
If you do want to disable the git integration then explicitely use path. It is not true that nix will not see things in git, if you do not allow it to use git. Though if you ask for git, you will get git.
We all hope that the error reporting around this will become better with the merge of the lazy tree, or at least that this merge is the foundation for better error reproting.
Why nix flakes require flake.nix and flake.lock to be in git? No other program does this. E.g. the npm install doesn’t require the package-lock.json to be in git
Again, it does not require it. But if you ask nix to use git, it requires the flake.{nix,lock} to be available in the repository. If you do not want to use git, use path.
I have to agree with @srghma to at least some degree, it always felt a bit odd to me that Nix is so tied to Git and I’m not sure those semantics are actually that useful.