GitoxideLabs/gitoxide · error

the new commit would be empty; use --allow-empty to create…

Error message

the new commit would be empty; use --allow-empty to create it anyway

What it means

`gix_tix::command::new::run` prepares the new commit via `edit::create::prepare_from`, which reports `prepared.is_empty` when the selected changes produce no diff relative to the parent. Without `--allow-empty`, creating such a commit is refused to avoid empty commits sneaking into the todo stack. Passing `--allow-empty` bypasses the check.

Solutions

  1. Stage or select actual changes before running `tix new`.
  2. Pass `--allow-empty` if an empty commit is intentional (e.g. markers, merge placeholders).
  3. Inspect what is staged (`gix status`) to confirm something differs from the parent.
  4. Make the script conditional: skip `tix new` when the diff against the parent is empty.

Example fix

// before
gix tix new -m "msg"
// after
gix tix new -m "msg" --allow-empty   # or stage changes first
Defensive patterns

Strategy: validation

Validate before calling

// Before running tix new: confirm the selected tree differs from the parent.
let prepared = crate::edit::create::prepare_from(repo, parent, source, author, todo)?;
if prepared.is_empty && !allow_empty { // skip or set allow_empty }

Try / catch

match run(repo, args) { Err(e) if e.to_string().contains("would be empty") => { args.allow_empty = true; run(repo, args) } other => other }

Prevention

When it happens

Trigger: Running `gix tix new` where the staged tree, index selection, or worktree selection matches the parent tree exactly (nothing selected or selected content is unchanged) and `--allow-empty` was not passed.

Common situations: Selecting no changes interactively; index/worktree selectors matching only already-committed content; scripts running `tix new` unconditionally after operations that staged nothing; expecting untracked files to count when they are ignored.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08). Data as JSON: /api/errors/55bdc53e40d53b15. Report an issue: GitHub.

Appendix: source

Thrown at gix-tix/src/command/new.rs:51

    } else if args.worktree_untracked {
        crate::edit::create::Source::WorktreeUntracked
    } else if args.worktree {
        crate::edit::create::Source::Worktree
    } else {
        crate::edit::create::Source::Default
    };
    let author = args
        .edit
        .author
        .as_deref()
        .map(gix::path::os_str_into_bstr)
        .transpose()
        .context("author is not valid UTF-8")?;
    let repository_path = repository.git_dir().to_owned();
    let bare = repository.is_bare();
    let mut prepared = crate::edit::create::prepare_from(repository, parent, source, author, args.todo)?;
    if prepared.is_empty && !args.allow_empty {
        anyhow::bail!("the new commit would be empty; use --allow-empty to create it anyway");
    }

    let explicit = super::reword::explicit_message(&args.edit, std::io::stdin())?;
    let outcome = if let Some(message) = explicit {
        let mut repository = crate::open_repository(&repository_path, bare, false)
            .context("could not reopen repository before creating commit")?;
        repository.object_cache_size(None);
        crate::edit::create::apply_message_reporting(repository, &graph, prepared, &message)?
    } else {
        let editor = prepared.editor.take().expect("prepared commits have an editor");
        let Some(edited) = crate::edit::edit_document_without_terminal(
            editor,
            &prepared.document,
            &format!("tix-commit-{}.md", std::process::id()),
        )?
        else {
            println!("no commit created: no input was provided");
            return Ok(());

View on GitHub (pinned to e73179060b)