Accessing .git directory in flake with local source

I have a flake with src = ./.. When the source is copied over to the store, the .git directory is removed.

I know there are issues with keeping that directory around, but is there a way to force this behaviour (like leaveDotGit for fetchFromGitHub)? There are packages around that then remove .git in a postFetch, which seems to be sufficient to restore purity?

The reason I’m wanting to do this is that the crate I’m trying to package runs git as part of the build (to have the hash in the output of --version), and I don’t see another way to make this work.

I remember running into this as well, and as far as I know there is no way to leave the .git directory around for flake inputs atm, unfortunately.

Have you found workarounds for the git rev-parse HEAD scenario, where git is run as part of the build?

At some points people mentionned that it could be possible to implement a tool that fake git. For instance by pre-recording git outputs and playing them in a dummy executable. It may even be possible to semi-automate the process by generating a json file while compiling in a nix shell, and then reuse this in the derivation, but it may be a bit annoying to do everytime we upgrade the package. At least the hash of the derivation is guaranteed to never shift.

1 Like

Use the following in the nativeBuildInputs:

writeShellScriptBin "git" ''
  echo "${theInput.rev}"
''

Extend the script as necessary for more complex “git queries”.

Alternatively patch the build process of the project to not rely on git at all for the version, but instead replace the git run with a hardcoded value based on your version field.

1 Like

The problem is that what I’m trying to access is not an input, it’s src = ./..

Git is used by the to-be-packaged crate to output something like foobar-v2-deadbeef-x86_64-linux-gnu, i.e. to have greater granularity than just the version.

I could manually keep the commit hash in the flake in sync and replicate the logic, but that’s just horrible.

Could nix expose the git hash, maybe as an env var, before deleting the directory? So one could access it from within the package and do stuff with it.

self is also an input. Though then you need to do something like self.rev or "dirty".

1 Like

Thank you so much @NobbZ, that’s a pretty elegant technique :slight_smile: