-
Notifications
You must be signed in to change notification settings - Fork 13
fixes to file.go in codewalker for issues #133 and #404 in SCC repository, #22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
817ae1b
d49063e
215ac90
b5c4679
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -353,7 +353,7 @@ func (f *FileWalker) walkDirectoryRecursive(iteration int, | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return err | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| gitIgnore := gitignore.New(bytes.NewReader(c), abs, nil) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| gitIgnore := gitignore.New(bytes.NewReader(c), filepath.ToSlash(abs), nil) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| gitignores = append(gitignores, gitIgnore) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -435,6 +435,22 @@ func (f *FileWalker) walkDirectoryRecursive(iteration int, | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if !f.IgnoreGitIgnore { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| gitdir := os.Getenv("GIT_DIR") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if gitdir == "" { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| gitdir = filepath.Join(directory, ".git") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| file := filepath.Join(gitdir, "info", "exclude") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if content, err := os.ReadFile(file); err == nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| abs, err := filepath.Abs(directory) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if err == nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| gitExclude := gitignore.New(bytes.NewReader(content), abs, nil) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if gitExclude != nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| gitignores = append(gitignores, gitExclude) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+440
to
+450
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if gitdir == "" { | |
| gitdir = filepath.Join(directory, ".git") | |
| } | |
| file := filepath.Join(gitdir, "info", "exclude") | |
| if content, err := os.ReadFile(file); err == nil { | |
| abs, err := filepath.Abs(directory) | |
| if err == nil { | |
| gitExclude := gitignore.New(bytes.NewReader(content), abs, nil) | |
| if gitExclude != nil { | |
| gitignores = append(gitignores, gitExclude) | |
| } | |
| shouldLoadGitExclude := gitdir != "" | |
| if gitdir == "" { | |
| gitdir = filepath.Join(directory, ".git") | |
| if info, err := os.Stat(gitdir); err == nil && info.IsDir() { | |
| shouldLoadGitExclude = true | |
| } | |
| } | |
| if shouldLoadGitExclude { | |
| file := filepath.Join(gitdir, "info", "exclude") | |
| if content, err := f.osReadFile(file); err == nil { | |
| abs, err := filepath.Abs(directory) | |
| if err != nil { | |
| if !f.errorsHandler(err) { | |
| return err | |
| } | |
| } else { | |
| abs = filepath.ToSlash(abs) | |
| gitExclude := gitignore.New(bytes.NewReader(content), abs, nil) | |
| if gitExclude != nil { | |
| gitignores = append(gitignores, gitExclude) | |
| } | |
| } | |
| } else if !errors.Is(err, fs.ErrNotExist) { | |
| if !f.errorsHandler(err) { | |
| return err | |
| } |
Copilot
AI
Apr 20, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
New behavior is introduced here to load and apply $GIT_DIR/info/exclude, but there’s no test exercising it. Since file_test.go already has extensive coverage for ignore handling, please add a unit test that creates a temp repo with .git/info/exclude containing patterns and asserts those files are skipped (including a case where IgnoreGitIgnore is true/false, and optionally when GIT_DIR is set).
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1500,3 +1500,134 @@ func TestSkipHandlerNilIsIgnored(t *testing.T) { | |
| t.Error("Expected 0 files") | ||
| } | ||
| } | ||
|
|
||
| func TestCRLFGitignore(t *testing.T) { | ||
| dir := t.TempDir() | ||
|
|
||
| content := "vendor/\r\n*.log\r\nbuild/\r\n" | ||
| if err := os.WriteFile(filepath.Join(dir, ".gitignore"), []byte(content), 0644); err != nil { | ||
| t.Fatal(err) | ||
| } | ||
|
|
||
| os.MkdirAll(filepath.Join(dir, "vendor", "pkg"), 0755) | ||
| os.WriteFile(filepath.Join(dir, "vendor", "pkg", "lib.go"), []byte("package p"), 0644) | ||
| os.WriteFile(filepath.Join(dir, "debug.log"), []byte("log"), 0644) | ||
| os.WriteFile(filepath.Join(dir, "main.go"), []byte("package main"), 0644) | ||
|
|
||
| queue := make(chan *File, 100) | ||
| walker := NewFileWalker(dir, queue) | ||
| go walker.Start() | ||
|
|
||
| var found []string | ||
| for f := range queue { | ||
| rel, _ := filepath.Rel(dir, f.Location) | ||
| found = append(found, filepath.ToSlash(rel)) | ||
| } | ||
|
|
||
| foundMain := false | ||
| for _, p := range found { | ||
| if p == "main.go" { | ||
| foundMain = true | ||
| } | ||
| if strings.HasPrefix(p, "vendor/") { | ||
| t.Errorf("vendor/ should be gitignored but got: %s", p) | ||
| } | ||
| if strings.HasSuffix(p, ".log") { | ||
| t.Errorf("*.log should be gitignored but got: %s", p) | ||
| } | ||
| } | ||
| if !foundMain { | ||
| t.Error("expected main.go to be found but it was not") | ||
| } | ||
| } | ||
|
|
||
| func TestWindowsPathNormalization(t *testing.T) { | ||
| dir := t.TempDir() | ||
|
|
||
| os.WriteFile(filepath.Join(dir, ".gitignore"), []byte("build/\n"), 0644) | ||
| os.MkdirAll(filepath.Join(dir, "build"), 0755) | ||
| os.WriteFile(filepath.Join(dir, "build", "out.bin"), []byte("bin"), 0644) | ||
| os.WriteFile(filepath.Join(dir, "main.go"), []byte("package main"), 0644) | ||
|
Comment on lines
+1544
to
+1550
|
||
|
|
||
| queue := make(chan *File, 100) | ||
| walker := NewFileWalker(dir, queue) | ||
| go walker.Start() | ||
|
|
||
| var found []string | ||
| for f := range queue { | ||
| rel, _ := filepath.Rel(dir, f.Location) | ||
| found = append(found, filepath.ToSlash(rel)) | ||
| } | ||
|
|
||
| foundMain := false | ||
| for _, p := range found { | ||
| if p == "main.go" { | ||
| foundMain = true | ||
| } | ||
| if strings.HasPrefix(p, "build/") { | ||
| t.Errorf("build/ should be gitignored but got: %s", p) | ||
| } | ||
| } | ||
| if !foundMain { | ||
| t.Error("expected main.go to be found but it was not") | ||
| } | ||
| } | ||
| func TestGitInfoExclude(t *testing.T) { | ||
| testDir, _ := os.MkdirTemp(os.TempDir(), randSeq(10)) | ||
| _ = os.MkdirAll(filepath.Join(testDir, ".git", "info"), 0755) | ||
| _ = os.WriteFile(filepath.Join(testDir, ".git", "info", "exclude"), []byte("secret.txt\n"), 0644) | ||
| _, _ = os.Create(filepath.Join(testDir, "secret.txt")) | ||
| _, _ = os.Create(filepath.Join(testDir, "visible.txt")) | ||
|
|
||
| fileListQueue := make(chan *File, 10) | ||
| walker := NewFileWalker(testDir, fileListQueue) | ||
| walker.IgnoreGitIgnore = false | ||
| _ = walker.Start() | ||
|
|
||
| count := 0 | ||
| for range fileListQueue { | ||
| count++ | ||
| } | ||
|
|
||
| if count != 1 { | ||
| t.Errorf("expected 1 file but got %d", count) | ||
| } | ||
| } | ||
| func TestGitInfoExcludeNoGitDir(t *testing.T) { | ||
| testDir, _ := os.MkdirTemp(os.TempDir(), randSeq(10)) | ||
| _, _ = os.Create(filepath.Join(testDir, "visible.txt")) | ||
|
|
||
| fileListQueue := make(chan *File, 10) | ||
| walker := NewFileWalker(testDir, fileListQueue) | ||
| walker.IgnoreGitIgnore = false | ||
| _ = walker.Start() | ||
|
|
||
| count := 0 | ||
| for range fileListQueue { | ||
| count++ | ||
| } | ||
|
|
||
| if count != 1 { | ||
| t.Errorf("expected 1 file but got %d", count) | ||
| } | ||
| } | ||
| func TestGitInfoExcludeIgnoredWhenGitIgnoreDisabled(t *testing.T) { | ||
| testDir, _ := os.MkdirTemp(os.TempDir(), randSeq(10)) | ||
| _ = os.MkdirAll(filepath.Join(testDir, ".git", "info"), 0755) | ||
| _ = os.WriteFile(filepath.Join(testDir, ".git", "info", "exclude"), []byte("secret.txt\n"), 0644) | ||
| _, _ = os.Create(filepath.Join(testDir, "secret.txt")) | ||
|
|
||
| fileListQueue := make(chan *File, 10) | ||
| walker := NewFileWalker(testDir, fileListQueue) | ||
| walker.IgnoreGitIgnore = true | ||
| _ = walker.Start() | ||
|
|
||
| count := 0 | ||
| for range fileListQueue { | ||
| count++ | ||
| } | ||
|
|
||
| if count != 1 { | ||
| t.Errorf("expected 1 file but got %d", count) | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -238,7 +238,8 @@ func (r *repository) Relative(path string, isdir bool) Match { | |||||||
| // move up the path hierarchy | ||||||||
| var _last string | ||||||||
| for { | ||||||||
| _file := filepath.Join(r._base, _parent, r._file) | ||||||||
| _file := r._base + string(os.PathSeparator) + | ||||||||
| filepath.FromSlash(_parent) + string(os.PathSeparator) + r._file | ||||||||
|
Comment on lines
+241
to
+242
|
||||||||
| _file := r._base + string(os.PathSeparator) + | |
| filepath.FromSlash(_parent) + string(os.PathSeparator) + r._file | |
| _file := filepath.Join(r._base, _parent, r._file) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,12 @@ | ||
| github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 h1:y5HC9v93H5EPKqaS1UYVg1uYah5Xf51mBfIoWehClUQ= | ||
| github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964/go.mod h1:Xd9hchkHSWYkEqJwUGisez3G1QY8Ryz0sdWrLPMGjLk= | ||
| github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | ||
| github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
| github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||
| github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||
| github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= | ||
| github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= | ||
| golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= | ||
| golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= | ||
| gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= | ||
| gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only the
.gitignoreignore instance is created with a slash-normalized base (filepath.ToSlash(abs)), but other ignore instances in this function (.ignore,.gitmodules,CustomIgnore,CustomIgnorePatterns, and the newinfo/excludeignore) still useabsdirectly. WithMatchIsDirnow normalizing paths to slash form, any ignore with a non-normalized base will fail theHasPrefixcheck on Windows and effectively stop matching. Normalize the base consistently for allgitignore.New(...)calls (or normalize inside the gitignore library constructors).