gitbutlerapp/gitbutler · warning · anyhow::Error

Refusing to overwrite an existing user.name and user.email

Error message

Refusing to overwrite an existing user.name and user.email

What it means

`save_author_if_unset_in_repo` writes user.name/user.email into a destination config file only for values unset in the repository. When the repo already defines both, nothing would be set, and the function bails instead of rewriting (truncating) the destination file as a no-op — the message means 'both values already exist, nothing to copy'.

Source

Thrown at crates/but-rebase/src/commit.rs:69

    if !config_path.exists() {
        std::fs::create_dir_all(config_path.parent().context("Git user config is never /")?)?;
        std::fs::File::create(&config_path)?;
    }

    let mut config = gix::config::File::from_path_no_includes(config_path.clone(), destination)?;
    let mut something_was_set = false;
    if let Some(name) = name {
        config.set_raw_value(gix::config::tree::User::NAME, name)?;
        something_was_set = true;
    }
    if let Some(email) = email {
        config.set_raw_value(gix::config::tree::User::EMAIL, email)?;
        something_was_set = true;
    }

    if !something_was_set {
        bail!("Refusing to overwrite an existing user.name and user.email");
    }

    config.write_to(
        &mut std::fs::OpenOptions::new()
            .write(true)
            .create(false)
            .truncate(true)
            .open(config_path)?,
    )?;

    Ok(())
}

/// Use the given `commit` and possibly sign it, replacing a possibly existing signature,
/// or removing the signature if GitButler is not configured to keep it.
///
/// Signatures will be removed automatically if signing is disabled to prevent an amended commit
/// to use the old signature.

View on GitHub (pinned to caf1f223d3)

Solutions

  1. Treat this bail as 'identity already present': check the repo config first and skip the call when both values exist
  2. If the intent is to force-copy identity, use a write path that overwrites unconditionally
  3. Unset one of the values if this helper genuinely needs to write something

Example fix

// before
but_rebase::commit::save_author_if_unset_in_repo(&repo, Source::Local, name, email)?; // bails when both set

// after: treat 'already configured' as success
let cfg = repo.config_snapshot();
let both_set = cfg.string(gix::config::tree::User::NAME).is_some()
    && cfg.string(gix::config::tree::User::EMAIL).is_some();
if !both_set {
    but_rebase::commit::save_author_if_unset_in_repo(&repo, Source::Local, name, email)?;
}
Defensive patterns

Strategy: validation

Validate before calling

// Rust: skip the copy when identity is already fully configured
let cfg = repo.config_snapshot();
let both_set = cfg.string(gix::config::tree::User::NAME).is_some()
    && cfg.string(gix::config::tree::User::EMAIL).is_some();
if !both_set {
    but_rebase::commit::save_author_if_unset_in_repo(&repo, Source::Local, name, email)?;
}

Try / catch

Catch the 'Refusing to overwrite' bail and treat it as success when the intent was 'ensure an identity exists' — the repo already has user.name and user.email.

Prevention

When it happens

Trigger: Calling `save_author_if_unset_in_repo` when both `user.name` and `user.email` are already configured for the repository (global or local), which is the common case in worktree-creation flows that copy identity.

Common situations: Developer workstations with a global git identity already set; provisioning scripts that assume an unconfigured repo; CI images that bake in an identity.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20). Data as JSON: /api/errors/8c2c80563f46a108. Report an issue: GitHub.