Skip to content

Read commits, rather than render them

GenerateFromRepo gives you a changelog. Sometimes you do not want a changelog: you want to know what the commits were, so you can decide something.

CommitsFromRepo is that path.

commits, err := changelog.CommitsFromRepo(".", changelog.WithSinceTag("v1.2.0"))
if err != nil {
    return err
}

for _, c := range commits {
    fmt.Println(c.Hash[:8], c.Type, c.Scope, c.Description, c.Breaking)
}

When you need this instead of Entry

Entry is the presentation model: what the changelog shows, and what Parse reads back out of it. Two things it deliberately cannot give you:

  • The commit type. Category maps feat, fix and perf, and sends everything else to CategoryOther. If you need to tell a refactor from a chore — because they mean different things to you — Category has already erased the difference.
  • The commit hash. It is not in the rendered output, so Parse could never recover it.

Commit carries both, along with the Body, so you can read your own trailers out of it.

It does not filter the way the generator does

GenerateFromRepo drops test and ci commits, because a changelog reader does not want them. CommitsFromRepo returns them.

That is deliberate. If your rule ignores ci commits, it should ignore them visibly, by your rule, rather than because the library removed them before you saw them.

Non-conventional commits are still dropped unless you pass WithIncludeAll, and merge commits never appear.

Only the commits that touch a directory

commits, err := changelog.CommitsFromRepo(".",
    changelog.WithSinceTag("lint/v0.6.0"),
    changelog.WithPaths("lint"))

WithPaths keeps the commits whose diff against their first parent changes a file under lint/ (or exactly the file named), in the same order as the unfiltered read. For a rule it cannot express, such as everything outside a set of directories, WithPathFilter takes the predicate itself. See the generation options.

The boundary is the same one

It takes the same options as GenerateFromRepo and walks the same history the same way, so the two never disagree about what is in range. WithSinceTag names the last release; an unknown tag is an error rather than a silent full-history read.

What it will not do

It will not put anything new in the rendered changelog. Nothing here changes Entry, Parse, or a single byte of generated markdown — see what this does not do.