GitoxideLabs/gitoxide · error
Refusing to checkout index into existing directory
Error message
Refusing to checkout index into existing directory '{}' - remove it and try again What it means
Thrown by gitoxide-core's exclusive index checkout (`index::checkout_exclusive`) when the destination directory already exists on disk. This command is meant to create the destination itself, so it refuses to overwrite or merge into pre-existing content to avoid clobbering user data.
Solutions
- Delete or move the existing destination directory, then re-run the checkout
- Choose a fresh destination directory path
- In scripts, `rm -rf` the target (carefully) before invoking the checkout
- Check `dest.exists()` in the caller and pick a unique path
Example fix
// before gix repo checkout-exclusive --destination ./worktree // after rm -rf ./worktree gix repo checkout-exclusive --destination ./worktree
Defensive patterns
Strategy: validation
Validate before calling
use std::path::Path;
fn prepare_dest(dest: &Path) -> std::io::Result<()> {
if dest.exists() {
std::fs::remove_dir_all(dest)?; // or bail in the caller
}
Ok(())
} Try / catch
match index::checkout_exclusive::checkout(/* args */) {
Ok(()) => /* proceed */,
Err(e) if e.to_string().contains("Refusing to checkout index into existing directory") => {
std::fs::remove_dir_all(dest)?;
// retry once
}
Err(e) => return Err(e),
} Prevention
- Always use a fresh destination directory per run
- Clean up the destination in scripts before checkout
- Never reuse a worktree path between checkout runs without deleting it first
When it happens
Trigger: Calling `gix repo checkout-exclusive` (or the `checkout_exclusive` function) with a `dest_directory` path that already exists on the filesystem, even if the directory is empty.
Common situations: Re-running a failed checkout without cleaning up; pointing at a directory created by a previous run or by another tool; scripting where the target path is reused between runs.
Understand the failure class
Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.
Related errors
- Failed to handle repositories
- Cannot run without any task to perform on the repositories
- At least one operation failed
- No commits to process
- One or more errors occurred - checkout is incomplete
AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08).
Data as JSON: /api/errors/7bd4b74181d28141.
Report an issue: GitHub.
Appendix: source
Thrown at gitoxide-core/src/index/checkout.rs:32
pub fn checkout_exclusive(
index_path: impl AsRef<Path>,
dest_directory: impl AsRef<Path>,
repo: Option<PathBuf>,
mut err: impl std::io::Write,
mut progress: impl NestedProgress,
should_interrupt: &AtomicBool,
index::checkout_exclusive::Options {
index: Options { object_hash, .. },
empty_files,
keep_going,
thread_limit,
}: index::checkout_exclusive::Options,
) -> anyhow::Result<()> {
let repo = repo.map(gix::discover).transpose()?;
let dest_directory = dest_directory.as_ref();
if dest_directory.exists() {
bail!(
"Refusing to checkout index into existing directory '{}' - remove it and try again",
dest_directory.display()
)
}
std::fs::create_dir_all(dest_directory)?;
let mut index = parse_file(index_path, object_hash)?;
let mut num_skipped = 0;
let maybe_symlink_mode = if !empty_files && repo.is_some() {
gix::index::entry::Mode::DIR
} else {
gix::index::entry::Mode::SYMLINK
};
for entry in index.entries_mut().iter_mut().filter(|e| {
e.mode
.contains(maybe_symlink_mode | gix::index::entry::Mode::DIR | gix::index::entry::Mode::COMMIT)
}) {View on GitHub (pinned to e73179060b)