(directory: &Path, patches: Vec<SnapshotPatch>)
| 25 | } |
| 26 | |
| 27 | pub fn revert(directory: &Path, patches: Vec<SnapshotPatch>) -> Result<()> { |
| 28 | let git_dir = ensure_snapshot_repo(directory)?; |
| 29 | let mut seen = HashSet::new(); |
| 30 | |
| 31 | for patch in patches { |
| 32 | for file in patch.files { |
| 33 | let file_path = PathBuf::from(&file); |
| 34 | let relative = relative_to_worktree(directory, &file_path); |
| 35 | if relative.is_empty() || !seen.insert(relative.clone()) { |
| 36 | continue; |
| 37 | } |
| 38 | |
| 39 | let checkout = git_output( |
| 40 | directory, |
| 41 | &git_dir, |
| 42 | &["checkout", &patch.hash, "--", &relative], |
| 43 | ); |
| 44 | if checkout.is_err() { |
| 45 | // If file does not exist in snapshot, delete it locally. |
| 46 | let exists_in_tree = git_output( |
| 47 | directory, |
| 48 | &git_dir, |
| 49 | &["ls-tree", &patch.hash, "--", &relative], |
| 50 | ) |
| 51 | .ok() |
| 52 | .map(|out| !String::from_utf8_lossy(&out.stdout).trim().is_empty()) |
| 53 | .unwrap_or(false); |
| 54 | |
| 55 | if !exists_in_tree { |
| 56 | let absolute = if file_path.is_absolute() { |
| 57 | file_path |
| 58 | } else { |
| 59 | directory.join(&relative) |
| 60 | }; |
| 61 | let _ = fs::remove_file(absolute); |
| 62 | } |
| 63 | } |
| 64 | } |
| 65 | } |
| 66 | Ok(()) |
| 67 | } |
| 68 | |
| 69 | pub fn restore(directory: &Path, snapshot: &str) -> Result<()> { |
| 70 | let git_dir = ensure_snapshot_repo(directory)?; |
nothing calls this directly
no test coverage detected