Skip to content

Commit dd067af

Browse files
authored
Merge pull request #785 from AriehSchneier/gitignore-relative-any-user
plumbing: gitignore, Allow gitconfig to contain a gitignore relative to any user home. Fixes #578
2 parents 87d35b7 + 4ed9ded commit dd067af

File tree

2 files changed

+57
-11
lines changed

2 files changed

+57
-11
lines changed

plumbing/format/gitignore/dir.go

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"bytes"
66
"io"
77
"os"
8+
"os/user"
89
"strings"
910

1011
"github.com/go-git/go-billy/v5"
@@ -27,9 +28,18 @@ const (
2728
func readIgnoreFile(fs billy.Filesystem, path []string, ignoreFile string) (ps []Pattern, err error) {
2829

2930
if strings.HasPrefix(ignoreFile, "~") {
30-
home, err := os.UserHomeDir()
31-
if err == nil {
32-
ignoreFile = strings.Replace(ignoreFile, "~", home, 1)
31+
firstSlash := strings.Index(ignoreFile, "/")
32+
if firstSlash == 1 {
33+
home, err := os.UserHomeDir()
34+
if err == nil {
35+
ignoreFile = strings.Replace(ignoreFile, "~", home, 1)
36+
}
37+
} else if firstSlash > 1 {
38+
username := ignoreFile[1:firstSlash]
39+
userAccount, err := user.Lookup(username)
40+
if err == nil {
41+
ignoreFile = strings.Replace(ignoreFile, ignoreFile[:firstSlash], userAccount.HomeDir, 1)
42+
}
3343
}
3444
}
3545

plumbing/format/gitignore/dir_test.go

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ package gitignore
22

33
import (
44
"os"
5+
"os/user"
56
"strconv"
7+
"strings"
68

79
"github.com/go-git/go-billy/v5"
810
"github.com/go-git/go-billy/v5/memfs"
@@ -12,7 +14,8 @@ import (
1214
type MatcherSuite struct {
1315
GFS billy.Filesystem // git repository root
1416
RFS billy.Filesystem // root that contains user home
15-
RFSR billy.Filesystem // root that contains user home, but with with relative ~/.gitignore_global
17+
RFSR billy.Filesystem // root that contains user home, but with relative ~/.gitignore_global
18+
RFSU billy.Filesystem // root that contains user home, but with relative ~user/.gitignore_global
1619
MCFS billy.Filesystem // root that contains user home, but missing ~/.gitconfig
1720
MEFS billy.Filesystem // root that contains user home, but missing excludesfile entry
1821
MIFS billy.Filesystem // root that contains user home, but missing .gitignore
@@ -144,6 +147,37 @@ func (s *MatcherSuite) SetUpTest(c *C) {
144147

145148
s.RFSR = fs
146149

150+
// root that contains user home, but with relative ~user/.gitignore_global
151+
fs = memfs.New()
152+
err = fs.MkdirAll(home, os.ModePerm)
153+
c.Assert(err, IsNil)
154+
155+
f, err = fs.Create(fs.Join(home, gitconfigFile))
156+
c.Assert(err, IsNil)
157+
_, err = f.Write([]byte("[core]\n"))
158+
c.Assert(err, IsNil)
159+
currentUser, err := user.Current()
160+
c.Assert(err, IsNil)
161+
// remove domain for windows
162+
username := currentUser.Username[strings.Index(currentUser.Username, "\\")+1:]
163+
_, err = f.Write([]byte(" excludesfile = ~" + username + "/.gitignore_global" + "\n"))
164+
c.Assert(err, IsNil)
165+
err = f.Close()
166+
c.Assert(err, IsNil)
167+
168+
f, err = fs.Create(fs.Join(home, ".gitignore_global"))
169+
c.Assert(err, IsNil)
170+
_, err = f.Write([]byte("# IntelliJ\n"))
171+
c.Assert(err, IsNil)
172+
_, err = f.Write([]byte(".idea/\n"))
173+
c.Assert(err, IsNil)
174+
_, err = f.Write([]byte("*.iml\n"))
175+
c.Assert(err, IsNil)
176+
err = f.Close()
177+
c.Assert(err, IsNil)
178+
179+
s.RFSU = fs
180+
147181
// root that contains user home, but missing ~/.gitconfig
148182
fs = memfs.New()
149183
err = fs.MkdirAll(home, os.ModePerm)
@@ -255,14 +289,16 @@ func (s *MatcherSuite) TestDir_ReadPatterns(c *C) {
255289
}
256290

257291
func (s *MatcherSuite) TestDir_ReadRelativeGlobalGitIgnore(c *C) {
258-
ps, err := LoadGlobalPatterns(s.RFSR)
259-
c.Assert(err, IsNil)
260-
c.Assert(ps, HasLen, 2)
292+
for _, fs := range []billy.Filesystem{s.RFSR, s.RFSU} {
293+
ps, err := LoadGlobalPatterns(fs)
294+
c.Assert(err, IsNil)
295+
c.Assert(ps, HasLen, 2)
261296

262-
m := NewMatcher(ps)
263-
c.Assert(m.Match([]string{".idea/"}, true), Equals, false)
264-
c.Assert(m.Match([]string{"*.iml"}, true), Equals, true)
265-
c.Assert(m.Match([]string{"IntelliJ"}, true), Equals, false)
297+
m := NewMatcher(ps)
298+
c.Assert(m.Match([]string{".idea/"}, true), Equals, false)
299+
c.Assert(m.Match([]string{"*.iml"}, true), Equals, true)
300+
c.Assert(m.Match([]string{"IntelliJ"}, true), Equals, false)
301+
}
266302
}
267303

268304
func (s *MatcherSuite) TestDir_LoadGlobalPatterns(c *C) {

0 commit comments

Comments
 (0)