@@ -552,10 +552,14 @@ struct GitRepoImpl : GitRepo, std::enable_shared_from_this<GitRepoImpl>
552552 /* *
553553 * A 'GitSourceAccessor' with no regard for export-ignore or any other transformations.
554554 */
555- ref<GitSourceAccessor> getRawAccessor (const Hash & rev, bool smudgeLfs = false );
555+ ref<GitSourceAccessor> getRawAccessor (const Hash & rev, bool smudgeLfs = false , bool applyFilters = false );
556556
557- ref<SourceAccessor>
558- getAccessor (const Hash & rev, bool exportIgnore, std::string displayPrefix, bool smudgeLfs = false ) override ;
557+ ref<SourceAccessor> getAccessor (
558+ const Hash & rev,
559+ bool exportIgnore,
560+ std::string displayPrefix,
561+ bool smudgeLfs = false ,
562+ bool applyFilters = false ) override ;
559563
560564 ref<SourceAccessor> getAccessor (const WorkdirInfo & wd, bool exportIgnore, MakeNotAllowedError e) override ;
561565
@@ -746,17 +750,21 @@ struct GitSourceAccessor : SourceAccessor
746750 struct State
747751 {
748752 ref<GitRepoImpl> repo;
753+ git_oid oid;
749754 Object root;
750755 std::optional<lfs::Fetch> lfsFetch = std::nullopt ;
756+ bool applyFilters;
751757 };
752758
753759 Sync<State> state_;
754760
755- GitSourceAccessor (ref<GitRepoImpl> repo_, const Hash & rev, bool smudgeLfs)
761+ GitSourceAccessor (ref<GitRepoImpl> repo_, const Hash & rev, bool smudgeLfs, bool applyFilters_ )
756762 : state_{State{
757763 .repo = repo_,
764+ .oid = hashToOID (rev),
758765 .root = peelToTreeOrBlob (lookupObject (*repo_, hashToOID (rev)).get ()),
759766 .lfsFetch = smudgeLfs ? std::make_optional (lfs::Fetch (*repo_, hashToOID (rev))) : std::nullopt ,
767+ .applyFilters = applyFilters_,
760768 }}
761769 {
762770 }
@@ -784,7 +792,28 @@ struct GitSourceAccessor : SourceAccessor
784792 }
785793 }
786794
787- return std::string ((const char *) git_blob_rawcontent (blob.get ()), git_blob_rawsize (blob.get ()));
795+ if (!state->applyFilters )
796+ return std::string ((const char *) git_blob_rawcontent (blob.get ()), git_blob_rawsize (blob.get ()));
797+ else {
798+ // Apply git filters including potential CRLF conversion
799+ git_buf filtered = GIT_BUF_INIT;
800+ git_blob_filter_options opts = GIT_BLOB_FILTER_OPTIONS_INIT;
801+
802+ opts.attr_commit_id = state->oid ;
803+ opts.flags = GIT_BLOB_FILTER_ATTRIBUTES_FROM_COMMIT;
804+
805+ int error = git_blob_filter (&filtered, blob.get (), path.rel_c_str (), &opts);
806+ if (error != 0 ) {
807+ const git_error * e = git_error_last ();
808+ std::string errorMsg = e ? e->message : " Unknown error" ;
809+ git_buf_dispose (&filtered);
810+ throw Error (" Failed to filter blob: " + errorMsg);
811+ }
812+ std::string result (filtered.ptr , filtered.size );
813+ git_buf_dispose (&filtered);
814+
815+ return result;
816+ }
788817 }
789818
790819 std::string readFile (const CanonPath & path) override
@@ -1307,17 +1336,17 @@ struct GitFileSystemObjectSinkImpl : GitFileSystemObjectSink
13071336 }
13081337};
13091338
1310- ref<GitSourceAccessor> GitRepoImpl::getRawAccessor (const Hash & rev, bool smudgeLfs)
1339+ ref<GitSourceAccessor> GitRepoImpl::getRawAccessor (const Hash & rev, bool smudgeLfs, bool applyFilters )
13111340{
13121341 auto self = ref<GitRepoImpl>(shared_from_this ());
1313- return make_ref<GitSourceAccessor>(self, rev, smudgeLfs);
1342+ return make_ref<GitSourceAccessor>(self, rev, smudgeLfs, applyFilters );
13141343}
13151344
1316- ref<SourceAccessor>
1317- GitRepoImpl::getAccessor ( const Hash & rev, bool exportIgnore, std::string displayPrefix, bool smudgeLfs)
1345+ ref<SourceAccessor> GitRepoImpl::getAccessor (
1346+ const Hash & rev, bool exportIgnore, std::string displayPrefix, bool smudgeLfs, bool applyFilters )
13181347{
13191348 auto self = ref<GitRepoImpl>(shared_from_this ());
1320- ref<GitSourceAccessor> rawGitAccessor = getRawAccessor (rev, smudgeLfs);
1349+ ref<GitSourceAccessor> rawGitAccessor = getRawAccessor (rev, smudgeLfs, applyFilters );
13211350 rawGitAccessor->setPathDisplay (std::move (displayPrefix));
13221351 if (exportIgnore)
13231352 return make_ref<GitExportIgnoreSourceAccessor>(self, rawGitAccessor, rev);
0 commit comments