From 13523762aaccf4e77184e0168097d462744b3d4b Mon Sep 17 00:00:00 2001 From: ZhenYi <434836402@qq.com> Date: Tue, 28 Apr 2026 19:58:52 +0800 Subject: [PATCH] =?UTF-8?q?fix(fctool):=20=E4=BF=AE=E5=A4=8D=20git=20tools?= =?UTF-8?q?=20=E4=B8=AD=E7=9A=84=E7=B1=BB=E5=9E=8B=E4=B8=8D=E5=8C=B9?= =?UTF-8?q?=E9=85=8D=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - blob.rs: 修复 resolve_oid 返回 commit OID 而非 blob OID 的问题 - tree.rs: 修复 git_tree_ls_exec 直接传递 commit OID 给 tree_list 的问题 - 所有修改使类型合约与 git domain API 匹配 --- libs/fctool/src/git_tools/blob.rs | 26 +++++++------------------- libs/fctool/src/git_tools/commit.rs | 13 ++++--------- libs/fctool/src/git_tools/tree.rs | 22 ++++++++++------------ 3 files changed, 21 insertions(+), 40 deletions(-) diff --git a/libs/fctool/src/git_tools/blob.rs b/libs/fctool/src/git_tools/blob.rs index 9d651fd..66fb932 100644 --- a/libs/fctool/src/git_tools/blob.rs +++ b/libs/fctool/src/git_tools/blob.rs @@ -16,8 +16,8 @@ async fn git_blob_info_exec( let oid = p.get("oid").and_then(|v| v.as_str()).ok_or("missing oid")?; let domain = ctx.open_repo(project_name, repo_name).await?; - let commit_oid = resolve_oid(&domain, oid)?; - let info = domain.blob_get(&commit_oid).map_err(|e| e.to_string())?; + let blob_oid = git::commit::types::CommitOid::new(oid); + let info = domain.blob_get(&blob_oid).map_err(|e| e.to_string())?; Ok(serde_json::json!({ "oid": info.oid.to_string(), @@ -37,10 +37,10 @@ async fn git_blob_exists_exec( let oid = p.get("oid").and_then(|v| v.as_str()).ok_or("missing oid")?; let domain = ctx.open_repo(project_name, repo_name).await?; - let commit_oid = resolve_oid(&domain, oid)?; - let exists = domain.blob_exists(&commit_oid); + let blob_oid = git::commit::types::CommitOid::new(oid); + let exists = domain.blob_exists(&blob_oid); - Ok(serde_json::json!({ "oid": commit_oid.to_string(), "exists": exists })) + Ok(serde_json::json!({ "oid": blob_oid.to_string(), "exists": exists })) } async fn git_blob_content_exec( @@ -55,8 +55,8 @@ async fn git_blob_content_exec( let max_size = p.get("max_size").and_then(|v| v.as_u64()).unwrap_or(1_048_576) as usize; // 1MB default let domain = ctx.open_repo(project_name, repo_name).await?; - let commit_oid = resolve_oid(&domain, oid)?; - let blob = domain.blob_content(&commit_oid).map_err(|e| e.to_string())?; + let blob_oid = git::commit::types::CommitOid::new(oid); + let blob = domain.blob_content(&blob_oid).map_err(|e| e.to_string())?; if blob.size > max_size { return Err(format!( @@ -109,18 +109,6 @@ async fn git_blob_create_exec( })) } -fn resolve_oid( - domain: &git::GitDomain, - rev: &str, -) -> Result { - if rev.len() == 40 && rev.chars().all(|c| c.is_ascii_hexdigit()) { - Ok(git::commit::types::CommitOid::new(rev)) - } else if let Ok(Some(oid)) = domain.ref_target(rev) { - Ok(oid) - } else { - domain.commit_get_prefix(rev).map_err(|e| e.to_string()).map(|m| m.oid) - } -} pub fn register_git_tools(registry: &mut ToolRegistry) { // git_blob_info diff --git a/libs/fctool/src/git_tools/commit.rs b/libs/fctool/src/git_tools/commit.rs index 86fae2c..299e5b5 100644 --- a/libs/fctool/src/git_tools/commit.rs +++ b/libs/fctool/src/git_tools/commit.rs @@ -47,16 +47,11 @@ async fn git_log_exec(ctx: GitToolCtx, args: serde_json::Value) -> Result Result { - if rev.len() == 40 && rev.chars().all(|c| c.is_ascii_hexdigit()) { - domain.commit_get(&git::commit::types::CommitOid::new(rev)).map_err(|e| e.to_string()) - } else if let Ok(Some(oid)) = domain.ref_target(rev) { - domain.commit_get(&oid).map_err(|e| e.to_string()) - } else { - domain.commit_get_prefix(rev).map_err(|e| e.to_string()) - } + let oid = domain.resolve_rev(rev).map_err(|e| e.to_string())?; + domain.commit_get(&oid).map_err(|e| e.to_string()) } async fn git_show_exec(ctx: GitToolCtx, args: serde_json::Value) -> Result { diff --git a/libs/fctool/src/git_tools/tree.rs b/libs/fctool/src/git_tools/tree.rs index 7be822d..0f94e58 100644 --- a/libs/fctool/src/git_tools/tree.rs +++ b/libs/fctool/src/git_tools/tree.rs @@ -5,16 +5,10 @@ use agent::{ToolDefinition, ToolHandler, ToolParam, ToolRegistry, ToolSchema}; use base64::Engine; use std::collections::HashMap; -/// Resolve a rev string to a commit OID. Tries full OID first (exactly 40 hex chars), -/// then reference name resolution (branch, tag, HEAD), then hex prefix lookup. +/// Resolve a rev string to a commit OID using the full rev-parse machinery +/// (branch names, tags, HEAD, hex prefixes, etc.). fn resolve_commit_oid(domain: &git::GitDomain, rev: &str) -> Result { - if rev.len() == 40 && rev.chars().all(|c| c.is_ascii_hexdigit()) { - Ok(git::commit::types::CommitOid::new(rev)) - } else if let Ok(Some(oid)) = domain.ref_target(rev) { - Ok(oid) - } else { - domain.commit_get_prefix(rev).map_err(|e| e.to_string()).map(|m| m.oid) - } + domain.resolve_rev(rev).map_err(|e| e.to_string()) } async fn git_file_content_exec(ctx: GitToolCtx, args: serde_json::Value) -> Result { @@ -54,14 +48,18 @@ async fn git_tree_ls_exec(ctx: GitToolCtx, args: serde_json::Value) -> Result { - let entry = domain.tree_entry_by_path(&commit_oid, dp).map_err(|e| e.to_string())?; + let entry = domain.tree_entry_by_path(tree_oid, dp).map_err(|e| e.to_string())?; domain.tree_list(&entry.oid).map_err(|e| e.to_string())? } - None => domain.tree_list(&commit_oid).map_err(|e| e.to_string())?, + None => domain.tree_list(tree_oid).map_err(|e| e.to_string())?, }; let result: Vec<_> = entries.iter().map(|e| {