Apply a stash to the current working copy. Reads raw file bytes from the sidecar directory (`.atomic/stashes/ /`) and writes them to disk. This is a pure filesystem operation — no graph interaction.
(&self, repo: &mut Repository, stash: &StashEntry)
| 564 | /// (`.atomic/stashes/<view_name>/`) and writes them to disk. |
| 565 | /// This is a pure filesystem operation — no graph interaction. |
| 566 | fn apply_stash(&self, repo: &mut Repository, stash: &StashEntry) -> CliResult<()> { |
| 567 | let stash_dir = repo.dot_dir().join("stashes").join(&stash.view_name); |
| 568 | let manifest_path = stash_dir.join("MANIFEST"); |
| 569 | |
| 570 | if !manifest_path.exists() { |
| 571 | return Err(CliError::Internal(anyhow::anyhow!( |
| 572 | "Stash sidecar not found: {}", |
| 573 | manifest_path.display() |
| 574 | ))); |
| 575 | } |
| 576 | |
| 577 | let manifest = std::fs::read_to_string(&manifest_path).map_err(|e| { |
| 578 | CliError::Internal(anyhow::anyhow!("Failed to read stash manifest: {}", e)) |
| 579 | })?; |
| 580 | |
| 581 | let repo_root = repo.root().to_path_buf(); |
| 582 | let mut files_restored = 0usize; |
| 583 | |
| 584 | for line in manifest.lines() { |
| 585 | let path = line.trim(); |
| 586 | if path.is_empty() { |
| 587 | continue; |
| 588 | } |
| 589 | let src = stash_dir.join(path); |
| 590 | let dst = repo_root.join(path); |
| 591 | |
| 592 | if src.is_file() { |
| 593 | if let Some(parent) = dst.parent() { |
| 594 | let _ = std::fs::create_dir_all(parent); |
| 595 | } |
| 596 | if std::fs::copy(&src, &dst).is_ok() { |
| 597 | files_restored += 1; |
| 598 | } |
| 599 | } |
| 600 | } |
| 601 | |
| 602 | if files_restored > 0 { |
| 603 | print_success(&format!("Applied {} to working copy", stash.reference())); |
| 604 | } else { |
| 605 | print_warning("Stash was already applied or is empty"); |
| 606 | } |
| 607 | |
| 608 | Ok(()) |
| 609 | } |
| 610 | |
| 611 | /// Execute stash list. |
| 612 | fn run_list(&self, repo: &Repository) -> CliResult<()> { |