check-merged.go 3.1 KB

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