@@ -357,6 +357,24 @@ func addGitignorePatterns(cfg *Config, path string) error {
357357 }
358358 repoPath := * optRepoPath
359359 debugf ("git repo path for %q: %q" , path , repoPath )
360+
361+ globalExcludesPath , err := gitConfigPath (repoPath , "core.excludesFile" )
362+ if err != nil {
363+ debugf ("Could not determine global Git excludes file: %s" , err )
364+ } else if globalExcludesPath != "" {
365+ if err := addGitignoreFilePatterns (cfg , globalExcludesPath , repoPath ); err != nil {
366+ return err
367+ }
368+ }
369+ infoExcludesPath , err := gitPath (repoPath , "info/exclude" )
370+ if err != nil {
371+ debugf ("Could not determine repository Git excludes file: %s" , err )
372+ } else {
373+ if err := addGitignoreFilePatterns (cfg , infoExcludesPath , repoPath ); err != nil {
374+ return err
375+ }
376+ }
377+
360378 ls := exec .Command ("git" , "ls-files" , "--cached" , "--modified" , "--others" )
361379 ls .Dir = repoPath
362380 stdout := bytes .NewBuffer (nil )
@@ -375,24 +393,56 @@ func addGitignorePatterns(cfg *Config, path string) error {
375393 }
376394 }
377395 for _ , gitignoreRelPath := range gitignorePaths {
378- // TODO: Use `git ls-files` to find all .gitignore paths in the repo, and
379- // incorporate those too.
380396 gitignorePath := filepath .Join (repoPath , gitignoreRelPath )
381- b , err := os .ReadFile (gitignorePath )
382- if err != nil {
383- if os .IsNotExist (err ) {
384- return nil
385- }
397+ if err := addGitignoreFilePatterns (cfg , gitignorePath , filepath .Dir (gitignorePath )); err != nil {
386398 return err
387399 }
388- debugf ("Reading .gitignore patterns from %s" , gitignorePath )
389- debugf ("Raw .gitignore contents: %s" , string (b ))
390- patterns := parseGitignore (b , filepath .Dir (gitignorePath ))
391- cfg .ignorePatterns = append (cfg .ignorePatterns , patterns ... )
392400 }
393401 return nil
394402}
395403
404+ func gitConfigPath (repoPath , key string ) (string , error ) {
405+ cmd := exec .Command ("git" , "config" , "--path" , "--get" , key )
406+ cmd .Dir = repoPath
407+ out , err := cmd .Output ()
408+ if err != nil {
409+ if exitErr , ok := err .(* exec.ExitError ); ok && exitErr .ExitCode () == 1 {
410+ return "" , nil
411+ }
412+ return "" , fmt .Errorf ("git config --get %s failed: %w" , key , err )
413+ }
414+ return strings .TrimSpace (string (out )), nil
415+ }
416+
417+ func gitPath (repoPath , path string ) (string , error ) {
418+ cmd := exec .Command ("git" , "rev-parse" , "--git-path" , path )
419+ cmd .Dir = repoPath
420+ out , err := cmd .Output ()
421+ if err != nil {
422+ return "" , fmt .Errorf ("git rev-parse --git-path %s failed: %w" , path , err )
423+ }
424+ gitPath := strings .TrimSpace (string (out ))
425+ if ! filepath .IsAbs (gitPath ) {
426+ gitPath = filepath .Join (repoPath , gitPath )
427+ }
428+ return gitPath , nil
429+ }
430+
431+ func addGitignoreFilePatterns (cfg * Config , path , parentDirPath string ) error {
432+ b , err := os .ReadFile (path )
433+ if err != nil {
434+ if os .IsNotExist (err ) {
435+ return nil
436+ }
437+ return err
438+ }
439+ debugf ("Reading git ignore patterns from %s" , path )
440+ debugf ("Raw git ignore contents: %s" , string (b ))
441+ patterns := parseGitignore (b , parentDirPath )
442+ cfg .ignorePatterns = append (cfg .ignorePatterns , patterns ... )
443+ return nil
444+ }
445+
396446func parseGitignore (b []byte , parentDirPath string ) []* pattern {
397447 var patterns []* pattern
398448 lines := strings .Split (string (b ), "\n " )
0 commit comments