Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions src/libexpr/eval.cc
Original file line number Diff line number Diff line change
Expand Up @@ -795,7 +795,10 @@ StorePath EvalState::getZoneStorePath(std::string_view zonePath)
// Eager mode: immediate copy from git ODB
auto repo = getWorldRepo();
// exportIgnore=true: honor .gitattributes for zone content (unlike world accessor)
GitAccessorOptions opts{.exportIgnore = true, .smudgeLfs = false};
// smudgeLfs=true + lfsCommitRev: zones may contain LFS files; the accessor uses a tree
// SHA so we must pass the commit SHA separately for lfs::Fetch attribute lookup.
auto commitHash = Hash::parseNonSRIUnprefixed(requireTectonixGitSha(), HashAlgorithm::SHA1);
GitAccessorOptions opts{.exportIgnore = true, .smudgeLfs = true, .lfsCommitRev = commitHash};
auto accessor = repo->getAccessor(treeSha, opts, "zone");

std::string name = "zone-" + sanitizeZoneNameForStore(zonePath);
Expand Down Expand Up @@ -840,7 +843,10 @@ StorePath EvalState::mountZoneByTreeSha(const Hash & treeSha, std::string_view z
// race to mount the same zone, but we check again before inserting.
auto repo = getWorldRepo();
// exportIgnore=true: honor .gitattributes for zone content (unlike world accessor)
GitAccessorOptions opts{.exportIgnore = true, .smudgeLfs = false};
// smudgeLfs=true + lfsCommitRev: zones may contain LFS files; the accessor uses a tree
// SHA so we must pass the commit SHA separately for lfs::Fetch attribute lookup.
auto commitHash = Hash::parseNonSRIUnprefixed(requireTectonixGitSha(), HashAlgorithm::SHA1);
GitAccessorOptions opts{.exportIgnore = true, .smudgeLfs = true, .lfsCommitRev = commitHash};
auto accessor = repo->getAccessor(treeSha, opts, "zone");

// Generate name from zone path (sanitized for store path requirements)
Expand Down Expand Up @@ -947,8 +953,9 @@ StorePath EvalState::getZoneFromCheckout(std::string_view zonePath, const boost:

auto makeDirtyAccessor = [&]() -> ref<SourceAccessor> {
auto repo = getWorldRepo();
auto commitHash = Hash::parseNonSRIUnprefixed(requireTectonixGitSha(), HashAlgorithm::SHA1);
auto baseAccessor = repo->getAccessor(
getWorldTreeSha(zone), {.exportIgnore = true, .smudgeLfs = false}, "zone");
getWorldTreeSha(zone), {.exportIgnore = true, .smudgeLfs = true, .lfsCommitRev = commitHash}, "zone");
boost::unordered_flat_set<std::string> zoneDirtyFiles;
if (dirtyFiles) {
auto zonePrefix = zone + "/";
Expand Down
6 changes: 4 additions & 2 deletions src/libfetchers/git-utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -799,7 +799,8 @@ ref<GitRepo> GitRepo::openRepo(const std::filesystem::path & path, GitRepo::Opti

std::string GitAccessorOptions::makeFingerprint(const Hash & rev) const
{
return "git:" + rev.gitRev() + (exportIgnore ? ";e" : "") + (smudgeLfs ? ";l" : "");
return "git:" + rev.gitRev() + (exportIgnore ? ";e" : "") + (smudgeLfs ? ";l" : "")
+ (lfsCommitRev ? ";lc:" + lfsCommitRev->gitRev() : "");
}

/**
Expand All @@ -821,7 +822,8 @@ struct GitSourceAccessor : SourceAccessor
: state_{State{
.repo = repo_,
.root = peelToTreeOrBlob(lookupObject(*repo_, hashToOID(rev)).get()),
.lfsFetch = options.smudgeLfs ? std::make_optional(lfs::Fetch(*repo_, hashToOID(rev))) : std::nullopt,
.lfsFetch = options.smudgeLfs ? std::make_optional(lfs::Fetch(*repo_,
options.lfsCommitRev ? hashToOID(*options.lfsCommitRev) : hashToOID(rev))) : std::nullopt,
.options = options,
}}
{
Expand Down
8 changes: 8 additions & 0 deletions src/libfetchers/include/nix/fetchers/git-utils.hh
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ struct GitAccessorOptions
bool smudgeLfs = false;
bool submodules = false; // Currently implemented in GitInputScheme rather than GitAccessor

/**
* When set, use this commit hash for git-lfs attribute lookup instead of
* the tree hash passed to getAccessor(). Required when the accessor is
* created from a tree SHA rather than a commit SHA, since lfs::Fetch needs
* a commit OID for GIT_ATTR_CHECK_INCLUDE_COMMIT to find .gitattributes.
*/
std::optional<Hash> lfsCommitRev;

std::string makeFingerprint(const Hash & rev) const;
};

Expand Down
Loading