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

**URL:** https://discourse.nixos.org/t/can-i-use-flakes-within-a-git-repo-without-committing-flake-nix/18196
**Category:** Help
**Created:** [March 15, 2022, 6:26pm UTC](https://discourse.nixos.org/t/can-i-use-flakes-within-a-git-repo-without-committing-flake-nix/18196 "2022-03-15T18:26:46Z")
**Posts on this page:** 11
**Page:** 3

<div class="post-metadata">

### Author: ![TLATER](https://discourse.nixos.org/user_avatar/discourse.nixos.org/tlater/32/4257_2.png) [@TLATER](https://discourse.nixos.org/u/TLATER)
#### Post date: [June 12, 2023, 3:08pm UTC](https://discourse.nixos.org/t/can-i-use-flakes-within-a-git-repo-without-committing-flake-nix/18196/41 "2023-06-12T15:08:39Z")

</div>

> [@NobbZ](#):
>
> `path` just treats the full filesystem location as the base of the flake, `git+file` tries to read the flakes content from a git repository. This is explained in the manual.

To put that even more succinctly:

- `path:<path>` ~= `cp -r <path> /nix/store`
- `git+file:<path>` ~= `git clone file:///<path> /nix/store`

After that, the flake is evaluated in its new path in `/nix/store`. This is how it actually works today, [in the future](https://github.com/NixOS/nix/pull/6530) there will be some fancy mechanism to avoid doing this copy while pretending it has happened.

`cp -r` obviously copies everything, while `git clone` only copies files that have been `git add`-ed.

The `path` variant is generally git-unaware, so you can’t ask nix to use a specific commit or branch instead of what the repository is currently at, and you can’t ask it to exclude the `.git` directory.

You typically _want_ to exclude the `.git` directory for caching (because otherwise _any_ change will bust the cache), so nix defaults to the git protocol if at all possible. Same with other VC systems. The heuristic is deterministic, and very stable, so there’s not really a reason not to do this.

---

<div class="post-metadata">

### Author: ![srghma](https://discourse.nixos.org/user_avatar/discourse.nixos.org/srghma/32/28926_2.png) [@srghma](https://discourse.nixos.org/u/srghma)
#### Post date: [June 13, 2023, 10:20am UTC](https://discourse.nixos.org/t/can-i-use-flakes-within-a-git-repo-without-committing-flake-nix/18196/42 "2023-06-13T10:20:27Z")

</div>

@NobbZ I didn’t uderstand anything new, the philosophical meaning of self-contained was evident without comparing to MRE, I would better see examples and links to the code

E.g. "we need to copy whole dir, bc IF we would not copy THEN … "

But thank you for trying, no insulting, I understand that you cannot see what is in my brain

* * *

Thx @TLATER Now I understand more

But, probably, you should change

`git+file:<path>` ~= `git clone file:///<path> /nix/store`

To

`git+file:<path>` ~= `git clone file:///<path> /nix/git` (because it’s probably [behavior](https://github.com/NixOS/nix/blob/041486b11674e0480ad85f63d262c33a09276ef1/src/libfetchers/git.cc#L48) similar to builtins.fetchGit)

# Question:

Why the full directory is copied to nix store ? `cp -r <path> /nix/store`

Why not? … not copy anything at all? I mean, `nix build path:.` will just read `flake.nix` and `flake.lock` and imported nix files (if they exist) to build required derivations.

---

<div class="post-metadata">

### Author: ![NobbZ](https://discourse.nixos.org/user_avatar/discourse.nixos.org/nobbz/32/7022_2.png) [@NobbZ](https://discourse.nixos.org/u/NobbZ)
#### Post date: [June 13, 2023, 10:30am UTC](https://discourse.nixos.org/t/can-i-use-flakes-within-a-git-repo-without-committing-flake-nix/18196/43 "2023-06-13T10:30:30Z")

</div>

> [@srghma](#):
>
> E.g. "we need to copy whole dir, bc IF we would not copy THEN … "

Wer would not be able to ensure it exists at all, nor that path literals would point at the same location.

`nix build` (or any flake related thing in general) does not imply that the flake is actually local by any means.

Also, if we wouldn’t copy the flakes content to the store, then `./.` would be some `/home/srghma/…` for you, `/home/nmelzer/…` for me, and `/Users/foo/…` for someone running on the mac.

Even worse, how would you resolve a `./.` in a “remote” flake without copying first? Fully rely on a temporary folder created by `mktemp -d` with a random suffix?

All of these do not sound quite reproducible to me, as the state of the system influences what you get out of the build.

> [@srghma](#):
>
> `git+file:<path>` ~= `git clone file:///<path> /nix/git` (because it’s probably [behavior](https://github.com/NixOS/nix/blob/041486b11674e0480ad85f63d262c33a09276ef1/src/libfetchers/git.cc#L48) similar to builtins.fetchGit)

TLater was talking about “conceptually” which skips away **a lot** of the details… What actually happens for `git+file` is **much** more involved than a simple `git clone` (would take far too long for huge repos), instead in reality a `git ls-files` or so is ran in the repo and all files listed get copied over. But as said, TLater did simplify for getting concepts over, rather than implementations. They would be in the way here.

> [@srghma](#):
>
> Why the full directory is copied to nix store ?

Because the lazytree hasn’t been merged yet, as it causes much more troubles than you might think it would.

> [@srghma](#):
>
> not copy anything at all?

See above.

---

<div class="post-metadata">

### Author: ![srghma](https://discourse.nixos.org/user_avatar/discourse.nixos.org/srghma/32/28926_2.png) [@srghma](https://discourse.nixos.org/u/srghma)
#### Post date: [June 13, 2023, 4:46pm UTC](https://discourse.nixos.org/t/can-i-use-flakes-within-a-git-repo-without-committing-flake-nix/18196/44 "2023-06-13T16:46:10Z")

</div>

@NobbZ

I think i now understood (more) the answer on "Why to copy whole repo? What else it needs except `flake.nix` and `flake.lock`? " (after reading edolstra post about flakes on tweag once again)

> flake is simply a source tree (such as a Git repository) containing a file named flake.nix

Because flake is a repo by desing

---

<div class="post-metadata">

### Author: ![NobbZ](https://discourse.nixos.org/user_avatar/discourse.nixos.org/nobbz/32/7022_2.png) [@NobbZ](https://discourse.nixos.org/u/NobbZ)
#### Post date: [June 13, 2023, 5:10pm UTC](https://discourse.nixos.org/t/can-i-use-flakes-within-a-git-repo-without-committing-flake-nix/18196/45 "2023-06-13T17:10:42Z")

</div>

> [@srghma](#):
>
> What else it needs except `flake.nix` and `flake.lock`? "

Whatever is refered to by the flake. Which potentially is everything in its location. Even with lazytree, you will not be able to know in advance what exactly a derivation needs to be able to build. So when you hit a `src = "${self}"` or `src = ./.` you have to copy everything to satisfy the build.

---

<div class="post-metadata">

### Author: ![Dessix](https://discourse.nixos.org/user_avatar/discourse.nixos.org/dessix/32/10504_2.png) [@Dessix](https://discourse.nixos.org/u/Dessix)
#### Post date: [June 24, 2023, 10:39pm UTC](https://discourse.nixos.org/t/can-i-use-flakes-within-a-git-repo-without-committing-flake-nix/18196/46 "2023-06-24T22:39:36Z")

</div>

> [@](#):
>
> Even with lazytree, you will not be able to know in advance what exactly a derivation needs to be able to build. So when you hit a `src = "${self}"` or `src = ./.` you have to copy everything to satisfy the build.

To clarify- under the new abstraction, this _can_ be resolved by triggering after such dynamic paths are encountered, and won’t necessitate performing a full copy regardless of such encounters, right? I just want to make sure we aren’t losing the primary aspect of lazy trees I was looking forward to.

Otherwise, it could be worth looking into a “temporary” nix-store entry that read-only-links the original source until it is sure it was actually utilized.

---

<div class="post-metadata">

### Author: ![domenkozar](https://discourse.nixos.org/user_avatar/discourse.nixos.org/domenkozar/32/38357_2.png) [@domenkozar](https://discourse.nixos.org/u/domenkozar)
#### Post date: [July 8, 2023, 10:43pm UTC](https://discourse.nixos.org/t/can-i-use-flakes-within-a-git-repo-without-committing-flake-nix/18196/47 "2023-07-08T22:43:39Z")

</div>

Note that [https://devenv.sh](https://devenv.sh) lifts the restriction for files needing to be tracked by git.

The downside is that if there are many/big files in the repo, loading the flake takes a lot longer.

One use case is reading `.env` files from Nix, but that file shouldn’t be committed to git, since it contains secrets.

---

<div class="post-metadata">

### Author: ![Hubro](https://discourse.nixos.org/user_avatar/discourse.nixos.org/hubro/32/10414_2.png) [@Hubro](https://discourse.nixos.org/u/Hubro)
#### Post date: [October 20, 2023, 1:13pm UTC](https://discourse.nixos.org/t/can-i-use-flakes-within-a-git-repo-without-committing-flake-nix/18196/48 "2023-10-20T13:13:32Z")

</div>

One thing I’m not entirely clear on after reading this thread:

Is there _any_ downside in using `path:.` when your flake only contains devShells?

I have several projects at work that has nothing to do with Nix, but I like to use flakes to install development tools, and I don’t want to add that to Git.

---

<div class="post-metadata">

### Author: ![TLATER](https://discourse.nixos.org/user_avatar/discourse.nixos.org/tlater/32/4257_2.png) [@TLATER](https://discourse.nixos.org/u/TLATER)
#### Post date: [October 20, 2023, 1:27pm UTC](https://discourse.nixos.org/t/can-i-use-flakes-within-a-git-repo-without-committing-flake-nix/18196/49 "2023-10-20T13:27:50Z")

</div>

> [@Hubro](#):
>
> Is there _any_ downside in using `path:.` when your flake only contains devShells?

You give up on the evaluation cache. For just a handfull of devshells, that’s likely negligible.

---

<div class="post-metadata">

### Author: ![pr06lefs](https://discourse.nixos.org/user_avatar/discourse.nixos.org/pr06lefs/32/2729_2.png) [@pr06lefs](https://discourse.nixos.org/u/pr06lefs)
#### Post date: [November 1, 2023, 10:46pm UTC](https://discourse.nixos.org/t/can-i-use-flakes-within-a-git-repo-without-committing-flake-nix/18196/50 "2023-11-01T22:46:35Z")

</div>

So for the problem where you want to keep a flake.nix to provide a dev environment for a repo. Why not put that repo in a subdirectory and keep your flake.nix/flake.lock/.envrc in the directory above?

Like this:

```auto
embassy-rs-dev/  
   flake.nix <-- my flake just for `nix develop`
   flake.lock
   .envrc
   embassy/ <-- repo I'm working on

```

Could also make embassy-rs-dev into a repo that has embassy as a submodule. Then the versions of the flake.nix and the embassy repo are linked.

**Edit:** It appears that it matters a lot whether embassy-rs-dev is a repo or not. If it is not a repo, I get

`copying ~/bburdette/op-code/embassy-rs-dev`

Every time I `nix develop`. If I specify `nix develop path:.`, it still does the copy.

But if embassy-rs-dev **is** a repo, then nix-develop is instant.

---

<div class="post-metadata">

### Author: ![m9t](https://discourse.nixos.org/letter_avatar_proxy/v4/letter/m/e5b9ba/32.png) [@m9t](https://discourse.nixos.org/u/m9t)
#### Post date: [September 10, 2024, 10:24pm UTC](https://discourse.nixos.org/t/can-i-use-flakes-within-a-git-repo-without-committing-flake-nix/18196/51 "2024-09-10T22:24:33Z")

</div>

Thanks! Creating a parent git repo does the trick indeed!

[Previous page](https://discourse.nixos.org/t/can-i-use-flakes-within-a-git-repo-without-committing-flake-nix/18196.md?page=2)
