mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
Make turn diff tracking operation backed (#21180)
## Summary - replace filesystem-based turn diff tracking with an operation-backed accumulator - preserve enough verified apply_patch state to render move-overwrite cases correctly - keep the turn/diff/updated contract intact while removing remote-only turn-diff test skips This takes the assumption that no 3P services rely on the output format of `apply_patch` ## Why For the CCA file system isolation push --------- Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
committed by
GitHub
Unverified
parent
b2268999fe
commit
f7e8ff8e50
@@ -193,6 +193,7 @@ pub async fn maybe_parse_apply_patch_verified(
|
||||
let ApplyPatchFileUpdate {
|
||||
unified_diff,
|
||||
content: contents,
|
||||
..
|
||||
} = match unified_diff_from_chunks(&path, &chunks, fs, sandbox).await {
|
||||
Ok(diff) => diff,
|
||||
Err(e) => {
|
||||
@@ -707,6 +708,7 @@ PATCH"#,
|
||||
"#;
|
||||
let expected = ApplyPatchFileUpdate {
|
||||
unified_diff: expected_diff.to_string(),
|
||||
original_content: "foo\nbar\nbaz\n".to_string(),
|
||||
content: "foo\nbar\nBAZ\n".to_string(),
|
||||
};
|
||||
assert_eq!(expected, diff);
|
||||
@@ -745,6 +747,7 @@ PATCH"#,
|
||||
"#;
|
||||
let expected = ApplyPatchFileUpdate {
|
||||
unified_diff: expected_diff.to_string(),
|
||||
original_content: "foo\nbar\nbaz\n".to_string(),
|
||||
content: "foo\nbar\nbaz\nquux\n".to_string(),
|
||||
};
|
||||
assert_eq!(expected, diff);
|
||||
@@ -839,9 +842,10 @@ PATCH"#,
|
||||
|
||||
assert_eq!(action.cwd.as_path(), worktree_dir.as_path());
|
||||
|
||||
let source_path = worktree_dir.join(source_name);
|
||||
let change = action
|
||||
.changes()
|
||||
.get(&worktree_dir.join(source_name))
|
||||
.get(source_path.as_path())
|
||||
.expect("source file change present");
|
||||
|
||||
match change {
|
||||
@@ -854,4 +858,60 @@ PATCH"#,
|
||||
other => panic!("expected update change, got {other:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_unreadable_destinations_still_verify() {
|
||||
let session_dir = tempdir().unwrap();
|
||||
fs::write(session_dir.path().join("binary.dat"), [0xff, 0xfe, 0xfd]).unwrap();
|
||||
let cwd = AbsolutePathBuf::from_absolute_path(session_dir.path()).unwrap();
|
||||
let add_argv = vec![
|
||||
"apply_patch".to_string(),
|
||||
"*** Begin Patch\n*** Add File: binary.dat\n+text\n*** End Patch".to_string(),
|
||||
];
|
||||
fs::write(session_dir.path().join("source.txt"), "before\n").unwrap();
|
||||
let move_argv = vec![
|
||||
"apply_patch".to_string(),
|
||||
"*** Begin Patch\n*** Update File: source.txt\n*** Move to: binary.dat\n@@\n-before\n+after\n*** End Patch".to_string(),
|
||||
];
|
||||
|
||||
for argv in [add_argv, move_argv] {
|
||||
let result = maybe_parse_apply_patch_verified(
|
||||
&argv,
|
||||
&cwd,
|
||||
LOCAL_FS.as_ref(),
|
||||
/*sandbox*/ None,
|
||||
)
|
||||
.await;
|
||||
|
||||
assert!(matches!(result, MaybeApplyPatchVerified::Body(_)));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
#[tokio::test]
|
||||
async fn test_delete_symlink_still_verifies() {
|
||||
use std::os::unix::fs::symlink;
|
||||
|
||||
let session_dir = tempdir().unwrap();
|
||||
fs::write(session_dir.path().join("target.txt"), "target\n").unwrap();
|
||||
symlink(
|
||||
session_dir.path().join("target.txt"),
|
||||
session_dir.path().join("link.txt"),
|
||||
)
|
||||
.unwrap();
|
||||
let argv = vec![
|
||||
"apply_patch".to_string(),
|
||||
"*** Begin Patch\n*** Delete File: link.txt\n*** End Patch".to_string(),
|
||||
];
|
||||
|
||||
let result = maybe_parse_apply_patch_verified(
|
||||
&argv,
|
||||
&AbsolutePathBuf::from_absolute_path(session_dir.path()).unwrap(),
|
||||
LOCAL_FS.as_ref(),
|
||||
/*sandbox*/ None,
|
||||
)
|
||||
.await;
|
||||
|
||||
assert!(matches!(result, MaybeApplyPatchVerified::Body(_)));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user