aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--README.md3
-rw-r--r--cmd/git-extract-issue/main.go38
-rw-r--r--cmd/git-sw/main.go80
-rw-r--r--go.mod3
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
+}
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..d2b4976
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,3 @@
+module github.com/nsfisis/git-helpers
+
+go 1.24.2