mirror of
https://github.com/NixOS/nix.git
synced 2025-11-28 21:21:00 +01:00
Make it optional to apply git filters
This commit is contained in:
parent
d62f504799
commit
b78a8d9add
4 changed files with 57 additions and 33 deletions
|
|
@ -497,13 +497,15 @@ struct GitRepoImpl : GitRepo, std::enable_shared_from_this<GitRepoImpl>
|
||||||
*/
|
*/
|
||||||
ref<GitSourceAccessor> getRawAccessor(
|
ref<GitSourceAccessor> getRawAccessor(
|
||||||
const Hash & rev,
|
const Hash & rev,
|
||||||
bool smudgeLfs = false);
|
bool smudgeLfs = false,
|
||||||
|
bool applyFilters = false);
|
||||||
|
|
||||||
ref<SourceAccessor> getAccessor(
|
ref<SourceAccessor> getAccessor(
|
||||||
const Hash & rev,
|
const Hash & rev,
|
||||||
bool exportIgnore,
|
bool exportIgnore,
|
||||||
std::string displayPrefix,
|
std::string displayPrefix,
|
||||||
bool smudgeLfs = false) override;
|
bool smudgeLfs = false,
|
||||||
|
bool applyFilters = false) override;
|
||||||
|
|
||||||
ref<SourceAccessor> getAccessor(const WorkdirInfo & wd, bool exportIgnore, MakeNotAllowedError e) override;
|
ref<SourceAccessor> getAccessor(const WorkdirInfo & wd, bool exportIgnore, MakeNotAllowedError e) override;
|
||||||
|
|
||||||
|
|
@ -668,20 +670,22 @@ struct GitSourceAccessor : SourceAccessor
|
||||||
struct State
|
struct State
|
||||||
{
|
{
|
||||||
ref<GitRepoImpl> repo;
|
ref<GitRepoImpl> repo;
|
||||||
std::string gitRev;
|
git_oid oid;
|
||||||
Object root;
|
Object root;
|
||||||
std::optional<lfs::Fetch> lfsFetch = std::nullopt;
|
std::optional<lfs::Fetch> lfsFetch = std::nullopt;
|
||||||
|
bool applyFilters;
|
||||||
};
|
};
|
||||||
|
|
||||||
Sync<State> state_;
|
Sync<State> state_;
|
||||||
|
|
||||||
GitSourceAccessor(ref<GitRepoImpl> repo_, const Hash & rev, bool smudgeLfs)
|
GitSourceAccessor(ref<GitRepoImpl> repo_, const Hash & rev, bool smudgeLfs, bool applyFilters_)
|
||||||
: state_{
|
: state_{
|
||||||
State {
|
State {
|
||||||
.repo = repo_,
|
.repo = repo_,
|
||||||
.gitRev = rev.gitRev(),
|
.oid = hashToOID(rev),
|
||||||
.root = peelToTreeOrBlob(lookupObject(*repo_, hashToOID(rev)).get()),
|
.root = peelToTreeOrBlob(lookupObject(*repo_, hashToOID(rev)).get()),
|
||||||
.lfsFetch = smudgeLfs ? std::make_optional(lfs::Fetch(*repo_, hashToOID(rev))) : std::nullopt,
|
.lfsFetch = smudgeLfs ? std::make_optional(lfs::Fetch(*repo_, hashToOID(rev))) : std::nullopt,
|
||||||
|
.applyFilters = applyFilters_,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
|
@ -709,15 +713,14 @@ struct GitSourceAccessor : SourceAccessor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply git filters including CRLF conversion
|
if (!state->applyFilters)
|
||||||
|
return std::string((const char *) git_blob_rawcontent(blob.get()), git_blob_rawsize(blob.get()));
|
||||||
|
else {
|
||||||
|
// Apply git filters including potential CRLF conversion
|
||||||
git_buf filtered = GIT_BUF_INIT;
|
git_buf filtered = GIT_BUF_INIT;
|
||||||
git_blob_filter_options opts = GIT_BLOB_FILTER_OPTIONS_INIT;
|
git_blob_filter_options opts = GIT_BLOB_FILTER_OPTIONS_INIT;
|
||||||
|
|
||||||
git_oid oid;
|
opts.attr_commit_id = state->oid;
|
||||||
if (git_oid_fromstr(&oid, state->gitRev.c_str()))
|
|
||||||
throw Error("cannot convert '%s' to a Git OID", state->gitRev.c_str());
|
|
||||||
|
|
||||||
opts.attr_commit_id = oid;
|
|
||||||
opts.flags = GIT_BLOB_FILTER_ATTRIBUTES_FROM_COMMIT;
|
opts.flags = GIT_BLOB_FILTER_ATTRIBUTES_FROM_COMMIT;
|
||||||
|
|
||||||
int error = git_blob_filter(&filtered, blob.get(), path.rel_c_str(), &opts);
|
int error = git_blob_filter(&filtered, blob.get(), path.rel_c_str(), &opts);
|
||||||
|
|
@ -732,6 +735,7 @@ struct GitSourceAccessor : SourceAccessor
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string readFile(const CanonPath & path) override
|
std::string readFile(const CanonPath & path) override
|
||||||
{
|
{
|
||||||
|
|
@ -1243,20 +1247,22 @@ struct GitFileSystemObjectSinkImpl : GitFileSystemObjectSink
|
||||||
|
|
||||||
ref<GitSourceAccessor> GitRepoImpl::getRawAccessor(
|
ref<GitSourceAccessor> GitRepoImpl::getRawAccessor(
|
||||||
const Hash & rev,
|
const Hash & rev,
|
||||||
bool smudgeLfs)
|
bool smudgeLfs,
|
||||||
|
bool applyFilters)
|
||||||
{
|
{
|
||||||
auto self = ref<GitRepoImpl>(shared_from_this());
|
auto self = ref<GitRepoImpl>(shared_from_this());
|
||||||
return make_ref<GitSourceAccessor>(self, rev, smudgeLfs);
|
return make_ref<GitSourceAccessor>(self, rev, smudgeLfs, applyFilters);
|
||||||
}
|
}
|
||||||
|
|
||||||
ref<SourceAccessor> GitRepoImpl::getAccessor(
|
ref<SourceAccessor> GitRepoImpl::getAccessor(
|
||||||
const Hash & rev,
|
const Hash & rev,
|
||||||
bool exportIgnore,
|
bool exportIgnore,
|
||||||
std::string displayPrefix,
|
std::string displayPrefix,
|
||||||
bool smudgeLfs)
|
bool smudgeLfs,
|
||||||
|
bool applyFilters)
|
||||||
{
|
{
|
||||||
auto self = ref<GitRepoImpl>(shared_from_this());
|
auto self = ref<GitRepoImpl>(shared_from_this());
|
||||||
ref<GitSourceAccessor> rawGitAccessor = getRawAccessor(rev, smudgeLfs);
|
ref<GitSourceAccessor> rawGitAccessor = getRawAccessor(rev, smudgeLfs, applyFilters);
|
||||||
rawGitAccessor->setPathDisplay(std::move(displayPrefix));
|
rawGitAccessor->setPathDisplay(std::move(displayPrefix));
|
||||||
if (exportIgnore)
|
if (exportIgnore)
|
||||||
return make_ref<GitExportIgnoreSourceAccessor>(self, rawGitAccessor, rev);
|
return make_ref<GitExportIgnoreSourceAccessor>(self, rawGitAccessor, rev);
|
||||||
|
|
|
||||||
|
|
@ -182,7 +182,7 @@ struct GitInputScheme : InputScheme
|
||||||
for (auto & [name, value] : url.query) {
|
for (auto & [name, value] : url.query) {
|
||||||
if (name == "rev" || name == "ref" || name == "keytype" || name == "publicKey" || name == "publicKeys")
|
if (name == "rev" || name == "ref" || name == "keytype" || name == "publicKey" || name == "publicKeys")
|
||||||
attrs.emplace(name, value);
|
attrs.emplace(name, value);
|
||||||
else if (name == "shallow" || name == "submodules" || name == "lfs" || name == "exportIgnore" || name == "allRefs" || name == "verifyCommit")
|
else if (name == "shallow" || name == "submodules" || name == "lfs" || name == "exportIgnore" || name == "allRefs" || name == "verifyCommit" || name == "applyFilters")
|
||||||
attrs.emplace(name, Explicit<bool> { value == "1" });
|
attrs.emplace(name, Explicit<bool> { value == "1" });
|
||||||
else
|
else
|
||||||
url2.query.emplace(name, value);
|
url2.query.emplace(name, value);
|
||||||
|
|
@ -220,6 +220,7 @@ struct GitInputScheme : InputScheme
|
||||||
"keytype",
|
"keytype",
|
||||||
"publicKey",
|
"publicKey",
|
||||||
"publicKeys",
|
"publicKeys",
|
||||||
|
"applyFilters",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -275,6 +276,8 @@ struct GitInputScheme : InputScheme
|
||||||
}
|
}
|
||||||
else if (publicKeys.size() > 1)
|
else if (publicKeys.size() > 1)
|
||||||
url.query.insert_or_assign("publicKeys", publicKeys_to_string(publicKeys));
|
url.query.insert_or_assign("publicKeys", publicKeys_to_string(publicKeys));
|
||||||
|
if (maybeGetBoolAttr(input.attrs, "applyFilters").value_or(false))
|
||||||
|
url.query.insert_or_assign("applyFilters", "1");
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -425,6 +428,11 @@ struct GitInputScheme : InputScheme
|
||||||
return maybeGetBoolAttr(input.attrs, "allRefs").value_or(false);
|
return maybeGetBoolAttr(input.attrs, "allRefs").value_or(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool getApplyFiltersAttr(const Input & input) const
|
||||||
|
{
|
||||||
|
return maybeGetBoolAttr(input.attrs, "applyFilters").value_or(false);
|
||||||
|
}
|
||||||
|
|
||||||
RepoInfo getRepoInfo(const Input & input) const
|
RepoInfo getRepoInfo(const Input & input) const
|
||||||
{
|
{
|
||||||
auto checkHashAlgorithm = [&](const std::optional<Hash> & hash)
|
auto checkHashAlgorithm = [&](const std::optional<Hash> & hash)
|
||||||
|
|
@ -691,7 +699,8 @@ struct GitInputScheme : InputScheme
|
||||||
|
|
||||||
bool exportIgnore = getExportIgnoreAttr(input);
|
bool exportIgnore = getExportIgnoreAttr(input);
|
||||||
bool smudgeLfs = getLfsAttr(input);
|
bool smudgeLfs = getLfsAttr(input);
|
||||||
auto accessor = repo->getAccessor(rev, exportIgnore, "«" + input.to_string() + "»", smudgeLfs);
|
bool applyFilters = getApplyFiltersAttr(input);
|
||||||
|
auto accessor = repo->getAccessor(rev, exportIgnore, "«" + input.to_string() + "»", smudgeLfs, applyFilters);
|
||||||
|
|
||||||
/* If the repo has submodules, fetch them and return a mounted
|
/* If the repo has submodules, fetch them and return a mounted
|
||||||
input accessor consisting of the accessor for the top-level
|
input accessor consisting of the accessor for the top-level
|
||||||
|
|
@ -710,6 +719,7 @@ struct GitInputScheme : InputScheme
|
||||||
attrs.insert_or_assign("ref", submodule.branch);
|
attrs.insert_or_assign("ref", submodule.branch);
|
||||||
attrs.insert_or_assign("rev", submoduleRev.gitRev());
|
attrs.insert_or_assign("rev", submoduleRev.gitRev());
|
||||||
attrs.insert_or_assign("exportIgnore", Explicit<bool>{ exportIgnore });
|
attrs.insert_or_assign("exportIgnore", Explicit<bool>{ exportIgnore });
|
||||||
|
attrs.insert_or_assign("applyFilters", Explicit<bool>{ applyFilters });
|
||||||
attrs.insert_or_assign("submodules", Explicit<bool>{ true });
|
attrs.insert_or_assign("submodules", Explicit<bool>{ true });
|
||||||
attrs.insert_or_assign("lfs", Explicit<bool>{ smudgeLfs });
|
attrs.insert_or_assign("lfs", Explicit<bool>{ smudgeLfs });
|
||||||
attrs.insert_or_assign("allRefs", Explicit<bool>{ true });
|
attrs.insert_or_assign("allRefs", Explicit<bool>{ true });
|
||||||
|
|
@ -854,7 +864,8 @@ struct GitInputScheme : InputScheme
|
||||||
{
|
{
|
||||||
auto makeFingerprint = [&](const Hash & rev)
|
auto makeFingerprint = [&](const Hash & rev)
|
||||||
{
|
{
|
||||||
return rev.gitRev() + (getSubmodulesAttr(input) ? ";s" : "") + (getExportIgnoreAttr(input) ? ";e" : "") + (getLfsAttr(input) ? ";l" : "");
|
// FIXME(gdennis): Update
|
||||||
|
return rev.gitRev() + (getSubmodulesAttr(input) ? ";s" : "") + (getExportIgnoreAttr(input) ? ";e" : "") + (getLfsAttr(input) ? ";l" : "") + (getApplyFiltersAttr(input) ? ";f" : "");
|
||||||
};
|
};
|
||||||
|
|
||||||
if (auto rev = input.getRev())
|
if (auto rev = input.getRev())
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,8 @@ struct GitRepo
|
||||||
const Hash & rev,
|
const Hash & rev,
|
||||||
bool exportIgnore,
|
bool exportIgnore,
|
||||||
std::string displayPrefix,
|
std::string displayPrefix,
|
||||||
bool smudgeLfs = false) = 0;
|
bool smudgeLfs = false,
|
||||||
|
bool applyFilters = false) = 0;
|
||||||
|
|
||||||
virtual ref<SourceAccessor> getAccessor(const WorkdirInfo & wd, bool exportIgnore, MakeNotAllowedError makeNotAllowedError) = 0;
|
virtual ref<SourceAccessor> getAccessor(const WorkdirInfo & wd, bool exportIgnore, MakeNotAllowedError makeNotAllowedError) = 0;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -318,12 +318,18 @@ echo 'test.txt eol=crlf' > "$repo/.gitattributes"
|
||||||
git -C "$repo" add .gitattributes
|
git -C "$repo" add .gitattributes
|
||||||
git -C "$repo" commit -m 'Add eol=crlf to gitattributes'
|
git -C "$repo" commit -m 'Add eol=crlf to gitattributes'
|
||||||
narhash=$(nix eval --raw --impure --expr "(builtins.fetchGit { url = \"$repo\"; ref = \"master\"; }).narHash")
|
narhash=$(nix eval --raw --impure --expr "(builtins.fetchGit { url = \"$repo\"; ref = \"master\"; }).narHash")
|
||||||
|
[[ "$narhash" = "sha256-BBhuj+vOnwCUnk5az22PwAnF32KE1aulWAVfCQlbW7U=" ]]
|
||||||
|
|
||||||
|
narhash=$(nix eval --raw --impure --expr "(builtins.fetchGit { url = \"$repo\"; ref = \"master\"; applyFilters = true; }).narHash")
|
||||||
[[ "$narhash" = "sha256-k7u7RAaF+OvrbtT3KCCDQA8e9uOdflUo5zSgsosoLzA=" ]]
|
[[ "$narhash" = "sha256-k7u7RAaF+OvrbtT3KCCDQA8e9uOdflUo5zSgsosoLzA=" ]]
|
||||||
|
|
||||||
|
|
||||||
# Ensure that NAR hash doesn't depend on user configuration.
|
# Ensure that NAR hash doesn't depend on user configuration.
|
||||||
rm -rf $TEST_HOME/.cache/nix
|
rm -rf $TEST_HOME/.cache/nix
|
||||||
export GIT_CONFIG_GLOBAL="$TEST_ROOT/gitconfig"
|
export GIT_CONFIG_GLOBAL="$TEST_ROOT/gitconfig"
|
||||||
git config --global core.autocrlf true
|
git config --global core.autocrlf true
|
||||||
new_narhash=$(nix eval --raw --impure --expr "(builtins.fetchGit { url = \"$repo\"; ref = \"master\"; }).narHash")
|
narhash=$(nix eval --raw --impure --expr "(builtins.fetchGit { url = \"$repo\"; ref = \"master\"; }).narHash")
|
||||||
[[ "$new_narhash" = "$narhash" ]]
|
[[ "$narhash" = "sha256-BBhuj+vOnwCUnk5az22PwAnF32KE1aulWAVfCQlbW7U=" ]]
|
||||||
|
narhash=$(nix eval --raw --impure --expr "(builtins.fetchGit { url = \"$repo\"; ref = \"master\"; applyFilters = true; }).narHash")
|
||||||
|
[[ "$narhash" = "sha256-k7u7RAaF+OvrbtT3KCCDQA8e9uOdflUo5zSgsosoLzA=" ]]
|
||||||
unset GIT_CONFIG_GLOBAL
|
unset GIT_CONFIG_GLOBAL
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue