From 47597bb9fdfff0baf06efdda82cd1eba6510963a Mon Sep 17 00:00:00 2001 From: motoki317 Date: Wed, 27 Nov 2024 20:04:07 +0900 Subject: [PATCH] fix: Load system gitignore patterns --- cmd/root.go | 8 ++++++++ pkg/domain/tree_impl.go | 35 +++++++++++++++++++++++++++++++---- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/cmd/root.go b/cmd/root.go index b758eb8..49c3fea 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -206,6 +206,14 @@ func autoDetermineRefs(repo *git.Repository) (from, to string, err error) { if err != nil { return "", "", errors.Wrapf(err, "resolving worktree") } + wt.Excludes, err = domain.ReadSystemGitignore() + if err != nil { + return "", "", errors.Wrapf(err, "reading system gitignore") + } + wt.Filesystem, err = domain.NewBillyFSGitignore(wt.Filesystem) + if err != nil { + return "", "", errors.Wrapf(err, "making overlay ignore") + } st, err := wt.Status() if err != nil { return "", "", errors.Wrapf(err, "querying worktree status") diff --git a/pkg/domain/tree_impl.go b/pkg/domain/tree_impl.go index e11705f..05406d7 100644 --- a/pkg/domain/tree_impl.go +++ b/pkg/domain/tree_impl.go @@ -3,6 +3,7 @@ package domain import ( "fmt" "github.com/go-git/go-billy/v5" + "github.com/go-git/go-billy/v5/osfs" "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/plumbing/format/gitignore" "github.com/go-git/go-git/v5/plumbing/object" @@ -107,13 +108,42 @@ func (g *goGitCommitTree) Reader(path string) (io.ReadCloser, error) { type goGitIndexTree struct{} // TODO? // billyFSGitignore intercepts billy.Filesystem.Readdir() calls to filter out gitignore-d files. +// +// TODO: Ignoring worktree directly by gitignore patterns results in invalid diff +// - that is, if git-tracked file is present in a gitignore-d directory and is checked out, +// ignoring that file by overlay will result in a 'deleted' diff. type billyFSGitignore struct { billy.Filesystem m gitignore.Matcher } +func ReadSystemGitignore() ([]gitignore.Pattern, error) { + rootFs := osfs.New("/") + system, err := gitignore.LoadSystemPatterns(rootFs) + if err != nil { + return nil, err + } + user, err := gitignore.LoadGlobalPatterns(rootFs) + if err != nil { + return nil, err + } + return append(system, user...), nil +} + +func appendSystemPatterns(fs billy.Filesystem) ([]gitignore.Pattern, error) { + systemPatterns, err := ReadSystemGitignore() + if err != nil { + return nil, err + } + repoPatterns, err := gitignore.ReadPatterns(fs, nil) + if err != nil { + return nil, err + } + return append(systemPatterns, repoPatterns...), nil +} + func NewBillyFSGitignore(fs billy.Filesystem) (billy.Filesystem, error) { - patterns, err := gitignore.ReadPatterns(fs, nil) + patterns, err := appendSystemPatterns(fs) if err != nil { return nil, err } @@ -141,9 +171,6 @@ type goGitWorktree struct { } func newGoGitWorkTree(worktree *git.Worktree, fs billy.Filesystem) (*goGitWorktree, error) { - // TODO: Ignoring worktree directly by gitignore patterns results in invalid diff - // - that is, if git-tracked file is present in a gitignore-d directory and is checked out, - // ignoring that file by overlay will result in a 'deleted' diff. fs, err := NewBillyFSGitignore(fs) if err != nil { return nil, err