Can I use flakes within a git repo without committing flake.nix?

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?

6 Likes

You don’t have to commit it; you just have to git add it.

@mhwombat true, though its a bit tedious to add during dev, then un-stage when committing to the repo, then re-add to continue to dev.

6 Likes

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.

2 Likes

Here’s a neat workaround:

  • 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

This sounds perfect for a local workaround

41 Likes

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!

1 Like

The only restriction is that you can’t do git operations which would modify/remove the flake.nix

For example, git pull --rebase will no longer work if you do this.

5 Likes

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 @NobbZ path: suggestion when working with codebases where I can’t commit my flake.nix.

3 Likes

I am trying the following approach. Stage with direnv, use flake, restore. That is my .envrc:

git add flake.nix flake.lock
use flake
git restore --staged flake.nix flake.lock
7 Likes

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).

9 Likes

It doesn’t even need to be a local file…

use flake github:nobbz/nixos-config works as well…

5 Likes

I don’t love the --intent-to-add option since it kinda requires me to remember the state (now invisible to git).

I generally prefer to keep things explicit, so I use

git stash push -m "nix flake files" -- flake.nix flake.lock

and

git stash pop

since recent git versions allow to stash single files. An alias make it less painful. This requires some care as well, but I like it better.

2 Likes

Would be nice if the coupling to git was something you needed to explicitly opt into using a command line flag.

What if instead of a coupling to git by default, we have a .flakeignore, similar to .dockerignore and .gitignore?

2 Likes

Yeah. I hate this “feature”.

I am frequently working on patches for someone else’s repo and just using develop to give me an environment I can test build it on my NixOS machine.

They aren’t going to take a patch that adds a flake file, so I have to keep adding and removing it every time I want to work on it. Ugh.

6 Likes

You might be surprised. I recently searched for PRs adding flake.nix on GitHub and most maintainers didn’t mind.

1 Like

horrible design (more about Flakes and Git integration )

4 Likes

That document spreads misinformation.

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.

1 Like

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

1 Like

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.

1 Like

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.

3 Likes