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  }