@@ -7,7 +7,10 @@ import (
77 "runtime"
88 "strings"
99 "testing"
10+ "time"
1011
12+ "github.com/go-git/go-git/v5"
13+ "github.com/go-git/go-git/v5/plumbing/object"
1114 "github.com/rs/zerolog/log"
1215 "github.com/stretchr/testify/assert"
1316)
@@ -707,3 +710,124 @@ func TestDotSnykExclude_isExpired(t *testing.T) {
707710 })
708711 }
709712}
713+
714+ func TestFileFilter_GitTrackedFilesNotFiltered (t * testing.T ) {
715+ t .Run ("committed files are not filtered even if they match gitignore" , func (t * testing.T ) {
716+ tempDir := t .TempDir ()
717+
718+ // Initialize a git repository
719+ repo , err := git .PlainInit (tempDir , false )
720+ assert .NoError (t , err )
721+
722+ // Create a file that will be tracked and matches gitignore pattern
723+ trackedIgnoredFile := filepath .Join (tempDir , "ignored.log" )
724+ createFileInPath (t , trackedIgnoredFile , []byte ("tracked but ignored" ))
725+
726+ // Create another file that will NOT be tracked and matches gitignore pattern
727+ untrackedIgnoredFile := filepath .Join (tempDir , "untracked.log" )
728+ createFileInPath (t , untrackedIgnoredFile , []byte ("untracked and ignored" ))
729+
730+ // Create a regular file that doesn't match gitignore
731+ regularFile := filepath .Join (tempDir , "regular.txt" )
732+ createFileInPath (t , regularFile , []byte ("regular file" ))
733+
734+ // Add and commit the tracked file BEFORE creating gitignore
735+ worktree , err := repo .Worktree ()
736+ assert .NoError (t , err )
737+
738+ _ , err = worktree .Add ("ignored.log" )
739+ assert .NoError (t , err )
740+ _ , err = worktree .Add ("regular.txt" )
741+ assert .NoError (t , err )
742+
743+ _ , err = worktree .Commit ("initial commit" , & git.CommitOptions {
744+ Author : & object.Signature {
745+ Name : "Test" ,
746+ Email : "test@test.com" ,
747+ When : time .Now (),
748+ },
749+ })
750+ assert .NoError (t , err )
751+
752+ // Now create .gitignore that ignores *.log files
753+ gitignorePath := filepath .Join (tempDir , ".gitignore" )
754+ createFileInPath (t , gitignorePath , []byte ("*.log\n " ))
755+
756+ // Create file filter and get filtered files
757+ fileFilter := NewFileFilter (tempDir , & log .Logger )
758+ rules , err := fileFilter .GetRules ([]string {".gitignore" })
759+ assert .NoError (t , err )
760+
761+ allFiles := fileFilter .GetAllFiles ()
762+ filteredFiles := fileFilter .GetFilteredFiles (allFiles , rules )
763+
764+ // Collect filtered files
765+ var filteredFilesList []string
766+ for file := range filteredFiles {
767+ filteredFilesList = append (filteredFilesList , file )
768+ }
769+
770+ // The tracked file (ignored.log) should NOT be filtered out
771+ assert .Contains (t , filteredFilesList , trackedIgnoredFile , "git tracked file should not be filtered even if it matches gitignore" )
772+
773+ // The untracked file (untracked.log) SHOULD be filtered out
774+ assert .NotContains (t , filteredFilesList , untrackedIgnoredFile , "untracked file matching gitignore should be filtered" )
775+
776+ // The regular file should be present
777+ assert .Contains (t , filteredFilesList , regularFile , "regular file should not be filtered" )
778+
779+ // The gitignore file should be present
780+ assert .Contains (t , filteredFilesList , gitignorePath , ".gitignore should not be filtered" )
781+ })
782+
783+ t .Run ("staged but uncommitted files are not filtered even if they match gitignore" , func (t * testing.T ) {
784+ tempDir := t .TempDir ()
785+
786+ // Initialize a git repository
787+ repo , err := git .PlainInit (tempDir , false )
788+ assert .NoError (t , err )
789+
790+ // Create .gitignore first
791+ gitignorePath := filepath .Join (tempDir , ".gitignore" )
792+ createFileInPath (t , gitignorePath , []byte ("*.log\n " ))
793+
794+ // Create a file that matches gitignore pattern but will be staged (git add)
795+ stagedIgnoredFile := filepath .Join (tempDir , "staged.log" )
796+ createFileInPath (t , stagedIgnoredFile , []byte ("staged but ignored" ))
797+
798+ // Create another file that will NOT be staged and matches gitignore pattern
799+ unstagedIgnoredFile := filepath .Join (tempDir , "unstaged.log" )
800+ createFileInPath (t , unstagedIgnoredFile , []byte ("unstaged and ignored" ))
801+
802+ // Stage the file (git add) but do NOT commit
803+ worktree , err := repo .Worktree ()
804+ assert .NoError (t , err )
805+
806+ _ , err = worktree .Add ("staged.log" )
807+ assert .NoError (t , err )
808+ // Note: we do NOT commit here - the file is only staged
809+
810+ // Create file filter and get filtered files
811+ fileFilter := NewFileFilter (tempDir , & log .Logger )
812+ rules , err := fileFilter .GetRules ([]string {".gitignore" })
813+ assert .NoError (t , err )
814+
815+ allFiles := fileFilter .GetAllFiles ()
816+ filteredFiles := fileFilter .GetFilteredFiles (allFiles , rules )
817+
818+ // Collect filtered files
819+ var filteredFilesList []string
820+ for file := range filteredFiles {
821+ filteredFilesList = append (filteredFilesList , file )
822+ }
823+
824+ // The staged file (staged.log) should NOT be filtered out - it's in the index
825+ assert .Contains (t , filteredFilesList , stagedIgnoredFile , "staged file should not be filtered even if it matches gitignore" )
826+
827+ // The unstaged file (unstaged.log) SHOULD be filtered out
828+ assert .NotContains (t , filteredFilesList , unstagedIgnoredFile , "unstaged file matching gitignore should be filtered" )
829+
830+ // The gitignore file should be present
831+ assert .Contains (t , filteredFilesList , gitignorePath , ".gitignore should not be filtered" )
832+ })
833+ }
0 commit comments