summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/vcs_actions/src/actions/local_actions.rs72
-rw-r--r--crates/vcs_data/src/data/local/file_status.rs50
2 files changed, 72 insertions, 50 deletions
diff --git a/crates/vcs_actions/src/actions/local_actions.rs b/crates/vcs_actions/src/actions/local_actions.rs
index d10c317..f48cf6c 100644
--- a/crates/vcs_actions/src/actions/local_actions.rs
+++ b/crates/vcs_actions/src/actions/local_actions.rs
@@ -6,17 +6,22 @@ use log::info;
use serde::{Deserialize, Serialize};
use tcp_connection::error::TcpTargetError;
use tokio::time::Instant;
-use vcs_data::data::{
- local::{
- cached_sheet::CachedSheet,
- config::LocalConfig,
- latest_info::{LatestInfo, SheetInfo},
- local_sheet::LocalSheetData,
- member_held::MemberHeld,
+use vcs_data::{
+ constants::{CLIENT_PATH_CACHED_SHEET, CLIENT_PATH_LOCAL_SHEET},
+ data::{
+ local::{
+ cached_sheet::CachedSheet,
+ config::LocalConfig,
+ latest_file_data::LatestFileData,
+ latest_info::{LatestInfo, SheetInfo},
+ },
+ member::MemberId,
+ sheet::{SheetData, SheetName},
+ vault::{
+ config::VaultUuid,
+ virtual_file::{VirtualFileId, VirtualFileVersion},
+ },
},
- member::MemberId,
- sheet::{SheetData, SheetName},
- vault::{config::VaultUuid, virtual_file::VirtualFileId},
};
use crate::actions::{
@@ -236,6 +241,11 @@ pub async fn update_to_latest_info_action(
if len < 1 {
// Don't return here, continue to next section
+ // But we need to consume the false marker from the server
+ if ctx.is_proc_on_local() {
+ let mut mut_instance = instance.lock().await;
+ let _: bool = mut_instance.read_msgpack().await?;
+ }
} else {
// Send data to local
if ctx.is_proc_on_remote() {
@@ -336,21 +346,21 @@ pub async fn update_to_latest_info_action(
.await?;
// Receive information and write to local
- let result: HashMap<VirtualFileId, Option<MemberId>> =
+ let result: HashMap<VirtualFileId, (Option<MemberId>, VirtualFileVersion)> =
mut_instance.read_large_msgpack(1024u16).await?;
// Read configuration file
- let path = MemberHeld::held_file_path(&member_id)?;
- let mut member_held = match MemberHeld::read_from(&path).await {
+ let path = LatestFileData::data_path(&member_id)?;
+ let mut latest_file_data = match LatestFileData::read_from(&path).await {
Ok(r) => r,
- Err(_) => MemberHeld::default(),
+ Err(_) => LatestFileData::default(),
};
// Write the received information
- member_held.update_held_status(result);
+ latest_file_data.update_info(result);
// Write
- MemberHeld::write_to(&member_held, &path).await?;
+ LatestFileData::write_to(&latest_file_data, &path).await?;
}
if ctx.is_proc_on_remote() {
@@ -362,7 +372,8 @@ pub async fn update_to_latest_info_action(
mut_instance.read_large_msgpack(1024u16).await?;
// Organize the information
- let mut result: HashMap<VirtualFileId, Option<MemberId>> = HashMap::new();
+ let mut result: HashMap<VirtualFileId, (Option<MemberId>, VirtualFileVersion)> =
+ HashMap::new();
for id in holder_wants_know {
let Ok(meta) = vault.virtual_file_meta(&id).await else {
continue;
@@ -370,9 +381,9 @@ pub async fn update_to_latest_info_action(
result.insert(
id,
if meta.hold_member().is_empty() {
- None
+ (None, "".to_string())
} else {
- Some(meta.hold_member().to_string())
+ (Some(meta.hold_member().to_string()), meta.version_latest())
},
);
}
@@ -385,25 +396,24 @@ pub async fn update_to_latest_info_action(
// Sync cached sheet to local sheet
if ctx.is_proc_on_local() {
let workspace = try_get_local_workspace(&ctx)?;
- let local_sheet_paths =
- extract_sheet_names_from_paths(workspace.local_sheet_paths().await?)?;
+ let cached_sheet_path = workspace.local_path().join(CLIENT_PATH_CACHED_SHEET);
+ let local_sheet_path = workspace.local_path().join(CLIENT_PATH_LOCAL_SHEET);
+ if !local_sheet_path.exists() || !cached_sheet_path.exists() {
+ // No need to sync
+ return Ok(UpdateToLatestInfoResult::Success);
+ }
+
let cached_sheet_paths =
extract_sheet_names_from_paths(CachedSheet::cached_sheet_paths().await?)?;
- // Match cached sheets and local heets, and sync content
+ // Match cached sheets and local sheets, and sync content
for (cached_sheet_name, _cached_sheet_path) in cached_sheet_paths {
- // Get local sheet path by cached_sheet_name
- let Some(local_sheet_path) = local_sheet_paths.get(&cached_sheet_name) else {
- continue;
- };
-
// Read cached sheet and local sheet
let cached_sheet = CachedSheet::cached_sheet_data(&cached_sheet_name).await?;
- let Ok(local_sheet_data) = LocalSheetData::read_from(local_sheet_path).await else {
+ let Ok(mut local_sheet) = workspace.local_sheet(&member_id, &cached_sheet_name).await
+ else {
continue;
};
- let mut local_sheet =
- local_sheet_data.wrap_to_local_sheet(&workspace, "".to_string(), "".to_string());
// Read cached id mapping
let Some(cached_sheet_id_mapping) = cached_sheet.id_mapping() else {
@@ -437,7 +447,7 @@ pub async fn update_to_latest_info_action(
},
_ => {}
}
- local_sheet.write_to_path(&local_sheet_path).await?
+ local_sheet.write().await?;
}
}
}
diff --git a/crates/vcs_data/src/data/local/file_status.rs b/crates/vcs_data/src/data/local/file_status.rs
index c37c21b..8b1c17f 100644
--- a/crates/vcs_data/src/data/local/file_status.rs
+++ b/crates/vcs_data/src/data/local/file_status.rs
@@ -55,9 +55,9 @@ impl<'a> AnalyzeResult<'a> {
// Current member, sheet
let (member, sheet_name) = {
- let lock = workspace.config.lock().await;
- let member = lock.current_account();
- let Some(sheet) = lock.sheet_in_use().clone() else {
+ let mut_workspace = workspace.config.lock().await;
+ let member = mut_workspace.current_account();
+ let Some(sheet) = mut_workspace.sheet_in_use().clone() else {
return Err(Error::new(std::io::ErrorKind::NotFound, "Sheet not found"));
};
(member, sheet)
@@ -119,8 +119,14 @@ impl<'a> AnalyzeResult<'a> {
local_sheet,
cached_sheet_data,
};
- Self::analyze_moved(&mut result, &file_relative_paths, &analyze_ctx).await?;
- Self::analyze_modified(&mut result, &file_relative_paths, &mut analyze_ctx).await?;
+ Self::analyze_moved(&mut result, &file_relative_paths, &analyze_ctx, &workspace).await?;
+ Self::analyze_modified(
+ &mut result,
+ &file_relative_paths,
+ &mut analyze_ctx,
+ &workspace,
+ )
+ .await?;
Ok(result)
}
@@ -131,6 +137,7 @@ impl<'a> AnalyzeResult<'a> {
result: &mut AnalyzeResult<'_>,
file_relative_paths: &HashSet<PathBuf>,
analyze_ctx: &AnalyzeContext<'a>,
+ workspace: &LocalWorkspace,
) -> Result<(), std::io::Error> {
let local_sheet_paths: HashSet<&PathBuf> = match &analyze_ctx.local_sheet {
Some(local_sheet) => local_sheet.data.mapping.keys().collect(),
@@ -138,20 +145,23 @@ impl<'a> AnalyzeResult<'a> {
};
let file_relative_paths_ref: HashSet<&PathBuf> = file_relative_paths.iter().collect();
- // 在本地表存在但实际不存在的文件,为丢失
+ // Files that exist in the local sheet but not in reality are considered lost
let mut lost_files: HashSet<&PathBuf> = local_sheet_paths
.difference(&file_relative_paths_ref)
.cloned()
.collect();
- // 在本地表不存在但实际存在的文件,记录为新建
+ // Files that exist in reality but not in the local sheet are recorded as newly created
let mut new_files: HashSet<&PathBuf> = file_relative_paths_ref
.difference(&local_sheet_paths)
.cloned()
.collect();
- // 计算新增的文件 Hash
- let new_files_for_hash: Vec<PathBuf> = new_files.iter().map(|p| (*p).clone()).collect();
+ // Calculate hashes for new files
+ let new_files_for_hash: Vec<PathBuf> = new_files
+ .iter()
+ .map(|p| workspace.local_path.join(p))
+ .collect();
let file_hashes: HashSet<(PathBuf, String)> =
match calc_sha1_multi::<PathBuf, Vec<PathBuf>>(new_files_for_hash, 8192).await {
Ok(hash) => hash,
@@ -161,7 +171,7 @@ impl<'a> AnalyzeResult<'a> {
.map(|r| (r.file_path.clone(), r.hash.to_string()))
.collect();
- // 建立丢失文件的 Hash 映射表
+ // Build hash mapping table for lost files
let mut lost_files_hash_mapping: HashMap<String, FromRelativePathBuf> =
match &analyze_ctx.local_sheet {
Some(local_sheet) => lost_files
@@ -175,28 +185,28 @@ impl<'a> AnalyzeResult<'a> {
None => HashMap::new(),
};
- // 如果这些 Hash 能对应缺失文件的 Hash,那么这对新增和丢失项将被合并为移动项
+ // If these hashes correspond to the hashes of missing files, then this pair of new and lost items will be merged into moved items
let mut moved_files: HashSet<(FromRelativePathBuf, ToRelativePathBuf)> = HashSet::new();
for (new_path, new_hash) in file_hashes {
- // 如果新的 Hash 值命中映射,则添加移动项
+ // If the new hash value hits the mapping, add a moved item
if let Some(lost_path) = lost_files_hash_mapping.remove(&new_hash) {
- // 移除该新增项和丢失项
+ // Remove this new item and lost item
lost_files.remove(&lost_path);
new_files.remove(&new_path);
- // 建立移动项
+ // Create moved item
moved_files.insert((lost_path.clone(), new_path));
}
}
- // 进入模糊匹配,将其他未匹配的可能移动项进行匹配
- // 如果 新增 和 缺失 数量总和能被 2 整除,则说明还存在文件被移动的可能,考虑尝试模糊匹配
+ // Enter fuzzy matching to match other potentially moved items that haven't been matched
+ // If the total number of new and lost files is divisible by 2, it indicates there might still be files that have been moved, consider trying fuzzy matching
if new_files.len() + lost_files.len() % 2 == 0 {
- // 尝试模糊匹配
+ // Try fuzzy matching
// ...
}
- // 将结果收集,并设置结果
+ // Collect results and set the result
result.created = new_files.iter().map(|p| (*p).clone()).collect();
result.lost = lost_files.iter().map(|p| (*p).clone()).collect();
result.moved = moved_files
@@ -224,6 +234,7 @@ impl<'a> AnalyzeResult<'a> {
result: &mut AnalyzeResult<'_>,
file_relative_paths: &HashSet<PathBuf>,
analyze_ctx: &mut AnalyzeContext<'a>,
+ workspace: &LocalWorkspace,
) -> Result<(), std::io::Error> {
let local_sheet = &mut analyze_ctx.local_sheet.as_mut().unwrap();
let local_path = local_sheet.local_workspace.local_path().clone();
@@ -244,7 +255,8 @@ impl<'a> AnalyzeResult<'a> {
}
// Calculate hash
- let hash_calc = match sha1_hash::calc_sha1(path, 2048).await {
+ let hash_calc = match sha1_hash::calc_sha1(workspace.local_path.join(path), 2048).await
+ {
Ok(hash) => hash,
Err(e) => return Err(Error::new(std::io::ErrorKind::Other, e)),
};