├── go.mod ├── README.md └── main.go /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/sonatard/git-switch-trainer 2 | 3 | go 1.12 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | git-switch-trainer 2 | ====== 3 | 4 | ## Description 5 | 6 | You are forced to use git switch and git restore instead of git checkout by `git-switch-trainer`. 7 | 8 | ## Getting Started 9 | 10 | ### Install 11 | ```shell 12 | go get -u github.com/sonatard/git-switch-trainer/ 13 | ``` 14 | 15 | ### Settings 16 | 17 | Add alias to your `.bash_profile` 18 | 19 | - .bash_profile 20 | 21 | ``` 22 | alias git=git-switch-trainer 23 | ``` 24 | 25 | ``` 26 | $ source ~/.bash_profile 27 | ``` 28 | 29 | 30 | ## Example 31 | 32 | ```shell 33 | $ git checkout master 34 | Error: Use git switch or git restore instead of git checkout. 35 | ``` 36 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "io/ioutil" 7 | "os" 8 | "os/exec" 9 | "strings" 10 | ) 11 | 12 | func main() { 13 | if len(os.Args) > 1 { 14 | const checkout = "checkout" 15 | checkoutAliasConfigs, exitCode, err := grepGitConfig(checkout) 16 | if err != nil { 17 | fmt.Fprintf(os.Stderr, "Error: failed to read alias from git config") 18 | os.Exit(exitCode) 19 | } 20 | 21 | targets := append(aliasFromConfigs(checkoutAliasConfigs), checkout) 22 | 23 | subCommand := os.Args[1] 24 | if matchSubCommand(subCommand, targets) { 25 | fmt.Fprintf(os.Stderr, "Error: Use git switch or git restore instead of git checkout\n\n") 26 | os.Exit(1) 27 | } 28 | } 29 | 30 | if exitCode, err := gitExec(os.Args[1:]); err != nil { 31 | os.Exit(exitCode) 32 | } 33 | } 34 | 35 | func grepGitConfig(target string) ([]string, int, error) { 36 | var stdout bytes.Buffer 37 | cmd := exec.Command("git", "config", "--list") 38 | cmd.Stdout = &stdout 39 | cmd.Stderr = ioutil.Discard 40 | if err := cmd.Run(); err != nil { 41 | exitCode := cmd.ProcessState.ExitCode() 42 | return nil, exitCode, err 43 | } 44 | 45 | var matches []string 46 | configLines := strings.Fields(stdout.String()) 47 | for _, configLine := range configLines { 48 | if strings.Contains(configLine, target) { 49 | matches = append(matches, configLine) 50 | } 51 | } 52 | 53 | return matches, 0, nil 54 | } 55 | 56 | // alias.co=checkout -> co 57 | func aliasFromConfigs(aliasConfigs []string) []string { 58 | var aliases []string 59 | for _, aliasConfig := range aliasConfigs { 60 | // alias.co=checkout -> [alias.co checkout] 61 | aliasConfigSplit := strings.Split(aliasConfig, "=") 62 | if len(aliasConfigSplit) > 1 { 63 | // alias.co -> [alias co] 64 | aliasConfigSplit2 := strings.Split(aliasConfigSplit[0], ".") 65 | if len(aliasConfigSplit2) > 1 { 66 | // co 67 | aliases = append(aliases, aliasConfigSplit2[1]) 68 | } 69 | } 70 | } 71 | 72 | return aliases 73 | } 74 | 75 | func matchSubCommand(subCommand string, targets []string) bool { 76 | for _, target := range targets { 77 | if target == subCommand { 78 | return true 79 | } 80 | } 81 | 82 | return false 83 | } 84 | 85 | func gitExec(args []string) (int, error) { 86 | cmd := exec.Command("git", args...) 87 | cmd.Stdin = os.Stdin 88 | cmd.Stdout = os.Stdout 89 | cmd.Stderr = os.Stderr 90 | 91 | if err := cmd.Run(); err != nil { 92 | exitCode := cmd.ProcessState.ExitCode() 93 | return exitCode, err 94 | } 95 | 96 | return 0, nil 97 | } 98 | --------------------------------------------------------------------------------