Skip to content

Commit 179be46

Browse files
author
George Dunlap
committed
Remove "appendix" information from commit message
...similar to `git am`. Add a new field, `BodyAppendix` to PatchHeader. Modify `scanMessageBody` to return both the body and the appendix. Do this by keeping two string builders, and having it switch to the appendix builder when it finds a `---` line. Handling the newlines at the end as expected requires moving things around a bit. First, we were trimming space from the line once to decide whether the line was empty, and then trimming space again if we determined it wasn't empty. This only needs to be done once. Then, do all the trimming (both of whitespace and the prefix) first, before deciding what to do about the line. Add some tests to verify that it works as expected. NB that this patch will separate out an "appendix" even from the output of `git log`, which presumably has already been checked in. If this is not the desired behavior, we could either: 1. Make the `---` check after trimming whitespace, but before trimming the indent, or 2. Pass in a boolean to tell scanMessageBody not to separate out appendix material if we're calling from parseHeaderPretty. Signed-off-by: George Dunlap <[email protected]>
1 parent 379b893 commit 179be46

File tree

2 files changed

+92
-15
lines changed

2 files changed

+92
-15
lines changed

gitdiff/patch_header.go

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ type PatchHeader struct {
4444
// remove prefixes such as `Re: ` and `[PATCH v3 5/17]` from the
4545
// Title and place them here.
4646
SubjectPrefix string
47+
48+
// If the preamble contains a `---` line, that line and everything
49+
// after will be placed in BodyAppendix.
50+
BodyAppendix string
4751
}
4852

