| 167 | } |
| 168 | |
| 169 | fn ensure_git_shadow_excludes(git_dir: &Path) -> CliResult<bool> { |
| 170 | let info_dir = git_dir.join("info"); |
| 171 | std::fs::create_dir_all(&info_dir)?; |
| 172 | |
| 173 | let exclude_path = info_dir.join("exclude"); |
| 174 | let mut content = match std::fs::read_to_string(&exclude_path) { |
| 175 | Ok(content) => content, |
| 176 | Err(e) if e.kind() == ErrorKind::NotFound => String::new(), |
| 177 | Err(e) => return Err(e.into()), |
| 178 | }; |
| 179 | |
| 180 | let missing: Vec<&str> = GIT_SHADOW_EXCLUDE_PATTERNS |
| 181 | .iter() |
| 182 | .copied() |
| 183 | .filter(|pattern| !content.lines().any(|line| line.trim() == *pattern)) |
| 184 | .collect(); |
| 185 | |
| 186 | if missing.is_empty() { |
| 187 | return Ok(false); |
| 188 | } |
| 189 | |
| 190 | if !content.is_empty() && !content.ends_with('\n') { |
| 191 | content.push('\n'); |
| 192 | } |
| 193 | if !content.is_empty() { |
| 194 | content.push('\n'); |
| 195 | } |
| 196 | content.push_str("# Atomic local state (managed by atomic git import)\n"); |
| 197 | for pattern in missing { |
| 198 | content.push_str(pattern); |
| 199 | content.push('\n'); |
| 200 | } |
| 201 | |
| 202 | std::fs::write(exclude_path, content)?; |
| 203 | Ok(true) |
| 204 | } |
| 205 | |
| 206 | impl Import { |
| 207 | /// Import a single branch into an Atomic view using parallel processing. |