Use go-git for native git operations
Replace exec-based git calls with go-git/v6 library for ~5.6x speedup over shell version. Only pgrep remains as external call.
This commit is contained in:
77
main.go
77
main.go
@ -10,6 +10,7 @@ import (
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/go-git/go-git/v6"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
@ -94,10 +95,7 @@ func main() {
|
||||
termWidth := getTerminalWidth() - statuslineWidthOffset
|
||||
|
||||
// Calculate padding
|
||||
padding := termWidth - len(leftVisible) - len(rightVisible)
|
||||
if padding < 1 {
|
||||
padding = 1
|
||||
}
|
||||
padding := max(termWidth-len(leftVisible)-len(rightVisible), 1)
|
||||
|
||||
// Output with padding
|
||||
fmt.Printf("%s%s%s", left, strings.Repeat(" ", padding), right)
|
||||
@ -129,64 +127,59 @@ func getGiteaStatus() string {
|
||||
}
|
||||
|
||||
func getGitInfo(cwd string) string {
|
||||
// Change to the directory
|
||||
oldDir, _ := os.Getwd()
|
||||
if err := os.Chdir(cwd); err != nil {
|
||||
// Open the repository (searches up from cwd)
|
||||
repo, err := git.PlainOpenWithOptions(cwd, &git.PlainOpenOptions{
|
||||
DetectDotGit: true,
|
||||
})
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
defer os.Chdir(oldDir)
|
||||
|
||||
// Check if we're in a git repo
|
||||
cmd := exec.Command("git", "rev-parse", "--git-dir")
|
||||
cmd.Stderr = nil
|
||||
if err := cmd.Run(); err != nil {
|
||||
// Get HEAD reference
|
||||
head, err := repo.Head()
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Get branch name
|
||||
branch := ""
|
||||
cmd = exec.Command("git", "symbolic-ref", "--short", "HEAD")
|
||||
cmd.Stderr = nil
|
||||
if out, err := cmd.Output(); err == nil {
|
||||
branch = strings.TrimSpace(string(out))
|
||||
var branch string
|
||||
if head.Name().IsBranch() {
|
||||
branch = head.Name().Short()
|
||||
} else {
|
||||
// Fallback to short SHA
|
||||
cmd = exec.Command("git", "rev-parse", "--short", "HEAD")
|
||||
cmd.Stderr = nil
|
||||
if out, err := cmd.Output(); err == nil {
|
||||
branch = strings.TrimSpace(string(out))
|
||||
}
|
||||
}
|
||||
|
||||
if branch == "" {
|
||||
return ""
|
||||
// Detached HEAD - use short hash
|
||||
branch = head.Hash().String()[:7]
|
||||
}
|
||||
|
||||
// Check if working tree is dirty
|
||||
isDirty := false
|
||||
|
||||
// Check unstaged changes
|
||||
cmd = exec.Command("git", "diff", "--no-ext-diff", "--quiet", "--exit-code", "--no-optional-locks")
|
||||
cmd.Stderr = nil
|
||||
if err := cmd.Run(); err != nil {
|
||||
isDirty = true
|
||||
worktree, err := repo.Worktree()
|
||||
if err != nil {
|
||||
return fmt.Sprintf(" git:(%s)", branch)
|
||||
}
|
||||
|
||||
// Check staged changes
|
||||
if !isDirty {
|
||||
cmd = exec.Command("git", "diff-index", "--cached", "--quiet", "HEAD", "--no-optional-locks")
|
||||
cmd.Stderr = nil
|
||||
if err := cmd.Run(); err != nil {
|
||||
isDirty = true
|
||||
}
|
||||
status, err := worktree.Status()
|
||||
if err != nil {
|
||||
return fmt.Sprintf(" git:(%s)", branch)
|
||||
}
|
||||
|
||||
if isDirty {
|
||||
if !status.IsClean() {
|
||||
return fmt.Sprintf(" git:(%s) ✗", branch)
|
||||
}
|
||||
return fmt.Sprintf(" git:(%s)", branch)
|
||||
}
|
||||
|
||||
func findGitRoot(path string) string {
|
||||
for {
|
||||
if _, err := os.Stat(filepath.Join(path, ".git")); err == nil {
|
||||
return path
|
||||
}
|
||||
parent := filepath.Dir(path)
|
||||
if parent == path {
|
||||
return ""
|
||||
}
|
||||
path = parent
|
||||
}
|
||||
}
|
||||
|
||||
func getTerminalWidth() int {
|
||||
ws, err := unix.IoctlGetWinsize(int(os.Stdout.Fd()), unix.TIOCGWINSZ)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user