Difference between `fetchgit` and `fetchGit`

There are two functions for fetching from a generic git repository, fetchgit from nixpkgs and fetchGit which is a built-in function. What is their difference and is one to be preferred over the other?


builtins.fetchGit was added in 2.0, and from the release notes:

builtins.fetchGit allows Git repositories to be fetched at evaluation time. Thus it differs from the fetchgit function in Nixpkgs, which fetches at build time and cannot be used to fetch Nix expressions during evaluation.


What’s the difference between build time and evaluation time in nix?


nix-instantiate evaluates a Nix expression to produce a derivation. nix-store --realise will then build a derivation and produce the outputs. nix-build is essentially a wrapper around both.

You can also see this in nix repl where running builtins.fetchGit immediately fetches the repo and gives you info about it:

nix-repl> builtins.fetchGit { url = "https://github.com/NixOS/patchelf"; }
{ outPath = "/nix/store/hl1kqvll4km3p8ia9vlgggxjwvsyg6w1-source"; rev = "1bc54f0f74ae3a307aef68e2923661dbf4e1cd76"; revCount = 335; shortRev = "1bc54f0"; }

whereas fetchgit evaluates to a derivation whose builder is a script that uses git to check out the repo, so if you evaluate it in nix repl all you get is a derivation, and you have to actually build it before you get the git repo.


I find it helpful to think of the nix client and nix daemon to be separate things.

  1. The nix client is responsible for evaluating the nix expression language and produces build recipes (.drv files) and fixed-output files. The fixed-output files are when file paths are being used for example. Or any of the builtins.fetch* methods. It then talks to the nix daemon to add those to the store and build them.

  2. The nix daemon is responsible for the whole /nix folder. It has a RPC protocol to receive fixed-output files and .drv files. It can be asked to build derivations… Some of those derivations have a determined fixed output and are also implemented as fetchers.

Even in single-user mode, the nix client and daemon are just in the same process.


I’m thinking that the difference between the fetchGits can be useful depending on whether you’re in a dev environment or staging environment.

Suppose you’re trying to setup CI/CD system using Nix for your organization. Then the CI runners need to use Nix to fetch private source dependencies from your Gitlab server. It one uses SSH keys to do this, then it might be nice to bake in SSH keys into the Nix runner image, but also prevent the user who submits the job from acquiring those keys. This means using instead pkgs.fetchgit or pkgs.fetchgitPrivate.

1 Like

fetchgitPrivate has been removed in master, builtins.fetchGit as it is able to use native auth methods to pull down sources, thus making fetchgitPrivate obsolete.