diff options
| -rw-r--r-- | README.md | 3 | ||||
| -rw-r--r-- | cmd/git-extract-issue/main.go | 38 | ||||
| -rw-r--r-- | cmd/git-sw/main.go | 80 | ||||
| -rw-r--r-- | go.mod | 3 |
4 files changed, 124 insertions, 0 deletions
diff --git a/README.md b/README.md new file mode 100644 index 0000000..18c3973 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# My Git Helpers + +See https://github.com/nsfisis/dotfiles diff --git a/cmd/git-extract-issue/main.go b/cmd/git-extract-issue/main.go new file mode 100644 index 0000000..4681d4d --- /dev/null +++ b/cmd/git-extract-issue/main.go @@ -0,0 +1,38 @@ +package main + +import ( + "fmt" + "os" + "regexp" +) + +func main() { + argv := os.Args + argc := len(argv) + if argc != 2 { + return + } + branchName := argv[1] + fmt.Println(extractIssueNumberFromBranchName(branchName)) +} + +// * 123 => #123 +// * 123-suffix => #123 +// * feature/123 => #123 +// * feature/123-suffix => #123 +// * feature/prefix-123 => prefix-123 +// * feature/prefix-123-suffix => prefix-123 +func extractIssueNumberFromBranchName(branchName string) string { + pattern := regexp.MustCompile(`\A(?:\w+/)?(\w+-)?(\d+)(?:-\w+)*\z`) + matches := pattern.FindSubmatch([]byte(branchName)) + if len(matches) != 3 { + return "" + } + var prefix string + if len(matches[1]) == 0 { + prefix = "#" + } else { + prefix = string(matches[1]) + } + return prefix + string(matches[2]) +} diff --git a/cmd/git-sw/main.go b/cmd/git-sw/main.go new file mode 100644 index 0000000..5c098a1 --- /dev/null +++ b/cmd/git-sw/main.go @@ -0,0 +1,80 @@ +package main + +import ( + "log" + "os" + "os/exec" + "strings" + "unicode" +) + +func main() { + gitArgs := []string{"switch"} + if requiresDetachFlag(os.Args) { + gitArgs = append(gitArgs, "--detach") + } + firstPositionalArg := true + for i, argv := range os.Args { + if i == 0 { + continue // argv[0] is a program name. + } + if firstPositionalArg && !strings.HasPrefix(argv, "-") { + if isInt(argv) { + argv = "feature/" + argv + } + firstPositionalArg = false + } + gitArgs = append(gitArgs, argv) + } + + cmd := exec.Command("git", gitArgs...) + cmd.Stdin = os.Stdin + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + + err := cmd.Run() + if err != nil { + switch err.(type) { + case *exec.ExitError: + // Do nothing here because Git has already reported the error. + default: + log.Fatal(err) + } + } + + os.Exit(cmd.ProcessState.ExitCode()) +} + +func requiresDetachFlag(argv []string) bool { + argc := len(argv) + if argc == 1 { + return false + } + firstArg := argv[1] + + // Example: origin/main, upstream/develop + if strings.HasPrefix(firstArg, "origin/") || strings.HasPrefix(firstArg, "upstream/") { + return true + } + + // Example: 1234, cafebabe + if len(firstArg) >= 4 { + for _, c := range firstArg { + if !unicode.Is(unicode.ASCII_Hex_Digit, c) { + return false + } + } + return true + } + + return false +} + +func isInt(s string) bool { + for _, c := range s { + if !unicode.IsDigit(c) { + return false + } + } + return true +} @@ -0,0 +1,3 @@ +module github.com/nsfisis/git-helpers + +go 1.24.2 |
