Keep `.git` when copying flakes to the store?
Is your feature request related to a problem? Please describe.
I'm working on a project that examines its own git log at build time to extract a list of coauthors to credit for each file. I'd like to use flakes to make dependency management easier. This isn't possible currently because .git isn't copied to the store.
Describe the solution you'd like
I realise that this is non-trivial to do in a way that maintains purity, but maybe we could "clean up" the .git directory in a way that only depends on the revision?
Describe alternatives you've considered
A way to opt out of pure/hermetic evaluation per-flake and just impurely copy the whole .git directory.
Unfortunately I don't see how to do this, because we can't rely on the contents of .git to be binary-reproducible (e.g. due to the details of how git objects are packed/compressed).
Maybe an alternative solution would be to add more information to the sourceInfo attributes? I've also faced issues from not being able to access .git, which I use (with legacy builds) for creating a version string based on the latest tag. Obviously sourceInfo will never be able to encompass all the information one could extract from .git, but it seems like we could do a lot better than what's currently there.
For my use case you'd need to include the entire git history reachable from the given revision, which doesn't sound like a great idea and couples nix to git a lot more than it should be.
I think the most realistic solution would be to just copy .git if we're in --impure mode and the flake has a setting like nixConfig.copyGitDirectory = true;.
Yeah, that's fair. I'd definitely prefer to just have a way to keep .git as well. I guess I don't 100% understand why the sources/inputs need to be binary reproducible and can't have a leaveDotGit option similar to the legacy fetchGit, as long as there's no .git in the outputs.
Unfortunately I don't see how to do this, because we can't rely on the contents of .git to be binary-reproducible (e.g. due to the details of how git objects are packed/compressed).
Related: https://github.com/NixOS/nixpkgs/issues/8567 . It contains some discussion on how to do this.
Not sure if it'd be easy to keep .git in a reproducible way (even just the stripped branch history), but a very interesting usecase for this is that the store paths for flakes to also be flakes themselves.
E.g.: using something like environment.etc."current-nixos".source = self; or ./. in a system flake, then being able to refer include inputs.my-system-flake.url = "path:/etc/current-nixos"; in another flake. Specially important if the system flake is not public or accessible, and pushed with nixos-rebuild --target-host from somewhere else.
Currently, the copied source is NOT a flake on itself, since it's not a git repo.
This issue has been mentioned on NixOS Discourse. There might be relevant details there:
https://discourse.nixos.org/t/drive-version-in-mkderivation-from-git-describe-etc/39325/9
I think the most realistic solution would be to just copy
.gitif we're in--impuremode and the flake has a setting likenixConfig.copyGitDirectory = true;.
This seems reasonable to me and I'd like to be able to do this. I'd like to be able to include my flake's full git history in some bootable media images that I generate in my flake. That seems useful and convenient, even if it is impure.