LLM支持优化

This commit is contained in:
2026-05-26 17:43:42 +08:00
parent a08bc809bb
commit 4331b9306e
26 changed files with 2309 additions and 669 deletions

View File

@@ -2,7 +2,6 @@ use anyhow::{bail, Context, Result};
use git2::{Repository, Signature, StatusOptions, Config, Oid, ObjectType};
use std::path::{Path, PathBuf, Component};
use std::collections::HashMap;
use tempfile;
pub mod changelog;
pub mod commit;
@@ -15,16 +14,14 @@ fn normalize_path_for_git2(path: &Path) -> PathBuf {
#[cfg(target_os = "windows")]
{
let path_str = path.to_string_lossy();
if path_str.starts_with(r"\\?\") {
if let Some(stripped) = path_str.strip_prefix(r"\\?\") {
if path_str.starts_with(r"\\?\")
&& let Some(stripped) = path_str.strip_prefix(r"\\?\") {
normalized = PathBuf::from(stripped);
}
}
if path_str.starts_with(r"\\?\UNC\") {
if let Some(stripped) = path_str.strip_prefix(r"\\?\UNC\") {
if path_str.starts_with(r"\\?\UNC\")
&& let Some(stripped) = path_str.strip_prefix(r"\\?\UNC\") {
normalized = PathBuf::from(format!(r"\\{}", stripped));
}
}
}
normalized
@@ -75,7 +72,7 @@ fn try_open_repo_with_git2(path: &Path) -> Result<Repository> {
let discover_opts = git2::RepositoryOpenFlags::empty();
let ceiling_dirs: [&str; 0] = [];
let repo = Repository::open_ext(&normalized, discover_opts, &ceiling_dirs)
let repo = Repository::open_ext(&normalized, discover_opts, ceiling_dirs)
.or_else(|_| Repository::discover(&normalized))
.or_else(|_| Repository::open(&normalized));
@@ -84,7 +81,7 @@ fn try_open_repo_with_git2(path: &Path) -> Result<Repository> {
fn try_open_repo_with_git_cli(path: &Path) -> Result<Repository> {
let output = std::process::Command::new("git")
.args(&["rev-parse", "--show-toplevel"])
.args(["rev-parse", "--show-toplevel"])
.current_dir(path)
.output()
.context("Failed to execute git command")?;
@@ -330,7 +327,7 @@ impl GitRepo {
pub fn get_staged_diff(&self) -> Result<String> {
// Use git CLI to get staged diff for better compatibility
let output = std::process::Command::new("git")
.args(&["diff", "--cached"])
.args(["diff", "--cached"])
.current_dir(&self.path)
.output()
.with_context(|| "Failed to get staged diff with git command")?;
@@ -509,11 +506,10 @@ impl GitRepo {
let mut files = vec![];
for entry in statuses.iter() {
let status = entry.status();
if status.is_index_new() || status.is_index_modified() || status.is_index_deleted() || status.is_index_renamed() || status.is_index_typechange() {
if let Some(path) = entry.path() {
if (status.is_index_new() || status.is_index_modified() || status.is_index_deleted() || status.is_index_renamed() || status.is_index_typechange())
&& let Some(path) = entry.path() {
files.push(path.to_string());
}
}
}
Ok(files)
@@ -542,7 +538,7 @@ impl GitRepo {
pub fn stage_all(&self) -> Result<()> {
// Use git command for reliable staging (handles all edge cases)
let output = std::process::Command::new("git")
.args(&["add", "-A"])
.args(["add", "-A"])
.current_dir(&self.path)
.output()
.with_context(|| "Failed to stage changes with git command")?;
@@ -626,7 +622,7 @@ impl GitRepo {
std::fs::write(temp_file.path(), message)?;
let output = std::process::Command::new("git")
.args(&["commit", "-S", "-F", temp_file.path().to_str().unwrap()])
.args(["commit", "-S", "-F", temp_file.path().to_str().unwrap()])
.current_dir(&self.path)
.output()?;
@@ -801,7 +797,7 @@ impl GitRepo {
/// Create signed tag using git CLI
fn create_signed_tag_with_git2(&self, name: &str, message: &str, _signature: &Signature, _target_id: Oid) -> Result<()> {
let output = std::process::Command::new("git")
.args(&["tag", "-s", name, "-m", message])
.args(["tag", "-s", name, "-m", message])
.current_dir(&self.path)
.output()?;
@@ -827,7 +823,7 @@ impl GitRepo {
/// Push to remote
pub fn push(&self, remote: &str, refspec: &str) -> Result<()> {
let output = std::process::Command::new("git")
.args(&["push", remote, refspec])
.args(["push", remote, refspec])
.current_dir(&self.path)
.output()?;
@@ -856,7 +852,7 @@ impl GitRepo {
pub fn status_summary(&self) -> Result<StatusSummary> {
// Use git CLI for more reliable status detection
let output = std::process::Command::new("git")
.args(&["status", "--porcelain"])
.args(["status", "--porcelain"])
.current_dir(&self.path)
.output()
.with_context(|| "Failed to get status with git command")?;
@@ -1015,20 +1011,17 @@ pub fn find_repo<P: AsRef<Path>>(start_path: P) -> Result<GitRepo> {
}
if let Ok(output) = std::process::Command::new("git")
.args(&["rev-parse", "--show-toplevel"])
.args(["rev-parse", "--show-toplevel"])
.current_dir(&resolved_start)
.output()
{
if output.status.success() {
&& output.status.success() {
let stdout = String::from_utf8_lossy(&output.stdout);
let git_root = stdout.trim();
if !git_root.is_empty() {
if let Ok(repo) = GitRepo::open(git_root) {
if !git_root.is_empty()
&& let Ok(repo) = GitRepo::open(git_root) {
return Ok(repo);
}
}
}
}
let diagnosis = diagnose_repo_issue(&resolved_start);