Commit 6558e891 authored by ibbem's avatar ibbem
Browse files

lib.fileset.gitTracked: Allow clones of shallow repositories



The only reason shallow clones are not the default in
`builtins.fetchGit` is that `revCount` can't be provided when cloning a
shallow repository. However, `revCount` isn't used or exposed by
`lib.fileset`. Hence, allowing cloning shallow repositories makes
`gitTracked` more general without any drawbacks.

Co-authored-by: default avatarSilvan Mosberger <github@infinisil.com>
parent d3c09ae0
Loading
Loading
Loading
Loading
+18 −1
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@ let
    isAttrs
    isPath
    isString
    nixVersion
    pathExists
    readDir
    split
@@ -17,6 +18,7 @@ let
    attrNames
    attrValues
    mapAttrs
    optionalAttrs
    zipAttrsWith
    ;

@@ -56,6 +58,7 @@ let
    substring
    stringLength
    hasSuffix
    versionAtLeast
    ;

  inherit (lib.trivial)
@@ -840,6 +843,10 @@ rec {
  # https://github.com/NixOS/nix/commit/55cefd41d63368d4286568e2956afd535cb44018
  _fetchGitSubmodulesMinver = "2.4";

  # Support for `builtins.fetchGit` with `shallow = true` was introduced in 2.4
  # https://github.com/NixOS/nix/commit/d1165d8791f559352ff6aa7348e1293b2873db1c
  _fetchGitShallowMinver = "2.4";

  # Mirrors the contents of a Nix store path relative to a local path as a file set.
  # Some notes:
  # - The store path is read at evaluation time.
@@ -894,7 +901,17 @@ rec {
          # However a simpler alternative still would be [a builtins.gitLsFiles](https://github.com/NixOS/nix/issues/2944).
          fetchResult = fetchGit ({
            url = path;
          } // extraFetchGitAttrs);
          }
          # In older Nix versions, repositories were always assumed to be deep clones, which made `fetchGit` fail for shallow clones
          # For newer versions this was fixed, but the `shallow` flag is required.
          # The only behavioral difference is that for shallow clones, `fetchGit` doesn't return a `revCount`,
          # which we don't need here, so it's fine to always pass it.

          # Unfortunately this means older Nix versions get a poor error message for shallow repositories, and there's no good way to improve that.
          # Checking for `.git/shallow` doesn't seem worth it, especially since that's more of an implementation detail,
          # and would also require more code to handle worktrees where `.git` is a file.
          // optionalAttrs (versionAtLeast nixVersion _fetchGitShallowMinver) { shallow = true; }
          // extraFetchGitAttrs);
        in
        # We can identify local working directories by checking for .git,
        # see https://git-scm.com/docs/gitrepository-layout#_description.
+13 −0
Original line number Diff line number Diff line
@@ -1439,6 +1439,19 @@ if [[ -n "$fetchGitSupportsSubmodules" ]]; then
fi
rm -rf -- *

# shallow = true is not supported on all Nix versions
# and older versions don't support shallow clones at all
if [[ "$(nix-instantiate --eval --expr "$prefixExpression (versionAtLeast builtins.nixVersion _fetchGitShallowMinver)")" == true ]]; then
    createGitRepo full
    # Extra commit such that there's a commit that won't be in the shallow clone
    git -C full commit --allow-empty -q -m extra
    git clone -q --depth 1 "file://${PWD}/full" shallow
    cd shallow
    checkGitTracked
    cd ..
    rm -rf -- *
fi

# Go through all stages of Git files
# See https://www.git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository