commitLog returns non-merge commits in the given range, filtering out left-side commits (already in the base) and deduplicating cherry-picks using git's --cherry-mark.
(commitRange string)
| 26 | // out left-side commits (already in the base) and deduplicating |
| 27 | // cherry-picks using git's --cherry-mark. |
| 28 | func commitLog(commitRange string) ([]commitEntry, error) { |
| 29 | // Use --left-right --cherry-mark to identify equivalent |
| 30 | // (cherry-picked) commits and left-side-only commits. |
| 31 | out, err := gitOutput("log", "--no-merges", "--left-right", "--cherry-mark", |
| 32 | "--pretty=format:%m %ct %h %H %s", commitRange) |
| 33 | if err != nil { |
| 34 | return nil, err |
| 35 | } |
| 36 | if out == "" { |
| 37 | return nil, nil |
| 38 | } |
| 39 | |
| 40 | // Collect cherry-pick equivalent commits (marked with '=') so |
| 41 | // we can skip duplicates. We keep only the right-side version. |
| 42 | seen := make(map[string]bool) |
| 43 | |
| 44 | var entries []commitEntry |
| 45 | for _, line := range strings.Split(out, "\n") { |
| 46 | line = strings.TrimSpace(line) |
| 47 | if line == "" { |
| 48 | continue |
| 49 | } |
| 50 | // Format: %m %ct %h %H %s |
| 51 | // mark timestamp shortSHA fullSHA title... |
| 52 | parts := strings.SplitN(line, " ", 5) |
| 53 | if len(parts) < 5 { |
| 54 | continue |
| 55 | } |
| 56 | mark := parts[0] |
| 57 | ts, _ := strconv.ParseInt(parts[1], 10, 64) |
| 58 | shortSHA := parts[2] |
| 59 | fullSHA := parts[3] |
| 60 | title := parts[4] |
| 61 | |
| 62 | // Skip left-side commits (already in the old version). |
| 63 | if mark == "<" { |
| 64 | continue |
| 65 | } |
| 66 | // Skip cherry-pick equivalents that we've already seen |
| 67 | // (marked '=' by --cherry-mark). |
| 68 | if mark == "=" { |
| 69 | if seen[title] { |
| 70 | continue |
| 71 | } |
| 72 | seen[title] = true |
| 73 | } |
| 74 | |
| 75 | // Normalize cherry-pick bot titles: |
| 76 | // "chore: foo (cherry-pick #42) (#43)" → "chore: foo (#42)" |
| 77 | if m := cherryPickPRRe.FindStringSubmatch(title); m != nil { |
| 78 | title = title[:cherryPickPRRe.FindStringIndex(title)[0]] + "(#" + m[1] + ")" |
| 79 | } |
| 80 | |
| 81 | e := commitEntry{ |
| 82 | SHA: shortSHA, |
| 83 | FullSHA: fullSHA, |
| 84 | Title: title, |
| 85 | Timestamp: ts, |
no test coverage detected