github.com/emmahsax/go-git-helper@v0.0.8-0.20240519163017-907b9de0fa52/internal/git/git.go (about) 1 package git 2 3 import ( 4 "errors" 5 "fmt" 6 "regexp" 7 "strings" 8 9 "github.com/emmahsax/go-git-helper/internal/executor" 10 "github.com/emmahsax/go-git-helper/internal/utils" 11 ) 12 13 type Git struct { 14 Debug bool 15 Executor executor.ExecutorInterface 16 } 17 18 func NewGit(debug bool, executor executor.ExecutorInterface) *Git { 19 return &Git{ 20 Debug: debug, 21 Executor: executor, 22 } 23 } 24 25 func (g *Git) Checkout(branch string) { 26 _, err := g.Executor.Exec("waitAndStdout", "git", "checkout", branch) 27 if err != nil { 28 utils.HandleError(err, g.Debug, nil) 29 return 30 } 31 } 32 33 func (g *Git) CleanDeletedBranches() { 34 output, err := g.Executor.Exec("actionAndOutput", "git", "branch", "-vv") 35 if err != nil { 36 utils.HandleError(err, g.Debug, nil) 37 return 38 } 39 40 branches := strings.Split(string(output), "\n") 41 pattern := "origin/.*: gone" 42 43 for _, branch := range branches { 44 re := regexp.MustCompile(pattern) 45 46 if re.MatchString(branch) { 47 b := strings.Fields(branch)[0] 48 output, err = g.Executor.Exec("actionAndOutput", "git", "branch", "-D", b) 49 if err != nil { 50 utils.HandleError(err, g.Debug, nil) 51 return 52 } 53 54 fmt.Printf("%s", string(output)) 55 } 56 } 57 } 58 59 func (g *Git) CreateBranch(branch string) error { 60 _, err := g.Executor.Exec("waitAndStdout", "git", "branch", "--no-track", branch) 61 if err != nil { 62 return err 63 } 64 65 return nil 66 } 67 68 func (g *Git) CreateEmptyCommit() { 69 _, err := g.Executor.Exec("waitAndStdout", "git", "commit", "--allow-empty", "-m", "Empty commit") 70 if err != nil { 71 utils.HandleError(err, g.Debug, nil) 72 return 73 } 74 } 75 76 func (g *Git) CurrentBranch() string { 77 output, err := g.Executor.Exec("actionAndOutput", "git", "branch") 78 if err != nil { 79 utils.HandleError(err, g.Debug, nil) 80 return "" 81 } 82 83 re := regexp.MustCompile(`\*\s(\S*)`) 84 match := re.FindStringSubmatch(string(output)) 85 86 if len(match) == 2 { 87 return match[1] 88 } 89 90 return "" 91 } 92 93 func (g *Git) DefaultBranch() string { 94 output, err := g.Executor.Exec("actionAndOutput", "git", "symbolic-ref", "refs/remotes/origin/HEAD") 95 if err != nil { 96 if strings.Contains(err.Error(), "fatal: ") { 97 fmt.Printf("\nYour symbolic ref is not set up properly. Please run:\n git-helper set-head-ref [defaultBranch]\n\nAnd then try your command again.\n\n") 98 } 99 utils.HandleError(err, g.Debug, nil) 100 return "" 101 } 102 103 branch := strings.SplitN(strings.TrimSpace(string(output)), "/", 4) 104 if len(branch) != 4 { 105 err = errors.New("invalid branch format") 106 utils.HandleError(err, g.Debug, nil) 107 return "" 108 } 109 110 return branch[3] 111 } 112 113 func (g *Git) Fetch() { 114 _, err := g.Executor.Exec("waitAndStdout", "git", "fetch", "-p") 115 if err != nil { 116 utils.HandleError(err, g.Debug, nil) 117 return 118 } 119 } 120 121 func (g *Git) GetGitRootDir() string { 122 output, err := g.Executor.Exec("actionAndOutput", "git", "rev-parse", "--show-toplevel") 123 if err != nil { 124 utils.HandleError(err, g.Debug, nil) 125 return "" 126 } 127 return strings.TrimSpace(string(output)) 128 } 129 130 func (g *Git) Pull() { 131 _, err := g.Executor.Exec("waitAndStdout", "git", "pull") 132 if err != nil { 133 utils.HandleError(err, g.Debug, nil) 134 return 135 } 136 } 137 138 func (g *Git) PushBranch(branch string) { 139 _, err := g.Executor.Exec("waitAndStdout", "git", "push", "--set-upstream", "origin", branch) 140 if err != nil { 141 utils.HandleError(err, g.Debug, nil) 142 return 143 } 144 } 145 146 func (g *Git) RepoName() string { 147 output, err := g.Executor.Exec("actionAndOutput", "git", "remote", "-v") 148 if err != nil { 149 utils.HandleError(err, g.Debug, nil) 150 return "" 151 } 152 153 remoteURL := string(output) 154 re := regexp.MustCompile(`\S\s*\S+.com\S{1}(\S*) \(push\)`) 155 match := re.FindStringSubmatch(remoteURL) 156 if len(match) >= 2 { 157 return strings.Split(match[1], ".git")[0] 158 } else { 159 err = errors.New("no match found") 160 utils.HandleError(err, g.Debug, nil) 161 } 162 163 return "" 164 } 165 166 func (g *Git) Remotes() []string { 167 output, err := g.Executor.Exec("actionAndOutput", "git", "remote", "-v") 168 if err != nil { 169 utils.HandleError(err, g.Debug, nil) 170 return []string{} 171 } 172 173 return strings.Split(string(output), "\n") 174 } 175 176 func (g *Git) Reset() { 177 _, err := g.Executor.Exec("waitAndStdout", "git", "reset", "--hard", "origin/HEAD") 178 if err != nil { 179 utils.HandleError(err, g.Debug, nil) 180 return 181 } 182 } 183 184 func (g *Git) SetHeadRef(defaultBranch string) { 185 _, err := g.Executor.Exec("waitAndStdout", "git", "branch", "--set-upstream-to=origin/"+defaultBranch, defaultBranch) 186 if err != nil { 187 utils.HandleError(err, g.Debug, nil) 188 return 189 } 190 191 _, err = g.Executor.Exec("waitAndStdout", "git", "symbolic-ref", "refs/remotes/origin/HEAD", "refs/remotes/origin/"+defaultBranch) 192 if err != nil { 193 utils.HandleError(err, g.Debug, nil) 194 return 195 } 196 } 197 198 func (g *Git) Stash() { 199 _, err := g.Executor.Exec("waitAndStdout", "git", "stash") 200 if err != nil { 201 utils.HandleError(err, g.Debug, nil) 202 return 203 } 204 } 205 206 func (g *Git) StashDrop() { 207 _, _ = g.Executor.Exec("waitAndStdout", "git", "stash", "drop") 208 }