query
On this page

fetchgit

pkgs.fetchgit

Functor
Docs pulled from | This Revision | 35 minutes ago

No reference documentation found yet.

Contribute now!


Contribute
Enhance the ecosystem with your expertise! Contribute to fill the gaps in documentation. Your input can make a difference.

Noogle detected

This is a Functor

Learn about functors

Implementation

The following is the current implementation of this function.

finalAttrs:
      lib.fetchers.withNormalizedHash { } (
        # NOTE Please document parameter additions or changes in
        #   ../../../doc/build-helpers/fetchers.chapter.md
        {
          url,
          tag ? null,
          rev ? null,
          name ? urlToName {
            inherit url;
            rev = lib.revOrTag finalAttrs.revCustom finalAttrs.tag;
            # when rootDir is specified, avoid invalidating the result when rev changes
            append = if rootDir != "" then "-${lib.strings.sanitizeDerivationName rootDir}" else "";
          },
          # When null, will default to: `deepClone || fetchTags`
          leaveDotGit ? null,
          outputHash ? lib.fakeHash,
          outputHashAlgo ? null,
          fetchSubmodules ? true,
          deepClone ? false,
          branchName ? null,
          # When null, will default to: `lib.optional (rootdir != "") rootdir`
          sparseCheckout ? null,
          # When null, will default to: `rootDir != ""`
          nonConeMode ? null,
          nativeBuildInputs ? [ ],
          # Shell code executed before the file has been fetched.  This, in
          # particular, can do things like set NIX_PREFETCH_GIT_CHECKOUT_HOOK to
          # run operations between the checkout completing and deleting the .git
          # directory.
          preFetch ? "",
          # Shell code executed after `git checkout` and before .git directory removal/sanitization.
          postCheckout ? "",
          # Shell code executed after the file has been fetched
          # successfully. This can do things like check or transform the file.
          postFetch ? "",
          preferLocalBuild ? true,
          fetchLFS ? false,
          # Shell code to build a netrc file for BASIC auth
          netrcPhase ? null,
          # Impure env vars (https://nixos.org/nix/manual/#sec-advanced-attributes)
          # needed for netrcPhase
          netrcImpureEnvVars ? [ ],
          passthru ? { },
          meta ? { },
          allowedRequisites ? null,
          # fetch all tags after tree (useful for git describe)
          fetchTags ? false,
          # make this subdirectory the root of the result
          rootDir ? "",
          # GIT_CONFIG_GLOBAL (as a file)
          gitConfigFile ? config.gitConfigFile,
          # Additional stdenvNoCC.mkDerivation arguments.
          # It is typically for derived fetchers to pass down additional arguments,
          # and the specified arguments have lower precedence than other mkDerivation arguments.
          derivationArgs ? { },
        }:

        /*
          NOTE:
          fetchgit has one problem: git fetch only works for refs.
          This is because fetching arbitrary (maybe dangling) commits creates garbage collection risks
          and checking whether a commit belongs to a ref is expensive. This may
          change in the future when some caching is added to git (?)
          Usually refs are either tags (refs/tags/*) or branches (refs/heads/*)
          Cloning branches will make the hash check fail when there is an update.
          But not all patches we want can be accessed by tags.

          The workaround is getting the last n commits so that it's likely that they
          still contain the hash we want.

          for now : increase depth iteratively (TODO)

          real fix: ask git folks to add a
          git fetch $HASH contained in $BRANCH
          facility because checking that $HASH is contained in $BRANCH is less
          expensive than fetching --depth $N.
          Even if git folks implemented this feature soon it may take years until
          server admins start using the new version?
        */

        let
          finalHashHasColon = lib.hasInfix ":" finalAttrs.hash;
          finalHashColonMatch = lib.match "([^:]+)[:](.*)" finalAttrs.hash;
        in

        derivationArgs
        // {
          __structuredAttrs = true;

          inherit name;

          builder = ./builder.sh;
          fetcher = ./nix-prefetch-git;

          nativeBuildInputs = [
            git
            cacert
          ]
          ++ lib.optionals fetchLFS [ git-lfs ]
          ++ nativeBuildInputs;

          hash =
            if outputHashAlgo == null || outputHash == "" || lib.hasPrefix outputHashAlgo outputHash then
              outputHash
            else
              "${outputHashAlgo}:${outputHash}";

          outputHash =
            if finalAttrs.hash == "" then
              lib.fakeHash
            else if finalHashHasColon then
              lib.elemAt finalHashColonMatch 1
            else
              finalAttrs.hash;
          outputHashAlgo = if finalHashHasColon then lib.head finalHashColonMatch else null;
          outputHashMode = "recursive";

          sparseCheckout =
            let
              default = lib.optional (finalAttrs.rootDir != "") finalAttrs.rootDir;
            in
            lib.defaultTo default sparseCheckout;
          sparseCheckoutText =
            # Changed to throw on 2023-06-04
            assert (
              lib.assertMsg (lib.isList finalAttrs.sparseCheckout) "Please provide directories/patterns for sparse checkout as a list of strings. Passing a (multi-line) string is not supported any more."
            );
            assert finalAttrs.nonConeMode -> (finalAttrs.sparseCheckout != [ ]);
            # git-sparse-checkout(1) says:
            # > When the --stdin option is provided, the directories or patterns are read
            # > from standard in as a newline-delimited list instead of from the arguments.
            builtins.concatStringsSep "\n" finalAttrs.sparseCheckout;

          inherit
            url
            fetchLFS
            fetchSubmodules
            deepClone
            branchName
            preFetch
            postCheckout
            postFetch
            fetchTags
            rootDir
            gitConfigFile
            ;
          leaveDotGit =
            if leaveDotGit != null then
              assert fetchTags -> leaveDotGit;
              assert rootDir != "" -> !leaveDotGit;
              leaveDotGit
            else
              deepClone || fetchTags;
          nonConeMode = lib.defaultTo (finalAttrs.rootDir != "") nonConeMode;
          inherit tag;
          revCustom = rev;
          rev = getRevWithTag {
            inherit (finalAttrs) tag;
            rev = finalAttrs.revCustom;
          };

          postHook =
            if netrcPhase == null then
              null
            else
              ''
                ${netrcPhase}
                # required that git uses the netrc file
                mv {,.}netrc
                export NETRC=$PWD/.netrc
                export HOME=$PWD
              '';

          impureEnvVars =
            lib.fetchers.proxyImpureEnvVars
            ++ netrcImpureEnvVars
            ++ [
              "GIT_PROXY_COMMAND"
              "NIX_GIT_SSL_CAINFO"
              "SOCKS_SERVER"

              # This is a parameter intended to be set by setup hooks or preFetch
              # scripts that want per-URL control over HTTP proxies used by Git
              # (if per-URL control isn't needed, `http_proxy` etc. will
              # suffice). It must be a whitespace-separated (with backslash as an
              # escape character) list of pairs like this:
              #
              #   http://domain1/path1 proxy1 https://domain2/path2 proxy2
              #
              # where the URLs are as documented in the `git-config` manual page
              # under `http.<url>.*`, and the proxies are as documented on the
              # same page under `http.proxy`.
              "FETCHGIT_HTTP_PROXIES"
            ];

          outputChecks.out = {
            ${if allowedRequisites != null then "allowedRequisites" else null} = allowedRequisites;
          };

          inherit preferLocalBuild meta;

          env = {
            NIX_PREFETCH_GIT_CHECKOUT_HOOK = finalAttrs.postCheckout;
          };

          passthru = {
            gitRepoUrl = url;
          }
          // passthru;
        }
      )