本机派生目录 .export 只认项目根那一层
project/filesystem.rs:should_skip_project_derived_path 与快照同步判定改为只看第一个路径组件,源码里的嵌套 game/.export 不再被误排。 project_snapshot/tests.rs:补测试区分根 .export 与嵌套 .export。
This commit is contained in:
@@ -415,12 +415,15 @@ pub(crate) fn should_skip_project_snapshot_path(relative_path: &str) -> bool {
|
||||
/// 这些文件能从项目源码重跑出来,不该进索引、checkpoint 或版本库视角,也不该被当成项目变更;
|
||||
/// 但 Agent 必须能写它们,所以不能并进 `should_skip_project_snapshot_path`——那份列表同时是
|
||||
/// `agc_apply_patch` 的写入门禁,并进去会让首次适配直接卡死。
|
||||
///
|
||||
/// `.export` 只认项目根那一层(`EXPORT_WORK_RELATIVE_DIR` 就是 `root/.export`):源码里合法的
|
||||
/// 嵌套目录 `game/.export/...` 是用户自己的文件,不能被误伤。
|
||||
pub(crate) fn should_skip_project_derived_path(relative_path: &str) -> bool {
|
||||
project_snapshot_path_is_excluded(relative_path, false)
|
||||
|| relative_path
|
||||
.split('/')
|
||||
.filter(|component| !component.is_empty())
|
||||
.any(|component| {
|
||||
.find(|component| !component.is_empty())
|
||||
.is_some_and(|component| {
|
||||
PROJECT_DERIVED_EXCLUDED_COMPONENTS
|
||||
.iter()
|
||||
.any(|candidate| component.eq_ignore_ascii_case(candidate))
|
||||
@@ -439,7 +442,8 @@ pub(crate) fn should_skip_project_derived_path(relative_path: &str) -> bool {
|
||||
* `.env*` 与凭据类文件名一律不参与同步;符号链接与重解析点在扫描阶段单独跳过。
|
||||
*
|
||||
* 另外,同步还多认 `PROJECT_DERIVED_EXCLUDED_COMPONENTS`(`.export`):本机派生
|
||||
* 的导出工作目录不进同步,但 Agent 仍要能读写它。
|
||||
* 的导出工作目录不进同步,但 Agent 仍要能读写它。`.export` 同样只认项目根那一层,
|
||||
* 源码里的嵌套 `game/.export/...` 不在此列。
|
||||
*/
|
||||
pub(crate) fn should_skip_project_snapshot_sync_path(relative_path: &str) -> bool {
|
||||
project_snapshot_path_is_excluded(relative_path, true)
|
||||
@@ -536,8 +540,8 @@ fn project_snapshot_path_is_excluded(relative_path: &str, include_agent_state: b
|
||||
&& !(include_agent_state && component == ".agent")
|
||||
}) || (include_agent_state
|
||||
&& components
|
||||
.iter()
|
||||
.any(|component| PROJECT_DERIVED_EXCLUDED_COMPONENTS.contains(&component.as_str())))
|
||||
.first()
|
||||
.is_some_and(|component| PROJECT_DERIVED_EXCLUDED_COMPONENTS.contains(&component.as_str())))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -267,6 +267,41 @@ fn project_snapshot_sync_policy_keeps_agent_state_and_still_blocks_credentials()
|
||||
assert!(!should_skip_project_index_path("game/main.ts"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn derived_export_directory_is_matched_only_at_the_project_root() {
|
||||
// 项目根的 `.export` 才是本机派生工作目录:数据视角与快照同步都排除。
|
||||
for root_export in [
|
||||
".export/xhs-minitool.zip",
|
||||
".export/xhs-minitool.json",
|
||||
".EXPORT/xhs-minitool.zip",
|
||||
] {
|
||||
assert!(
|
||||
should_skip_project_derived_path(root_export),
|
||||
"根目录的 .export 必须排除:{root_export}"
|
||||
);
|
||||
assert!(
|
||||
should_skip_project_snapshot_sync_path(root_export),
|
||||
"根目录的 .export 不进快照同步:{root_export}"
|
||||
);
|
||||
}
|
||||
|
||||
// 嵌套在源码目录里的 `.export` 是用户自己的文件,不能按本机派生目录误伤。
|
||||
for nested in [
|
||||
"game/.export/local.ts",
|
||||
"game/.export/xhs-minitool.zip",
|
||||
"src/vendor/.export/keep.json",
|
||||
] {
|
||||
assert!(
|
||||
!should_skip_project_derived_path(nested),
|
||||
"嵌套 .export 是用户源码,不该被数据视角排除:{nested}"
|
||||
);
|
||||
assert!(
|
||||
!should_skip_project_snapshot_sync_path(nested),
|
||||
"嵌套 .export 是用户源码,不该被排除出快照同步:{nested}"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn project_snapshot_diff_reuses_metadata_and_reports_a_single_modification() {
|
||||
let root = fixture_root();
|
||||
|
||||
Reference in New Issue
Block a user