From 4ed9ded8ca127922d8286be188eef87efd2c2ab9 Mon Sep 17 00:00:00 2001 From: Arieh Schneier <15041913+AriehSchneier@users.noreply.github.com> Date: Mon, 5 Jun 2023 00:25:35 +1000 Subject: plumbing: gitignore, Allow gitconfig to contain a gitignore relative to any user home. Fixes #578 Signed-off-by: Arieh Schneier <15041913+AriehSchneier@users.noreply.github.com> --- plumbing/format/gitignore/dir.go | 16 +++++++++-- plumbing/format/gitignore/dir_test.go | 52 +++++++++++++++++++++++++++++------ 2 files changed, 57 insertions(+), 11 deletions(-) (limited to 'plumbing/format') diff --git a/plumbing/format/gitignore/dir.go b/plumbing/format/gitignore/dir.go index bf6a1c1..3c4469a 100644 --- a/plumbing/format/gitignore/dir.go +++ b/plumbing/format/gitignore/dir.go @@ -5,6 +5,7 @@ import ( "bytes" "io" "os" + "os/user" "strings" "github.com/go-git/go-billy/v5" @@ -27,9 +28,18 @@ const ( func readIgnoreFile(fs billy.Filesystem, path []string, ignoreFile string) (ps []Pattern, err error) { if strings.HasPrefix(ignoreFile, "~") { - home, err := os.UserHomeDir() - if err == nil { - ignoreFile = strings.Replace(ignoreFile, "~", home, 1) + firstSlash := strings.Index(ignoreFile, "/") + if firstSlash == 1 { + home, err := os.UserHomeDir() + if err == nil { + ignoreFile = strings.Replace(ignoreFile, "~", home, 1) + } + } else if firstSlash > 1 { + username := ignoreFile[1:firstSlash] + userAccount, err := user.Lookup(username) + if err == nil { + ignoreFile = strings.Replace(ignoreFile, ignoreFile[:firstSlash], userAccount.HomeDir, 1) + } } } diff --git a/plumbing/format/gitignore/dir_test.go b/plumbing/format/gitignore/dir_test.go index 4bbba68..465c571 100644 --- a/plumbing/format/gitignore/dir_test.go +++ b/plumbing/format/gitignore/dir_test.go @@ -2,7 +2,9 @@ package gitignore import ( "os" + "os/user" "strconv" + "strings" "github.com/go-git/go-billy/v5" "github.com/go-git/go-billy/v5/memfs" @@ -12,7 +14,8 @@ import ( type MatcherSuite struct { GFS billy.Filesystem // git repository root RFS billy.Filesystem // root that contains user home - RFSR billy.Filesystem // root that contains user home, but with with relative ~/.gitignore_global + RFSR billy.Filesystem // root that contains user home, but with relative ~/.gitignore_global + RFSU billy.Filesystem // root that contains user home, but with relative ~user/.gitignore_global MCFS billy.Filesystem // root that contains user home, but missing ~/.gitconfig MEFS billy.Filesystem // root that contains user home, but missing excludesfile entry MIFS billy.Filesystem // root that contains user home, but missing .gitignore @@ -144,6 +147,37 @@ func (s *MatcherSuite) SetUpTest(c *C) { s.RFSR = fs + // root that contains user home, but with relative ~user/.gitignore_global + fs = memfs.New() + err = fs.MkdirAll(home, os.ModePerm) + c.Assert(err, IsNil) + + f, err = fs.Create(fs.Join(home, gitconfigFile)) + c.Assert(err, IsNil) + _, err = f.Write([]byte("[core]\n")) + c.Assert(err, IsNil) + currentUser, err := user.Current() + c.Assert(err, IsNil) + // remove domain for windows + username := currentUser.Username[strings.Index(currentUser.Username, "\\")+1:] + _, err = f.Write([]byte(" excludesfile = ~" + username + "/.gitignore_global" + "\n")) + c.Assert(err, IsNil) + err = f.Close() + c.Assert(err, IsNil) + + f, err = fs.Create(fs.Join(home, ".gitignore_global")) + c.Assert(err, IsNil) + _, err = f.Write([]byte("# IntelliJ\n")) + c.Assert(err, IsNil) + _, err = f.Write([]byte(".idea/\n")) + c.Assert(err, IsNil) + _, err = f.Write([]byte("*.iml\n")) + c.Assert(err, IsNil) + err = f.Close() + c.Assert(err, IsNil) + + s.RFSU = fs + // root that contains user home, but missing ~/.gitconfig fs = memfs.New() err = fs.MkdirAll(home, os.ModePerm) @@ -255,14 +289,16 @@ func (s *MatcherSuite) TestDir_ReadPatterns(c *C) { } func (s *MatcherSuite) TestDir_ReadRelativeGlobalGitIgnore(c *C) { - ps, err := LoadGlobalPatterns(s.RFSR) - c.Assert(err, IsNil) - c.Assert(ps, HasLen, 2) + for _, fs := range []billy.Filesystem{s.RFSR, s.RFSU} { + ps, err := LoadGlobalPatterns(fs) + c.Assert(err, IsNil) + c.Assert(ps, HasLen, 2) - m := NewMatcher(ps) - c.Assert(m.Match([]string{".idea/"}, true), Equals, false) - c.Assert(m.Match([]string{"*.iml"}, true), Equals, true) - c.Assert(m.Match([]string{"IntelliJ"}, true), Equals, false) + m := NewMatcher(ps) + c.Assert(m.Match([]string{".idea/"}, true), Equals, false) + c.Assert(m.Match([]string{"*.iml"}, true), Equals, true) + c.Assert(m.Match([]string{"IntelliJ"}, true), Equals, false) + } } func (s *MatcherSuite) TestDir_LoadGlobalPatterns(c *C) { -- cgit