github.com/lgug2z/story@v0.4.1/git/branch.go (about) 1 package git 2 3 import ( 4 "fmt" 5 "os/exec" 6 "strings" 7 8 "github.com/spf13/afero" 9 ) 10 11 type CheckoutBranchOpts struct { 12 Branch string 13 Create bool 14 Project string 15 } 16 17 func CheckoutBranch(opts CheckoutBranchOpts) (string, error) { 18 var args []string 19 args = append(args, "checkout") 20 if opts.Create { 21 args = append(args, "-b") 22 23 } 24 25 args = append(args, opts.Branch) 26 27 command := exec.Command("git", args...) 28 if opts.Project != "" { 29 command.Dir = opts.Project 30 } 31 32 combinedOutput, err := command.CombinedOutput() 33 if err != nil { 34 return "", fmt.Errorf("%s: %s", err, combinedOutput) 35 } 36 37 return strings.TrimSpace(string(combinedOutput)), nil 38 } 39 40 type DeleteBranchOpts struct { 41 Branch string 42 Local bool 43 Project string 44 Remote bool 45 } 46 47 func DeleteBranch(opts DeleteBranchOpts) (string, error) { 48 var outputs []string 49 50 if opts.Local { 51 _, err := CheckoutBranch(CheckoutBranchOpts{Branch: "master", Project: opts.Project}) 52 if err != nil { 53 return "", err 54 } 55 } 56 57 var args []string 58 59 if opts.Local { 60 args = append(args, "branch", "--delete", "--force", opts.Branch) 61 command := exec.Command("git", args...) 62 if opts.Project != "" { 63 command.Dir = opts.Project 64 } 65 66 combinedOutput, err := command.CombinedOutput() 67 if err != nil { 68 return "", fmt.Errorf("%s: %s", err, combinedOutput) 69 } 70 71 outputs = append(outputs, strings.TrimSpace(string(combinedOutput))) 72 } 73 74 if opts.Remote { 75 args = append(args, "push", "origin", "--delete", opts.Branch) 76 command := exec.Command("git", args...) 77 if opts.Project != "" { 78 command.Dir = opts.Project 79 } 80 81 combinedOutput, err := command.CombinedOutput() 82 if err != nil { 83 return "", fmt.Errorf("%s: %s", err, combinedOutput) 84 } 85 86 outputs = append(outputs, strings.TrimSpace(string(combinedOutput))) 87 } 88 89 return strings.Join(outputs, "\n"), nil 90 } 91 92 func GetCurrentBranch(fs afero.Fs, project string) (string, error) { 93 b, err := afero.ReadFile(fs, fmt.Sprintf("%s/.git/HEAD", project)) 94 if err != nil { 95 return "", err 96 } 97 98 return strings.TrimSpace(strings.TrimPrefix(string(b), "ref: refs/heads/")), nil 99 } 100 101 func HeadsAreEqual(fs afero.Fs, project, b1, b2 string) (bool, error) { 102 h1, err := getHead(fs, project, b1) 103 if err != nil { 104 return false, err 105 } 106 107 h2, err := getHead(fs, project, b2) 108 if err != nil { 109 return false, err 110 } 111 112 return h1 == h2, nil 113 } 114 115 func getHead(fs afero.Fs, project, branch string) (string, error) { 116 b, err := afero.ReadFile(fs, fmt.Sprintf("%s/.git/refs/heads/%s", project, branch)) 117 if err != nil { 118 return "", err 119 } 120 121 return strings.TrimSpace(string(b)), nil 122 }