-
Notifications
You must be signed in to change notification settings - Fork 9
/
git.go
122 lines (108 loc) 路 3.2 KB
/
git.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package content
import (
"path/filepath"
"strings"
"github.com/Equationzhao/g/internal/align"
constval "github.com/Equationzhao/g/internal/const"
"github.com/Equationzhao/g/internal/git"
"github.com/Equationzhao/g/internal/item"
"github.com/Equationzhao/g/internal/render"
)
type GitEnabler struct {
cache git.Cache
Path git.RepoPath
}
func (g *GitEnabler) InitCache(repo git.RepoPath) {
g.cache.Set(repo, git.DefaultInit(repo)())
}
func NewGitEnabler() *GitEnabler {
return &GitEnabler{
cache: git.GetCache(),
}
}
const GitStatus = constval.NameOfGitStatus
func (g *GitEnabler) Enable(renderer *render.Renderer) ContentOption {
isOrIsParentOf := func(parent, child string) bool {
if parent == child {
return true
}
if strings.HasPrefix(child, parent+string(filepath.Separator)) {
return true
}
return false
}
return func(info *item.FileInfo) (string, string) {
gits, ok := g.cache.Get(g.Path)
if ok {
topLevel, err := git.GetTopLevel(g.Path)
if err != nil {
return gitByName(git.Unmodified, renderer) + gitByName(git.Unmodified, renderer), GitStatus
}
rel, err := filepath.Rel(topLevel, info.FullPath)
if err != nil {
return gitByName(git.Unmodified, renderer) + gitByName(git.Unmodified, renderer), GitStatus
}
for _, status := range *gits {
if status.X == git.Ignored || status.Y == git.Ignored {
// if status is ignored,
// and the file is or is a child of the ignored file
if isOrIsParentOf(status.Name, rel) {
return gitByName(status.X, renderer) + gitByName(status.Y, renderer), GitStatus
}
} else {
if isOrIsParentOf(rel, status.Name) {
return gitByName(status.X, renderer) + gitByName(status.Y, renderer), GitStatus
}
}
}
}
return gitByName(git.Unmodified, renderer) + gitByName(git.Unmodified, renderer), GitStatus
}
}
func gitByName(status git.Status, renderer *render.Renderer) string {
switch status {
case git.Unmodified:
return renderer.GitUnmodified("-")
case git.Modified:
return renderer.GitModified("M")
case git.Added:
return renderer.GitAdded("A")
case git.Deleted:
return renderer.GitDeleted("D")
case git.Renamed:
return renderer.GitRenamed("R")
case git.Copied:
return renderer.GitCopied("C")
case git.Untracked:
return renderer.GitUntracked("?")
case git.Ignored:
return renderer.GitIgnored("!")
case git.TypeChanged:
return renderer.GitTypeChanged("T")
case git.UpdatedButUnmerged:
return renderer.GitUpdatedButUnmerged("U")
}
return " "
}
const (
GitRepoBranch = constval.NameOfGitRepoBranch
GitRepoStatus = constval.NameOfGitRepoStatus
)
type GitRepoEnabler struct{}
func (g *GitRepoEnabler) Enable(renderer *render.Renderer) ContentOption {
align.Register(GitRepoBranch)
return func(info *item.FileInfo) (string, string) {
// get branch name
return renderer.GitRepoBranch(git.GetBranch(info.FullPath)), GitRepoBranch
}
}
func (g *GitRepoEnabler) EnableStatus(renderer *render.Renderer) ContentOption {
align.Register(GitRepoStatus)
return func(info *item.FileInfo) (string, string) {
// get repo status
return renderer.GitRepoStatus(git.GetRepoStatus(info.FullPath)), GitRepoStatus
}
}
func NewGitRepoEnabler() *GitRepoEnabler {
return &GitRepoEnabler{}
}