e256fedf61b7b137c9bed4020230fbab9a47bfcf

Author
Ayman Bagabas <ayman.bagabas@gmail.com>
Committer
Ayman Bagabas <ayman.bagabas@gmail.com>
Date

Message

fix: don't load non-git repos

Fixes: https://github.com/charmbracelet/soft-serve/issues/108

Diff

 1diff --git a/git/errors.go b/git/errors.go
 2index 51a6ddb05dc570507d02a889ac6b9e3633e3530f..e4c2ec35c8774584bdb34c1e0526cd8c4e66339c 100644
 3--- a/git/errors.go
 4+++ b/git/errors.go
 5@@ -15,4 +15,6 @@ var (
 6 	ErrReferenceNotFound = errors.New("reference not found")
 7 	// ErrRevisionNotExist is returned when a revision is not found.
 8 	ErrRevisionNotExist = git.ErrRevisionNotExist
 9+	// ErrNotAGitRepository is returned when the given path is not a Git repository.
10+	ErrNotAGitRepository = errors.New("not a git repository")
11 )
12diff --git a/git/repo.go b/git/repo.go
13index f2b1d058a926a9da03a115a099fa34c65100ae22..b6d95b56d75c1cd6f18e6224b12d8223ff79daae 100644
14--- a/git/repo.go
15+++ b/git/repo.go
16@@ -18,7 +18,8 @@ var (
17 // Repository is a wrapper around git.Repository with helper methods.
18 type Repository struct {
19 	*git.Repository
20-	Path string
21+	Path   string
22+	IsBare bool
23 }
24 
25 // Clone clones a repository.
26@@ -35,15 +36,34 @@ func Init(path string, bare bool) (*Repository, error) {
27 	return Open(path)
28 }
29 
30+func isInsideWorkTree(r *git.Repository) bool {
31+	out, err := r.RevParse("--is-inside-work-tree")
32+	return err == nil && out == "true"
33+}
34+
35+func isInsideGitDir(r *git.Repository) bool {
36+	out, err := r.RevParse("--is-inside-git-dir")
37+	return err == nil && out == "true"
38+}
39+
40+func gitDir(r *git.Repository) (string, error) {
41+	return r.RevParse("--git-dir")
42+}
43+
44 // Open opens a git repository at the given path.
45 func Open(path string) (*Repository, error) {
46 	repo, err := git.Open(path)
47 	if err != nil {
48 		return nil, err
49 	}
50+	gp, err := gitDir(repo)
51+	if err != nil || (gp != "." && gp != ".git") {
52+		return nil, ErrNotAGitRepository
53+	}
54 	return &Repository{
55 		Repository: repo,
56 		Path:       path,
57+		IsBare:     gp == ".",
58 	}, nil
59 }
60 
61diff --git a/internal/git/git.go b/internal/git/git.go
62index 728304d457ff1da377736390f17842c2f10def48..f755465c30f9c43072a263385756a23a6569d487 100644
63--- a/internal/git/git.go
64+++ b/internal/git/git.go
65@@ -26,8 +26,8 @@ type Repo struct {
66 	patchCache *lru.Cache
67 }
68 
69-// Open opens a Git repository.
70-func (rs *RepoSource) Open(path string) (*Repo, error) {
71+// open opens a Git repository.
72+func (rs *RepoSource) open(path string) (*Repo, error) {
73 	rg, err := git.Open(path)
74 	if err != nil {
75 		return nil, err
76@@ -199,8 +199,9 @@ func (rs *RepoSource) LoadRepo(name string) error {
77 	rs.mtx.Lock()
78 	defer rs.mtx.Unlock()
79 	rp := filepath.Join(rs.Path, name)
80-	r, err := rs.Open(rp)
81+	r, err := rs.open(rp)
82 	if err != nil {
83+		log.Printf("error opening repository %s: %s", name, err)
84 		return err
85 	}
86 	rs.repos[name] = r
87@@ -215,6 +216,9 @@ func (rs *RepoSource) LoadRepos() error {
88 	}
89 	for _, de := range rd {
90 		err = rs.LoadRepo(de.Name())
91+		if err == git.ErrNotAGitRepository {
92+			continue
93+		}
94 		if err != nil {
95 			return err
96 		}