Create .atomicignore and initialize vault AFTER git import + materialize. This runs post-import so the import's materialize step can't stomp the vault files' tracked state. The sequence is: 1. Create .atomicignore (auto-detect project type) → add → record 2. Create .vault/ with defaults → add → record 3. Status is clean.
(
repo: &mut Repository,
workdir: &std::path::Path,
kind: Option<&str>,
no_vault: bool,
)
| 932 | /// 2. Create .vault/ with defaults → add → record |
| 933 | /// 3. Status is clean. |
| 934 | fn init_atomicignore_and_vault( |
| 935 | repo: &mut Repository, |
| 936 | workdir: &std::path::Path, |
| 937 | kind: Option<&str>, |
| 938 | no_vault: bool, |
| 939 | ) -> CliResult<()> { |
| 940 | // Step 1: .atomicignore |
| 941 | { |
| 942 | let ignore_path = workdir.join(".atomicignore"); |
| 943 | if !ignore_path.exists() { |
| 944 | // Use explicit --kind if provided, otherwise auto-detect from project files |
| 945 | let ignore_content = if let Some(k) = kind { |
| 946 | super::super::init::get_ignore_template(k).unwrap_or(".atomic\n.git\n") |
| 947 | } else if workdir.join("Cargo.toml").exists() { |
| 948 | super::super::init::get_ignore_template("rust").unwrap_or(".atomic\n.git\n") |
| 949 | } else if workdir.join("package.json").exists() { |
| 950 | super::super::init::get_ignore_template("node").unwrap_or(".atomic\n.git\n") |
| 951 | } else if workdir.join("go.mod").exists() { |
| 952 | super::super::init::get_ignore_template("go").unwrap_or(".atomic\n.git\n") |
| 953 | } else if workdir.join("setup.py").exists() || workdir.join("pyproject.toml").exists() { |
| 954 | super::super::init::get_ignore_template("python").unwrap_or(".atomic\n.git\n") |
| 955 | } else { |
| 956 | ".atomic\n.git\n" |
| 957 | }; |
| 958 | let _ = std::fs::write(&ignore_path, ignore_content); |
| 959 | } |
| 960 | |
| 961 | let _ = repo.add( |
| 962 | ".atomicignore", |
| 963 | atomic_repository::TrackingOptions::default(), |
| 964 | ); |
| 965 | let header = atomic_core::change::ChangeHeader::new("Initialize repository"); |
| 966 | let options = atomic_repository::RecordOptions::new() |
| 967 | .add_path(".atomicignore") |
| 968 | .detect_raw_renames(false); |
| 969 | match repo.record(header, options) { |
| 970 | Ok(_) => print_info("Recorded .atomicignore"), |
| 971 | Err(atomic_repository::RecordError::NothingToRecord) => {} |
| 972 | Err(e) => log::warn!("Failed to record .atomicignore: {}", e), |
| 973 | } |
| 974 | } |
| 975 | |
| 976 | // Step 2: Vault (unless --no-vault) |
| 977 | if no_vault { |
| 978 | return Ok(()); |
| 979 | } |
| 980 | |
| 981 | match repo.init_vault() { |
| 982 | Ok(()) => { |
| 983 | print_info("Initialized vault at .vault/"); |
| 984 | |
| 985 | // Add all vault files |
| 986 | fn add_dir_recursive(repo: &Repository, dir: &std::path::Path) { |
| 987 | if let Ok(entries) = std::fs::read_dir(dir) { |
| 988 | for entry in entries.flatten() { |
| 989 | let path = entry.path(); |
| 990 | if path.is_dir() { |
| 991 | add_dir_recursive(repo, &path); |
no test coverage detected