Skip to main content

apply_diff

Function apply_diff 

Source
pub fn apply_diff(
    root: impl AsRef<Path>,
    patch: &str,
) -> Result<ApplyDiffReport, ApplyDiffError>
Expand description

Applies a complete patch to files beneath root.

The patch must use *** Begin Patch and *** End Patch, with one or more *** Add File:, *** Update File:, or *** Delete File: blocks. Update blocks may include *** Move to: immediately after their file header.

Each logical file is independent: failures do not prevent unrelated files from committing. All blocks connected through the same paths are first applied in memory and then committed together, so a failed file is never left partially edited.

Paths must be non-empty and relative, may not contain . or .., and may not traverse symbolic links. Existing files must be regular UTF-8 files. Missing parent directories for added or moved files are created as needed.

Updates are installed with atomic replacement on Linux, macOS, and Windows. Overlapping paths are serialized within this process. Before each commit, the current file is compared with the snapshot used for planning; an observed external modification becomes a FailedFile conflict.

§Errors

Returns ApplyDiffError before applying file operations when root is not an accessible directory, the patch envelope is malformed, an operation path is unsafe, or the envelope contains no operations. File-specific errors are returned in ApplyDiffReport::failed instead.

§Example

use std::path::Path;
use agents_tools::apply_diff;

let report = apply_diff(
    root,
    "*** Begin Patch\n*** Update File: settings.txt\n-old\n+new\n*** End Patch",
)?;

for change in &report.applied {
    println!("{:?}: {}", change.kind, change.path.display());
}
for failure in &report.failed {
    eprintln!("{}: {}", failure.path.display(), failure.message);
}