Repository::commit_index turns the stage-zero index into trees, writes a
commit, and advances the current branch or detached HEAD. Every read and
write goes through the repository's FileSystem; the operation works unchanged
with host, memory, and user-defined storage adapters.
use git_rs::{CommitOptions, Repository, Signature};
fn commit_staged(repository: &Repository) -> git_rs::Result<git_rs::ObjectId> {
let author = Signature::new("Ada", "ada@example.com", 1_700_000_000, 0)?;
repository.commit_index(
b"Implement object negotiation\n",
&author,
&author,
&CommitOptions::default(),
)
}The API deliberately receives author and committer identities from the caller. It does not inspect environment variables, invoke an editor, run hooks, or read the host clock. Applications can obtain identities from any configuration and remain deterministic in tests.
- An unborn symbolic
HEADcreates a root commit and its branch. - A normal commit makes the current commit its first parent.
amendreuses the current commit's parents. The passed author remains explicit, allowing either preservation or reset by the caller.- Every valid line of
MERGE_HEADbecomes a parent. Duplicate parent IDs are removed, and merge state is cleared only after publication succeeds. - Unresolved stages and intent-to-add entries are rejected by index-to-tree construction.
- An unchanged ordinary tree is rejected unless
allow_emptyis set. Merge and amend commits may retain the tree, matching their semantic purpose. - Active cherry-pick, revert, or rebase state is rejected so callers use the dedicated continuation APIs and preserve their author/message rules.
- The current
HEADtarget and expected commit are checked while locks are held. Branch publication uses compare-and-swap and updates both branch andHEADreflogs. Detached commits lock and compareHEADdirectly. max_object_sizebounds every parent commit decoded during validation.
Commit objects may be written before a later ref transaction fails. Such an object is unreachable and harmless, matching Git's content-addressed object model; no ref points to it after a failed compare-and-swap.
First stage content with Git or the library, then commit the existing index:
cargo run --example commit -- /path/to/repository "subject and message"
cargo run --example commit -- /path/to/repository "replacement" --amend
cargo run --example commit -- /path/to/repository "empty marker" --allow-emptyThis is independently written Rust code. Its behavioral tests correspond to these upstream Git contracts:
builtin/commit.c:prepare_indexprepares and validates the index used for a commit.builtin/commit.c:cmd_commitrejects unresolved entries, evaluates whether a commit is committable, reads everyMERGE_HEAD, constructs parents, writes the commit, updatesHEAD, and removes merge state.builtin/commit.c:commit_index_filespublishes the locked index state.refs/files-backend.candlockfile.cdefine compare-and-swap ref locking and atomic lockfile publication.commit.c:commit_tree_extendeddefines canonical commit construction and ordered parent headers.