summaryrefslogtreecommitdiffstats
path: root/gitcommands.go
diff options
context:
space:
mode:
authorJesse Duffield <jessedduffield@gmail.com>2018-05-21 20:52:48 +1000
committerJesse Duffield <jessedduffield@gmail.com>2018-05-21 20:52:48 +1000
commitac1fa346acd7ba24eace2953359f16e47515645b (patch)
tree798a4914f6075f5cb50d460ecdcc1be455b47f04 /gitcommands.go
parent30c4c6e576a39915d7a4d9406015ade32660f4cc (diff)
test file
Diffstat (limited to 'gitcommands.go')
-rw-r--r--gitcommands.go199
1 files changed, 146 insertions, 53 deletions
diff --git a/gitcommands.go b/gitcommands.go
index 94e71686d..465a61da1 100644
--- a/gitcommands.go
+++ b/gitcommands.go
@@ -5,92 +5,164 @@
package main
import (
- "fmt"
+
// "log"
+ "fmt"
"os/exec"
- "os"
"strings"
- "regexp"
- "runtime"
)
-// Map (from https://gobyexample.com/collection-functions)
-func Map(vs []string, f func(string) string) []string {
- vsm := make([]string, len(vs))
- for i, v := range vs {
- vsm[i] = f(v)
- }
- return vsm
+// GitFile : A staged/unstaged file
+type GitFile struct {
+ Name string
+ DisplayString string
+ HasStagedChanges bool
+ HasUnstagedChanges bool
+ Tracked bool
+ Deleted bool
}
-func sanitisedFileString(fileString string) string {
- r := regexp.MustCompile("\\s| \\(new commits\\)|.* ")
- fileString = r.ReplaceAllString(fileString, "")
- return fileString
+// Branch : A git branch
+type Branch struct {
+ Name string
+ DisplayString string
+ Type string
+ BaseBranch string
}
-func filesByMatches(statusString string, targets []string) []string {
- files := make([]string, 0)
- for _, target := range targets {
- if strings.Index(statusString, target) == -1 {
- continue
- }
- r := regexp.MustCompile("(?s)" + target + ".*?\n\n(.*?)\n\n")
- // fmt.Println(r)
-
- matchedFileStrings := strings.Split(r.FindStringSubmatch(statusString)[1], "\n")
- // fmt.Println(matchedFileStrings)
+// Map (from https://gobyexample.com/collection-functions)
+func Map(vs []string, f func(string) string) []string {
+ vsm := make([]string, len(vs))
+ for i, v := range vs {
+ vsm[i] = f(v)
+ }
+ return vsm
+}
- matchedFiles := Map(matchedFileStrings, sanitisedFileString)
- // fmt.Println(matchedFiles)
- files = append(files, matchedFiles...)
+func mergeGitStatusFiles(oldGitFiles, newGitFiles []GitFile) []GitFile {
+ if len(oldGitFiles) == 0 {
+ return newGitFiles
+ }
+ result := make([]GitFile, 0)
+ for _, oldGitFile := range oldGitFiles {
+ for _, newGitFile := range newGitFiles {
+ if oldGitFile.Name == newGitFile.Name {
+ result = append(result, newGitFile)
+ break
+ }
+ }
}
+ return result
+}
- breakHere()
+func getGitBranchOutput() (string, error) {
+ cmdOut, err := exec.Command("bash", "-c", getBranchesCommand).Output()
+ return string(cmdOut), err
+}
- // fmt.Println(files)
- return files
+func branchNameFromString(branchString string) string {
+ // because this has the recency at the beginning,
+ // we need to split and take the second part
+ splitBranchName := strings.Split(branchString, "\t")
+ return splitBranchName[len(splitBranchName)-1]
}
-func breakHere() {
- if len(os.Args) > 1 && os.Args[1] == "debug" {
- runtime.Breakpoint()
+func getGitBranches() []Branch {
+ branches := make([]Branch, 0)
+ rawString, _ := getGitBranchOutput()
+ branchLines := splitLines(rawString)
+ for _, line := range branchLines {
+ name := branchNameFromString(line)
+ var branchType string
+ var baseBranch string
+ if strings.Contains(line, "feature/") {
+ branchType = "feature"
+ baseBranch = "develop"
+ } else if strings.Contains(line, "bugfix/") {
+ branchType = "bugfix"
+ baseBranch = "develop"
+ } else if strings.Contains(line, "hotfix/") {
+ branchType = "hotfix"
+ baseBranch = "master"
+ } else {
+ branchType = "other"
+ baseBranch = name
+ }
+ branches = append(branches, Branch{name, line, branchType, baseBranch})
}
+ devLog(fmt.Sprint(branches))
+ return branches
}
-func getFilesToStage(statusString string) []string {
- targets := []string{"Changes not staged for commit:", "Untracked files:"}
- return filesByMatches(statusString, targets)
+func getGitStatusFiles() []GitFile {
+ statusOutput, _ := getGitStatus()
+ statusStrings := splitLines(statusOutput)
+ devLog(fmt.Sprint(statusStrings))
+ // a file can have both staged and unstaged changes
+ // I'll probably end up ignoring the unstaged flag for now but might revisit
+ // tracked, staged, unstaged
+
+ gitFiles := make([]GitFile, 0)
+
+ for _, statusString := range statusStrings {
+ stagedChange := statusString[0:1]
+ unstagedChange := statusString[1:2]
+ filename := statusString[3:]
+ tracked := statusString[0:2] != "??"
+ gitFile := GitFile{
+ Name: filename,
+ DisplayString: statusString,
+ HasStagedChanges: tracked && stagedChange != " ",
+ HasUnstagedChanges: !tracked || unstagedChange != " ",
+ Tracked: tracked,
+ Deleted: unstagedChange == "D" || stagedChange == "D",
+ }
+ gitFiles = append(gitFiles, gitFile)
+ }
+ return gitFiles
}
-func getFilesToUnstage(statusString string) []string {
- targets := []string{"Changes to be committed:"}
- return filesByMatches(statusString, targets)
+func gitCheckout(branch string, force bool) error {
+ forceArg := ""
+ if force {
+ forceArg = "--force "
+ }
+ _, err := runCommand("git checkout " + forceArg + branch)
+ return err
}
func runCommand(cmd string) (string, error) {
splitCmd := strings.Split(cmd, " ")
cmdOut, err := exec.Command(splitCmd[0], splitCmd[1:]...).Output()
+ devLog(cmd)
+ devLog(string(cmdOut))
return string(cmdOut), err
}
-func getDiff(file string, cached bool) string {
- devLog(file)
+func getBranchDiff(branch string, baseBranch string) (string, error) {
+ return runCommand("git diff --color " + baseBranch + "..." + branch)
+}
+
+func getDiff(file GitFile) string {
cachedArg := ""
- if cached {
+ if file.HasStagedChanges {
cachedArg = "--cached "
}
- s, err := runCommand("git diff " + cachedArg + file)
+ deletedArg := ""
+ if file.Deleted || !file.Tracked {
+ deletedArg = "--no-index /dev/null "
+ }
+ command := "git diff --color " + cachedArg + deletedArg + file.Name
+ s, err := runCommand(command)
if err != nil {
// for now we assume an error means the file was deleted
- return "deleted"
+ return s
}
return s
}
func stageFile(file string) error {
- devLog("staging " + file)
_, err := runCommand("git add " + file)
return err
}
@@ -100,13 +172,34 @@ func unStageFile(file string) error {
return err
}
-func testGettingFiles() {
-
- statusString, _ := runCommand("git status")
- fmt.Println(getFilesToStage(statusString))
- fmt.Println(getFilesToUnstage(statusString))
+func getGitStatus() (string, error) {
+ return runCommand("git status --untracked-files=all --short")
+}
- runCommand("git add hello-world.go")
+const getBranchesCommand = `set -e
+git reflog -n100 --pretty='%cr|%gs' --grep-reflog='checkout: moving' HEAD | {
+ seen=":"
+ git_dir="$(git rev-parse --git-dir)"
+ while read line; do
+ date="${line%%|*}"
+ branch="${line##* }"
+ if ! [[ $seen == *:"${branch}":* ]]; then
+ seen="${seen}${branch}:"
+ if [ -f "${git_dir}/refs/heads/${branch}" ]; then
+ printf "%s\t%s\n" "$date" "$branch"
+ fi
+ fi
+ done | sed 's/ days /d /g' | sed 's/ weeks /w /g' | sed 's/ hours /h /g' | sed 's/ minutes /m /g' | sed 's/ago//g' | tr -d ' '
}
+`
+
+// func main() {
+// getGitStatusFiles()
+// }
+// func devLog(s string) {
+// f, _ := os.OpenFile("development.log", os.O_APPEND|os.O_WRONLY, 0644)
+// defer f.Close()
+// f.WriteString(s + "\n")
+// }