MCPcopy Create free account
hub / github.com/atomicdotdev/atomic / run

Method run

atomic-cli/src/commands/mv.rs:197–266  ·  view source on GitHub ↗

Execute the move command. # Process 1. Find and open the repository 2. Normalize source and destination paths 3. Check that source is tracked 4. If not dry-run: a. Update tracking (move_file in repository) b. Move the actual file on disk 5. Display results

(&self)

Source from the content-addressed store, hash-verified

195 /// b. Move the actual file on disk
196 /// 5. Display results
197 fn run(&self) -> CliResult<()> {
198 // Find repository
199 let repo_root = find_repository_root()?;
200 let repo = Repository::open(&repo_root).map_err(CliError::Repository)?;
201
202 // Normalize paths
203 let source = self.normalize_path(&repo_root, &self.source)?;
204 let dest_raw = self.normalize_path(&repo_root, &self.destination)?;
205 let destination = self.resolve_destination(&repo_root, &source, &dest_raw);
206
207 // Check if source exists and is tracked
208 if !repo.is_tracked(&source).map_err(CliError::Repository)? {
209 return Err(CliError::FileNotTracked {
210 path: PathBuf::from(&source),
211 });
212 }
213
214 // Check if source file exists on disk
215 let source_path = repo_root.join(&source);
216 if !source_path.exists() {
217 return Err(CliError::FileNotFound { path: source_path });
218 }
219
220 // Check if destination is already tracked (unless force)
221 if !self.force
222 && repo
223 .is_tracked(&destination)
224 .map_err(CliError::Repository)?
225 {
226 return Err(CliError::FileAlreadyTracked {
227 path: PathBuf::from(&destination),
228 });
229 }
230
231 // Dry run mode
232 if self.dry_run {
233 println!("Would move: {} → {}", source, destination);
234 println!();
235 print_hint("(dry run - no changes made)");
236 return Ok(());
237 }
238
239 // Perform the move
240 println!("Moving: {} → {}", source, destination);
241
242 // Move the file on disk ONLY. We deliberately do NOT eagerly update
243 // tracking (no `repo.move_file`): doing so would rewrite TREE (drop
244 // old, add new) and thereby hide the rename from `record`'s move
245 // detection, which pairs a tracked-but-missing (Deleted) path with an
246 // untracked on-disk (Untracked) path of identical content into a
247 // single `GraphOp::FileMove` that preserves the inode. Leaving the
248 // working copy in that raw-rename shape lets the next `record` capture
249 // it as a genuine move. This mirrors the git importer, which also
250 // records a FileMove and lets apply update TREE rather than calling
251 // `move_file`. (Until you record, `atomic status` will show the old
252 // path as Deleted and the new path as Untracked — expected; there is
253 // no `Moved` status yet.)
254 if let Err(e) = self.move_file_on_disk(&repo_root, &source, &destination) {

Callers 1

mainFunction · 0.45

Calls 8

find_repository_rootFunction · 0.85
print_hintFunction · 0.85
print_successFunction · 0.85
normalize_pathMethod · 0.80
resolve_destinationMethod · 0.80
is_trackedMethod · 0.80
move_file_on_diskMethod · 0.80
existsMethod · 0.45

Tested by

no test coverage detected