Add an empty directory to tracking explicitly. Unlike `add()` which only tracks files (directories are created implicitly), this method explicitly tracks empty directories as first-class citizens in the repository graph. This is useful for: - Preserving empty directory structure (no `.keep` files needed) - Tracking directories that will be populated later - Ensuring directory creation during clo
(
&self,
path: P,
options: TrackingOptions,
)
| 247 | /// └────────────────────────────────────────────────────────────────┘ |
| 248 | /// ``` |
| 249 | pub fn add_directory<P: AsRef<Path>>( |
| 250 | &self, |
| 251 | path: P, |
| 252 | options: TrackingOptions, |
| 253 | ) -> Result<TrackingStats, RepositoryError> { |
| 254 | use crate::tracking::add_directory_to_tree; |
| 255 | |
| 256 | let path = path.as_ref(); |
| 257 | let mut stats = TrackingStats::new(); |
| 258 | |
| 259 | // Load ignore rules |
| 260 | let rules = self.ignore_rules(); |
| 261 | |
| 262 | // Check for internal paths and ignore patterns |
| 263 | // For add_directory, we know the path is a directory |
| 264 | if should_ignore_with_rules(path, true, true, Some(&rules)) { |
| 265 | return Err(RepositoryError::PathOutsideRepository { |
| 266 | path: path.to_path_buf(), |
| 267 | }); |
| 268 | } |
| 269 | |
| 270 | // Verify the path exists and is a directory |
| 271 | let abs_path = self.root.join(path); |
| 272 | if !abs_path.exists() { |
| 273 | return Err(RepositoryError::FileNotFound { |
| 274 | path: path.to_path_buf(), |
| 275 | }); |
| 276 | } |
| 277 | |
| 278 | if !abs_path.is_dir() { |
| 279 | return Err(RepositoryError::InvalidOperation { |
| 280 | message: format!("Path is not a directory: {}", path.display()), |
| 281 | }); |
| 282 | } |
| 283 | |
| 284 | let normalized = normalize_path(path); |
| 285 | |
| 286 | // Don't modify if dry run |
| 287 | if options.dry_run { |
| 288 | stats.explicit_directories_added += 1; |
| 289 | return Ok(stats); |
| 290 | } |
| 291 | |
| 292 | let mut txn = self |
| 293 | .pristine |
| 294 | .write_txn() |
| 295 | .map_err(|e| RepositoryError::Database(e.to_string()))?; |
| 296 | |
| 297 | // Check if already tracked |
| 298 | if is_tracked(&txn, &normalized).map_err(|e| RepositoryError::Database(e.to_string()))? { |
| 299 | if !options.force { |
| 300 | return Err(RepositoryError::FileAlreadyTracked { |
| 301 | path: path.to_path_buf(), |
| 302 | }); |
| 303 | } |
| 304 | stats.skip(path.to_path_buf(), "already tracked"); |
| 305 | return Ok(stats); |
| 306 | } |
nothing calls this directly
no test coverage detected