nikivdev/code · error

target path exists but is not a git checkout: {}

Error message

target path exists but is not a git checkout: {}

What it means

preflight_clone_target checks the clone destination state before cloning. If the target path already exists and contains files but is neither empty nor a git checkout (CloneTargetState::OccupiedNonRepo), the clone is refused with this message naming the path. It prevents clobbering unrelated directory contents.

Source

Thrown at src/repos.rs:527

    };

    configure_upstream(&target_dir, &upstream_url, fetch_depth)?;
    if shallow {
        spawn_background_history_fetch(&target_dir, !upstream_is_origin)?;
    }

    init_jj_repo(&target_dir)?;
    Ok(CloneRepoResult {
        path: target_dir,
        already_cloned: false,
    })
}

fn preflight_clone_target(target_dir: &Path) -> Result<bool> {
    match clone_target_state(target_dir)? {
        CloneTargetState::Missing | CloneTargetState::EmptyDir => Ok(false),
        CloneTargetState::GitCheckout => Ok(true),
        CloneTargetState::OccupiedNonRepo => bail!(
            "target path exists but is not a git checkout: {}",
            target_dir.display()
        ),
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum CloneTargetState {
    Missing,
    EmptyDir,
    GitCheckout,
    OccupiedNonRepo,
}

fn clone_target_state(path: &Path) -> Result<CloneTargetState> {
    if !path.exists() {
        return Ok(CloneTargetState::Missing);
    }

View on GitHub (pinned to a747e741ae)

Solutions

  1. Choose a new, empty target directory.
  2. Move/delete the existing contents at that path (after verifying they are not needed).
  3. If the directory should be a repo, re-clone or `git init`/repair it first so it becomes a valid checkout.

Example fix

// before
clone(repo, "./existing-project")  // contains random files
// after
clone(repo, "./new-target")  // missing or empty dir
// or: $ mv existing-project existing-project.bak && clone(repo, "./existing-project")
Defensive patterns

Strategy: validation

Validate before calling

fn clone_target_ok(dir: &Path) -> bool {
    match dir.try_exists() {
        Ok(false) => true,
        Ok(true) => std::fs::read_dir(dir).map_or(false, |mut d| d.next().is_none())
            || dir.join(".git").exists(),
        Err(_) => false,
    }
}

Try / catch

match clone_repo(url, target) {
    Err(e) if e.to_string().contains("target path exists but is not a git checkout") => {
        // prompt user to move the directory or pick a new target
        let alt = target.with_extension("clone");
        clone_repo(url, &alt)?;
    }
    r => r?,
}

Prevention

When it happens

Trigger: Calling clone_repo (via preflight_clone_target) with a target_dir that exists, is non-empty, and has no `.git` directory.

Common situations: Cloning into a directory that holds stray files or an old non-git project; typos in the target path reusing an existing folder; leftover build/download directories.

Related errors


AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01). Data as JSON: /api/errors/18a758b5bd6ce253. Report an issue: GitHub.