Skip to content

autoupdate --freeze pins annotated tag object SHAs instead of commit SHAs #3644

@jezdez

Description

@jezdez

autoupdate --freeze uses git rev-parse <tag> to resolve the frozen SHA, but for annotated tags this returns the tag object SHA, not the underlying commit SHA.

This means the pinned SHA in .pre-commit-config.yaml ends up being a tag object rather than a commit. It still works at checkout time (git dereferences tag objects transparently), but it causes a few problems:

  • The SHA is not browsable on GitHub. https://github.com/<org>/<repo>/commit/<tag-object-sha> returns 404 because it's not a commit. This makes it harder to audit what code a frozen rev actually points to.
  • Tools like Dependabot that also resolve frozen pre-commit revs will resolve the same tag to the commit SHA instead, producing PRs that change the SHA without changing the version (e.g. # frozen: 1.20.0 stays the same but the rev changes). This is confusing for reviewers.
  • Compare URLs on GitHub also 404 when one side is a tag object SHA, so you can't easily diff what changed.

To reproduce, run pre-commit autoupdate --freeze on a config that uses a repo with annotated tags (e.g. blacken-docs, check-jsonschema), then check the resulting SHA:

$ git cat-file -t <frozen-sha>
tag       # <-- should be "commit"

The fix should be straightforward — in pre_commit/commands/autoupdate.py, the freeze logic:

exact = cmd_output(*_git, 'rev-parse', rev)[1].strip()

should dereference through tag objects:

exact = cmd_output(*_git, 'rev-parse', f'{rev}^{{}}')[1].strip()

^{} tells git to peel the ref until it reaches a non-tag object (i.e. the commit).

Found this while investigating conda/conda#15820 where Dependabot was showing SHA changes for blacken-docs (1.20.0 → 1.20.0) and check-jsonschema (0.37.1 → 0.37.1). The old SHAs from --freeze were annotated tag objects, the new SHAs from Dependabot were the commits those tag objects point to. Same code, different object types.

For example, for blacken-docs 1.20.0:

  • dda8db18cfc68df532abf33b185ecd12d5b7b326 — the annotated tag object (what --freeze pinned, 404s on GitHub)
  • fda77690955e9b63c6687d8806bafd56a526e45f — the commit it points to (what Dependabot resolved to, works on GitHub)

Both resolve to the same tree, confirmed via git rev-parse <sha>^{tree}.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions