diff options
author | Jesse Duffield <jessedduffield@gmail.com> | 2018-05-21 20:52:48 +1000 |
---|---|---|
committer | Jesse Duffield <jessedduffield@gmail.com> | 2018-05-21 20:52:48 +1000 |
commit | ac1fa346acd7ba24eace2953359f16e47515645b (patch) | |
tree | 798a4914f6075f5cb50d460ecdcc1be455b47f04 /gitcommands.go | |
parent | 30c4c6e576a39915d7a4d9406015ade32660f4cc (diff) |
test file
Diffstat (limited to 'gitcommands.go')
-rw-r--r-- | gitcommands.go | 199 |
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") +// } |