Skip to content

Keep repository configuration from changing a Git.Commit object’s encoding #489

Description

@taras

What

A retained checkout can set i18n.commitEncoding in its own .git/config. Native Git then adds an encoding header to a commit object even when the admitted message, tree, parent, author and committer identity, and provider-owned time are unchanged.

This is distinct from #488: no additional program runs and no effect escapes the transaction. The repository configuration changes the durable object the transaction commits.

Reproducer

Reproduced against real Git using the exact fixed configuration and commit flags from #483:

git config i18n.commitEncoding ISO-8859-1

printf 'review message\n' | env \
  GIT_AUTHOR_DATE='1787058001 +0000' \
  GIT_COMMITTER_DATE='1787058001 +0000' \
  git \
    -c core.hooksPath=/dev/null \
    -c core.fsmonitor=false \
    -c commit.gpgSign=false \
    -c tag.gpgSign=false \
    commit --cleanup=verbatim --no-gpg-sign --file -

The resulting one-parent object retained the expected tree, parent, identity, timestamps, and message, but also held:

encoding ISO-8859-1

With the same authorized inputs and canonical UTF-8 configuration, Git produced a different commit object ID.

The live verification in performCommit() accepts the configured object because it checks parent, tree, timestamps, message bytes, and final checkout state but not the complete object header set. The retained-result parser likewise accepts the recorded SHA and relations on replay.

Consequence

Repository-local configuration becomes an undeclared input to durable commit identity. Two otherwise identical Git.Commit effects can publish different object IDs, and retained history does not explain the additional header.

This conflicts with the Git.Commit contract that the object is decided by the admitted message, index, parent, provider identity, and provider-owned time—not by what the checkout asks for.

Acceptance

  • Git.Commit uses one provider-owned canonical message encoding.
  • Repository-local i18n.commitEncoding and related output-encoding settings cannot change the committed object.
  • The resulting object is unsigned and carries only the provider-authorized headers.
  • A focused regression configures a noncanonical commit encoding and proves the object still has the canonical form.
  • Message-byte evidence, parent/tree relations, provider time, transaction rollback, cancellation, and replay-without-Git behavior remain unchanged.

Relationship

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions