-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathgit-prompt.go
129 lines (106 loc) · 2.19 KB
/
git-prompt.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
123
124
125
126
127
128
129
/*
git-prompt
To use just add $(git-prompt) to PS1, for example.
PS1='\u@\h:\w $(git-prompt)$ '
Ole Martin Bjorndalen
https://github.com/olemb/git-prompt
License: MIT
*/
package main
import (
"fmt"
"os/exec"
"strings"
"unicode"
)
func readCommand(cmdName string, cmdArgs []string) string {
var (
cmdOut []byte
err error
)
if cmdOut, err = exec.Command(cmdName, cmdArgs...).Output(); err != nil {
return ""
}
return string(cmdOut)
}
func getStatusText() string {
return readCommand("git", []string{"status", "--porcelain=v2", "--branch"})
}
func parseStatus(text string) (string, map[string]bool) {
oid := ""
head := ""
branch := ""
status := make(map[string]bool)
lines := strings.Split(strings.TrimSpace(text), "\n")
for _, line := range lines {
char := line[0]
if char == '#' {
words := strings.Fields(line)
name := words[1]
args := words[2:]
if name == "branch.oid" {
oid = args[0]
} else if name == "branch.head" {
head = args[0]
} else if name == "branch.ab" {
if args[0] != "+0" {
status["ahead"] = true
}
if args[1] != "-0" {
status["behind"] = true
}
}
} else if char == '?' {
status["untracked"] = true
} else if char == 'u' {
status["conflict"] = true
} else if unicode.IsDigit(rune(char)) {
status["changed"] = true
}
}
if oid == "(initial)" {
branch = ":initial"
} else if head == "(detached)" {
branch = ":" + oid[:6]
} else {
branch = head
}
return branch, status
}
func formatStatus(branch string, status map[string]bool) string {
green := "92"
yellow := "93"
red := "31"
flags := ""
color := green
if status["changed"] {
flags += "*"
color = yellow
}
if status["untracked"] {
flags += "?"
color = yellow
}
if status["conflict"] {
flags += "!"
color = red
}
if status["ahead"] && status["behind"] {
flags += "↕"
} else if status["ahead"] {
flags += "↑"
} else if status["behind"] {
flags += "↓"
}
if flags != "" {
flags = " " + flags
}
return fmt.Sprintf("\033[%sm[%s%s]\033[0m", color, branch, flags)
}
func main() {
text := getStatusText()
if text != "" {
branch, status := parseStatus(text)
fmt.Print(formatStatus(branch, status))
}
}