From 683c5a857533e661f2f8aff0f16c9053005b5304 Mon Sep 17 00:00:00 2001 From: Canon Date: Thu, 12 Mar 2026 06:00:00 +0800 Subject: [PATCH] Fix mistaken errors when cloning FCP-Tools and Add more Logging --- Services/GitService.cs | 21 +++++++++++++++++---- Services/IGitService.cs | 2 +- UI/InteractiveMenu.cs | 8 ++++---- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/Services/GitService.cs b/Services/GitService.cs index ae5b4fe..20ee4d3 100644 --- a/Services/GitService.cs +++ b/Services/GitService.cs @@ -129,7 +129,7 @@ public partial class GitService : IGitService return exitCode == 0; } - public async Task CloneAsync(string url, string targetPath, IProgress? progress = null, + public async Task<(bool Success, string? Error)> CloneAsync(string url, string targetPath, IProgress? progress = null, IProgress? percentProgress = null, CancellationToken ct = default) { progress?.Report($"Cloning {url}..."); @@ -144,10 +144,23 @@ public partial class GitService : IGitService ct, timeoutMs: 300000); // 5 minute timeout for clone - if (exitCode != 0) - progress?.Report($"Clone failed: {error}"); + // Exit code 141 = SIGPIPE (128+13), harmless when git's progress pipe closes early + if (exitCode != 0 && exitCode != 141) + { + var errorMessage = $"Clone failed (exit code {exitCode}): url={url}, target={targetPath}, git output: {error}"; + progress?.Report(errorMessage); + return (Success: false, Error: errorMessage); + } - return exitCode == 0; + // Verify the clone actually produced a valid git repo + if (!Directory.Exists(targetPath) || !await IsGitRepositoryAsync(targetPath, ct)) + { + var errorMessage = $"Clone appeared to finish but target is not a valid git repo: url={url}, target={targetPath}, git output: {error}"; + progress?.Report(errorMessage); + return (Success: false, Error: errorMessage); + } + + return (Success: true, Error: null); } public async Task> GetRemoteBranchesAsync(string path, CancellationToken ct = default) diff --git a/Services/IGitService.cs b/Services/IGitService.cs index b7f7cf5..1518d56 100644 --- a/Services/IGitService.cs +++ b/Services/IGitService.cs @@ -12,7 +12,7 @@ public interface IGitService Task> GetIncomingCommitsAsync(string path, int limit = 10, CancellationToken ct = default); Task FetchAsync(string path, IProgress? progress = null, CancellationToken ct = default); Task PullAsync(string path, IProgress? progress = null, CancellationToken ct = default); - Task CloneAsync(string url, string targetPath, IProgress? progress = null, IProgress? percentProgress = null, CancellationToken ct = default); + Task<(bool Success, string? Error)> CloneAsync(string url, string targetPath, IProgress? progress = null, IProgress? percentProgress = null, CancellationToken ct = default); Task> GetRemoteBranchesAsync(string path, CancellationToken ct = default); Task CheckoutAsync(string path, string branchOrCommit, CancellationToken ct = default); Task ResetToCommitAsync(string path, string commitHash, CancellationToken ct = default); diff --git a/UI/InteractiveMenu.cs b/UI/InteractiveMenu.cs index ff4367d..2916c9c 100644 --- a/UI/InteractiveMenu.cs +++ b/UI/InteractiveMenu.cs @@ -221,9 +221,9 @@ public class InteractiveMenu { var targetPath = Path.Combine(_modsDirectory, repo.Name); - var cloneOk = await _gitService.CloneAsync(repo.CloneUrl, targetPath, percentProgress: progress, ct: ct); + var result = await _gitService.CloneAsync(repo.CloneUrl, targetPath, percentProgress: progress, ct: ct); - return (Success: cloneOk, Error: cloneOk ? null : "Clone failed"); + return (Success: result.Success, Error: result.Error); }); ModTableRenderer.RenderUpdateSummary(results); @@ -353,9 +353,9 @@ public class InteractiveMenu Directory.Delete(mod.Path, recursive: true); // Clone fresh with progress - var cloneOk = await _gitService.CloneAsync(repo.CloneUrl, mod.Path, percentProgress: progress, ct: ct); + var result = await _gitService.CloneAsync(repo.CloneUrl, mod.Path, percentProgress: progress, ct: ct); - return (Success: cloneOk, Error: cloneOk ? null : "Clone failed"); + return (result.Success, result.Error); } catch (Exception ex) {