aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/email
diff options
context:
space:
mode:
authorPimyn Girgis <pimyn@google.com>2026-01-09 09:34:26 +0100
committerAleksandr Nogikh <nogikh@google.com>2026-01-09 16:05:14 +0000
commit335c6e7a07a76ec192731e88670dedd7f3c45e0c (patch)
tree3f64ebd1550aaf0bda5c7535055573773473b093 /pkg/email
parent64c076ea8f57b01c61f2a55fbf9e82ef73fd011a (diff)
pkg/email: extract base-commit hash from emails
If the author of a patch series provides a base-commit tag, extract and store the hash.
Diffstat (limited to 'pkg/email')
-rw-r--r--pkg/email/lore/parse.go16
-rw-r--r--pkg/email/parser.go68
2 files changed, 50 insertions, 34 deletions
diff --git a/pkg/email/lore/parse.go b/pkg/email/lore/parse.go
index 3b044bf21..29b025a78 100644
--- a/pkg/email/lore/parse.go
+++ b/pkg/email/lore/parse.go
@@ -25,12 +25,13 @@ type Thread struct {
// Series represents a single patch series sent over email.
type Series struct {
- Subject string
- MessageID string
- Version int
- Corrupted string // If non-empty, contains a reason why the series better be ignored.
- Tags []string
- Patches []Patch
+ Subject string
+ MessageID string
+ Version int
+ Corrupted string // If non-empty, contains a reason why the series better be ignored.
+ Tags []string
+ Patches []Patch
+ BaseCommitHint string
}
type Patch struct {
@@ -88,6 +89,9 @@ func PatchSeries(emails []*Email) []*Series {
if !ok {
continue
}
+ if series.BaseCommitHint == "" { // Usually base-commit is in patch 0 or 1. Check them all to be safe.
+ series.BaseCommitHint = email.BaseCommitHint
+ }
seq := patch.Seq.ValueOr(1)
if seq == 0 {
// The cover email is not of interest.
diff --git a/pkg/email/parser.go b/pkg/email/parser.go
index 7c776ec72..b7404988a 100644
--- a/pkg/email/parser.go
+++ b/pkg/email/parser.go
@@ -20,20 +20,21 @@ import (
)
type Email struct {
- BugIDs []string
- MessageID string
- InReplyTo string
- Date time.Time
- Link string
- Subject string
- MailingList string
- Author string
- OwnEmail bool
- Cc []string
- RawCc []string // unstripped emails
- Body string // text/plain part
- Patch string // attached patch, if any
- Commands []*SingleCommand
+ BugIDs []string
+ MessageID string
+ InReplyTo string
+ Date time.Time
+ Link string
+ Subject string
+ MailingList string
+ Author string
+ OwnEmail bool
+ Cc []string
+ RawCc []string // unstripped emails
+ Body string // text/plain part
+ Patch string // attached patch, if any
+ BaseCommitHint string // Hash of base-commit, if provided.
+ Commands []*SingleCommand
}
type SingleCommand struct {
@@ -179,20 +180,21 @@ func Parse(r io.Reader, ownEmails, goodLists, domains []string) (*Email, error)
}
date, _ := mail.ParseDate(msg.Header.Get("Date"))
email := &Email{
- BugIDs: unique(bugIDs),
- MessageID: msg.Header.Get("Message-ID"),
- InReplyTo: extractInReplyTo(msg.Header),
- Date: date,
- Link: link,
- Author: author,
- OwnEmail: fromMe,
- MailingList: mailingList,
- Subject: subject,
- Cc: ccList,
- RawCc: mergeRawAddresses(from, originalFroms, to, cc),
- Body: bodyStr,
- Patch: patch,
- Commands: cmds,
+ BugIDs: unique(bugIDs),
+ MessageID: msg.Header.Get("Message-ID"),
+ InReplyTo: extractInReplyTo(msg.Header),
+ Date: date,
+ Link: link,
+ Author: author,
+ OwnEmail: fromMe,
+ MailingList: mailingList,
+ Subject: subject,
+ Cc: ccList,
+ RawCc: mergeRawAddresses(from, originalFroms, to, cc),
+ Body: bodyStr,
+ Patch: patch,
+ Commands: cmds,
+ BaseCommitHint: extractBaseCommitHint(bodyStr),
}
return email, nil
}
@@ -575,3 +577,13 @@ func decodeSubject(rawSubject string) string {
}
return decodedSubject
}
+
+var baseCommitRegex = regexp.MustCompile(`(?m)^base-commit:\s*([0-9a-fA-F]{40})\r?$`)
+
+func extractBaseCommitHint(email string) string {
+ matches := baseCommitRegex.FindStringSubmatch(email)
+ if matches != nil {
+ return matches[1]
+ }
+ return ""
+}