4953
// Message returns the commit message for the header. The message consists of
@@ -170,9 +174,17 @@ func ParsePatchDate(s string) (time.Time, error) {
170174
// `[PATCH]` or `Re:` in the same way that `git mailinfo` does.
171175
// SubjectPrefix will be set to the value of this removed string.
172176
// (`git mailinfo` is the core part of `git am` that pulls information
173-
// out of an individual mail.) Unline `git mailinfo`,
174-
// ParsePatchHeader does not at the moment remove commit states or
175-
// other extraneous matter after a `---` line.
177+
// out of an individual mail.)
178+
//
179+
// Additionally, ParsePatchHeader will separate a `---` line and
180+
// anything after it into BodyAppendix.
181+
//
182+
// Those wishing the effect of a plain `git am` should use
183+
// `PatchHeader.Title + "\n" + PatchHeader.Body` (or
184+
// `PatchHeader.Message()`). Those wishing to retain the subject
185+
// prefix and appendix material should use `PatchHeader.SubjectPrefix
186+
// + PatchHeader.Title + "\n" + PatchHeader.Body + "\n" +
187+
// PatchHeader.BodyAppendix`.
176188
func ParsePatchHeader(s string) (*PatchHeader, error) {
177189
r := bufio.NewReader(strings.NewReader(s))
178190

@@ -277,11 +289,12 @@ func parseHeaderPretty(prettyLine string, r io.Reader) (*PatchHeader, error) {
277289
h.Title = title
278290

279291
if title != "" {
280-
body := scanMessageBody(s, indent)
292+
body, appendix := scanMessageBody(s, indent)
281293
if s.Err() != nil {
282294
return nil, s.Err()
283295
}
284296
h.Body = body
297+
h.BodyAppendix = appendix
285298
}
286299

287300
return h, nil
@@ -309,29 +322,39 @@ func scanMessageTitle(s *bufio.Scanner) (title string, indent string) {
309322
return b.String(), indent
310323
}
311324

312-
func scanMessageBody(s *bufio.Scanner, indent string) string {
313-
var b strings.Builder
325+
func scanMessageBody(s *bufio.Scanner, indent string) (string, string) {
326+
// Body and appendix
327+
var body, appendix strings.Builder
328+
c := &body
314329
var empty int
315330
for i := 0; s.Scan(); i++ {
316331
line := s.Text()
317-
if strings.TrimSpace(line) == "" {
332+
333+
line = strings.TrimRightFunc(line, unicode.IsSpace)
334+
line = strings.TrimPrefix(line, indent)
335+
336+
if line == "" {
318337
empty++
319338
continue
320339
}
321340

322-
if b.Len() > 0 {
323-
b.WriteByte('\n')
341+
// Parse out "appendix" information (often added by `git
342+
// format-patch` and removed by `git am`).
343+
if c == &body && line == "---" {
344+
c = &appendix
345+
}
346+
347+
if c.Len() > 0 {
348+
c.WriteByte('\n')
324349
if empty > 0 {
325-
b.WriteByte('\n')
350+
c.WriteByte('\n')
326351
}
327352
}
328353
empty = 0
329354

330-
line = strings.TrimRightFunc(line, unicode.IsSpace)
331-
line = strings.TrimPrefix(line, indent)
332-
b.WriteString(line)
355+
c.WriteString(line)
333356
}
334-
return b.String()
357+
return body.String(), appendix.String()
335358
}
336359

337360
func parseHeaderMail(mailLine string, r io.Reader) (*PatchHeader, error) {
@@ -372,7 +395,7 @@ func parseHeaderMail(mailLine string, r io.Reader) (*PatchHeader, error) {
372395
h.SubjectPrefix, h.Title = parseSubject(subject)
373396

374397
s := bufio.NewScanner(msg.Body)
375-
h.Body = scanMessageBody(s, "")
398+
h.Body, h.BodyAppendix = scanMessageBody(s, "")
376399
if s.Err() != nil {
377400
return nil, s.Err()
378401
}

gitdiff/patch_header_test.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ func TestParsePatchHeader(t *testing.T) {
139139
expectedDate := time.Date(2020, 04, 11, 15, 21, 23, 0, time.FixedZone("PDT", -7*60*60))
140140
expectedTitle := "A sample commit to test header parsing"
141141
expectedBody := "The medium format shows the body, which\nmay wrap on to multiple lines.\n\nAnother body line."
142+
expectedBodyAppendix := "---\nCC: Joe Smith <[email protected]>"
142143

143144
tests := map[string]struct {
144145
Input string
@@ -221,6 +222,33 @@ CommitDate: Sat Apr 11 15:21:23 2020 -0700
221222
Body: expectedBody,
222223
},
223224
},
225+
"prettyAppendix": {
226+
Input: `commit 61f5cd90bed4d204ee3feb3aa41ee91d4734855b
227+
Author: Morton Haypenny <[email protected]>
228+
AuthorDate: Sat Apr 11 15:21:23 2020 -0700
229+
Commit: Morton Haypenny <[email protected]>
230+
CommitDate: Sat Apr 11 15:21:23 2020 -0700
231+
232+
A sample commit to test header parsing
233+
234+
The medium format shows the body, which
235+
may wrap on to multiple lines.
236+
237+
Another body line.
238+
---
239+
CC: Joe Smith <[email protected]>
240+
`,
241+
Header: PatchHeader{
242+
SHA: expectedSHA,
243+
Author: expectedIdentity,
244+
AuthorDate: expectedDate,
245+
Committer: expectedIdentity,
246+
CommitterDate: expectedDate,
247+
Title: expectedTitle,
248+
Body: expectedBody,
249+
BodyAppendix: expectedBodyAppendix,
250+
},
251+
},
224252
"mailbox": {
225253
Input: `From 61f5cd90bed4d204ee3feb3aa41ee91d4734855b Mon Sep 17 00:00:00 2001
226254
From: Morton Haypenny <[email protected]>
@@ -240,6 +268,28 @@ Another body line.
240268
Body: expectedBody,
241269
},
242270
},
271+
"mailboxAppendix": {
272+
Input: `From 61f5cd90bed4d204ee3feb3aa41ee91d4734855b Mon Sep 17 00:00:00 2001
273+
From: Morton Haypenny <[email protected]>
274+
Date: Sat, 11 Apr 2020 15:21:23 -0700
275+
Subject: [PATCH] A sample commit to test header parsing
276+
277+
The medium format shows the body, which
278+
may wrap on to multiple lines.
279+
280+
Another body line.
281+
---
282+
CC: Joe Smith <[email protected]>
283+
`,
284+
Header: PatchHeader{
285+
SHA: expectedSHA,
286+
Author: expectedIdentity,
287+
AuthorDate: expectedDate,
288+
Title: expectedTitle,
289+
Body: expectedBody,
290+
BodyAppendix: expectedBodyAppendix,
291+
},
292+
},
243293
"unwrapTitle": {
244294
Input: `commit 61f5cd90bed4d204ee3feb3aa41ee91d4734855b
245295
Author: Morton Haypenny <[email protected]>
@@ -333,6 +383,10 @@ Author: Morton Haypenny <[email protected]>
333383
if exp.Body != act.Body {
334384
t.Errorf("incorrect parsed body:\n expected: %q\n actual: %q", exp.Body, act.Body)
335385
}
386+
if exp.BodyAppendix != act.BodyAppendix {
387+
t.Errorf("incorrect parsed body appendix:\n expected: %q\n actual: %q",
388+
exp.BodyAppendix, act.BodyAppendix)
389+
}
336390
})
337391
}
338392
}

0 commit comments

Comments
 (0)