| 364 | } |
| 365 | |
| 366 | func (c *Client) Commits(ctx context.Context, baseRef, headRef string) ([]*Commit, error) { |
| 367 | // The formatting directive %x00 indicates that git should include the null byte as a separator. |
| 368 | // We use this because it is not a valid character to include in a commit message. Previously, |
| 369 | // commas were used here but when we Split on them, we would get incorrect results if commit titles |
| 370 | // happened to contain them. |
| 371 | // https://git-scm.com/docs/pretty-formats#Documentation/pretty-formats.txt-emx00em |
| 372 | args := []string{"-c", "log.ShowSignature=false", "log", "--pretty=format:%H%x00%s%x00%b%x00", "--cherry", fmt.Sprintf("%s...%s", baseRef, headRef)} |
| 373 | cmd, err := c.Command(ctx, args...) |
| 374 | if err != nil { |
| 375 | return nil, err |
| 376 | } |
| 377 | out, err := cmd.Output() |
| 378 | if err != nil { |
| 379 | return nil, err |
| 380 | } |
| 381 | |
| 382 | commits := []*Commit{} |
| 383 | commitLogs := commitLogRE.FindAllString(string(out), -1) |
| 384 | for _, commitLog := range commitLogs { |
| 385 | // Each line looks like this: |
| 386 | // 6a6872b918c601a0e730710ad8473938a7516d30\u0000title 1\u0000Body 1\u0000\n |
| 387 | |
| 388 | // Or with an optional body: |
| 389 | // 6a6872b918c601a0e730710ad8473938a7516d30\u0000title 1\u0000\u0000\n |
| 390 | |
| 391 | // Therefore after splitting we will have: |
| 392 | // ["6a6872b918c601a0e730710ad8473938a7516d30", "title 1", "Body 1", ""] |
| 393 | |
| 394 | // Or with an optional body: |
| 395 | // ["6a6872b918c601a0e730710ad8473938a7516d30", "title 1", "", ""] |
| 396 | commitLogParts := strings.Split(commitLog, "\u0000") |
| 397 | commits = append(commits, &Commit{ |
| 398 | Sha: commitLogParts[0], |
| 399 | Title: commitLogParts[1], |
| 400 | Body: commitLogParts[2], |
| 401 | }) |
| 402 | } |
| 403 | |
| 404 | if len(commits) == 0 { |
| 405 | return nil, fmt.Errorf("could not find any commits between %s and %s", baseRef, headRef) |
| 406 | } |
| 407 | |
| 408 | return commits, nil |
| 409 | } |
| 410 | |
| 411 | func (c *Client) LastCommit(ctx context.Context) (*Commit, error) { |
| 412 | output, err := c.lookupCommit(ctx, "HEAD", "%H,%s") |