github.com/artpar/rclone@v1.67.3/bin/check-merged.go (about) 1 //go:build ignore 2 3 // Attempt to work out if branches have already been merged 4 package main 5 6 import ( 7 "bufio" 8 "errors" 9 "flag" 10 "fmt" 11 "log" 12 "os" 13 "os/exec" 14 "regexp" 15 ) 16 17 var ( 18 // Flags 19 master = flag.String("master", "master", "Branch to work out if merged into") 20 version = "development version" // overridden by goreleaser 21 ) 22 23 func usage() { 24 fmt.Fprintf(os.Stderr, `Usage: %s [options] 25 Version: %s 26 27 Attempt to work out if in the current git repo branches have been 28 merged into master. 29 30 Example usage: 31 32 %s 33 34 Full options: 35 `, os.Args[0], version, os.Args[0]) 36 flag.PrintDefaults() 37 } 38 39 var ( 40 printedSep = false 41 ) 42 43 const ( 44 sep1 = "============================================================" 45 sep2 = "------------------------------------------------------------" 46 ) 47 48 // Show the diff between two git revisions 49 func gitDiffDiff(rev1, rev2 string) { 50 fmt.Printf("Diff of diffs of %q and %q\n", rev1, rev2) 51 cmd := exec.Command("bash", "-c", fmt.Sprintf(`diff <(git show "%s") <(git show "%s")`, rev1, rev2)) 52 out, err := cmd.Output() 53 if err != nil { 54 var exitErr *exec.ExitError 55 if errors.As(err, &exitErr) && exitErr.ExitCode() == 1 { 56 // OK just different 57 } else { 58 log.Fatalf("git diff failed: %#v", err) 59 } 60 } 61 _, _ = os.Stdout.Write(out) 62 } 63 64 var reCommit = regexp.MustCompile(`commit ([0-9a-f]{32,})`) 65 66 // Grep the git log for logLine 67 func gitLogGrep(branch, rev, logLine string) { 68 cmd := exec.Command("git", "log", "--grep", regexp.QuoteMeta(logLine), *master) 69 out, err := cmd.Output() 70 if err != nil { 71 log.Fatalf("git log grep failed: %v", err) 72 } 73 if len(out) > 0 { 74 if !printedSep { 75 fmt.Println(sep1) 76 printedSep = true 77 } 78 fmt.Printf("Branch: %s - MAY BE MERGED to %s\nLog: %s\n\n", branch, *master, logLine) 79 _, _ = os.Stdout.Write(out) 80 match := reCommit.FindSubmatch(out) 81 if len(match) != 0 { 82 commit := string(match[1]) 83 fmt.Println(sep2) 84 gitDiffDiff(rev, commit) 85 } 86 fmt.Println(sep1) 87 } 88 } 89 90 // * b2-fix-download-url 4209c768a [gone] b2: fix transfers when using download_url 91 var reLine = regexp.MustCompile(`^[ *] (\S+)\s+([0-9a-f]+)\s+(?:\[[^]]+\] )?(.*)$`) 92 93 // Run git branch -v, parse the output and check it in the log 94 func gitBranch() { 95 cmd := exec.Command("git", "branch", "-v") 96 cmd.Stderr = os.Stderr 97 out, err := cmd.StdoutPipe() 98 if err != nil { 99 log.Fatalf("git branch pipe failed: %v", err) 100 } 101 if err := cmd.Start(); err != nil { 102 log.Fatalf("git branch failed: %v", err) 103 } 104 scanner := bufio.NewScanner(out) 105 for scanner.Scan() { 106 line := scanner.Text() 107 match := reLine.FindStringSubmatch(line) 108 if len(match) != 4 { 109 log.Printf("Invalid line %q", line) 110 continue 111 } 112 branch, rev, logLine := match[1], match[2], match[3] 113 if branch == *master { 114 continue 115 } 116 //fmt.Printf("branch = %q, rev = %q, logLine = %q\n", branch, rev, logLine) 117 gitLogGrep(branch, rev, logLine) 118 } 119 if err := scanner.Err(); err != nil { 120 log.Fatalf("failed reading git branch: %v", err) 121 } 122 if err := cmd.Wait(); err != nil { 123 log.Fatalf("git branch wait failed: %v", err) 124 } 125 } 126 127 func main() { 128 flag.Usage = usage 129 flag.Parse() 130 args := flag.Args() 131 if len(args) != 0 { 132 usage() 133 log.Fatal("Wrong number of arguments") 134 } 135 gitBranch() 136 }