forked from cli/cli
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathgit.go
More file actions
125 lines (101 loc) · 2.51 KB
/
git.go
File metadata and controls
125 lines (101 loc) · 2.51 KB
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
package git
import (
"bytes"
"fmt"
"io/ioutil"
"os/exec"
"path/filepath"
"strings"
"github.com/github/gh-cli/utils"
)
func Dir() (string, error) {
dirCmd := exec.Command("git", "rev-parse", "-q", "--git-dir")
output, err := utils.PrepareCmd(dirCmd).Output()
if err != nil {
return "", fmt.Errorf("Not a git repository (or any of the parent directories): .git")
}
gitDir := firstLine(output)
if !filepath.IsAbs(gitDir) {
gitDir, err = filepath.Abs(gitDir)
if err != nil {
return "", err
}
gitDir = filepath.Clean(gitDir)
}
return gitDir, nil
}
func VerifyRef(ref string) bool {
showRef := exec.Command("git", "show-ref", "--verify", "--quiet", ref)
err := utils.PrepareCmd(showRef).Run()
return err == nil
}
func BranchAtRef(paths ...string) (name string, err error) {
dir, err := Dir()
if err != nil {
return
}
segments := []string{dir}
segments = append(segments, paths...)
path := filepath.Join(segments...)
b, err := ioutil.ReadFile(path)
if err != nil {
return
}
n := string(b)
refPrefix := "ref: "
if strings.HasPrefix(n, refPrefix) {
name = strings.TrimPrefix(n, refPrefix)
name = strings.TrimSpace(name)
} else {
err = fmt.Errorf("No branch info in %s: %s", path, n)
}
return
}
func Head() (string, error) {
return BranchAtRef("HEAD")
}
func listRemotes() ([]string, error) {
remoteCmd := exec.Command("git", "remote", "-v")
output, err := utils.PrepareCmd(remoteCmd).Output()
return outputLines(output), err
}
func Config(name string) (string, error) {
configCmd := exec.Command("git", "config", name)
output, err := utils.PrepareCmd(configCmd).Output()
if err != nil {
return "", fmt.Errorf("unknown config key: %s", name)
}
return firstLine(output), nil
}
var GitCommand = func(args ...string) *exec.Cmd {
return exec.Command("git", args...)
}
func UncommittedChangeCount() (int, error) {
statusCmd := GitCommand("status", "--porcelain")
output, err := utils.PrepareCmd(statusCmd).Output()
if err != nil {
return 0, err
}
lines := strings.Split(string(output), "\n")
count := 0
for _, l := range lines {
if l != "" {
count++
}
}
return count, nil
}
func Push(remote string, ref string) error {
cmd := GitCommand("push", "--set-upstream", remote, ref)
return cmd.Run()
}
func outputLines(output []byte) []string {
lines := strings.TrimSuffix(string(output), "\n")
return strings.Split(lines, "\n")
}
func firstLine(output []byte) string {
if i := bytes.IndexAny(output, "\n"); i >= 0 {
return string(output)[0:i]
}
return string(output)
}