diff --git a/.claude/settings.local.json b/.claude/settings.local.json index f7ccea6..7d9e6ce 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -78,7 +78,8 @@ "Bash(rustfmt --edition 2024 --check src/badge.rs src/main.rs)", "Bash(rustfmt --edition 2024 --check src/git.rs)", "Bash(rustfmt --edition 2024 --check src/badge.rs)", - "Bash(rustfmt --edition 2024 --check src/git.rs src/main.rs)" + "Bash(rustfmt --edition 2024 --check src/git.rs src/main.rs)", + "Bash(pkg-config --list-all)" ] } } diff --git a/package-lock.json b/package-lock.json index 589dd3e..a7855eb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "git-lite", - "version": "2026.7.12", + "version": "2026.7.11", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "git-lite", - "version": "2026.7.12", + "version": "2026.7.11", "dependencies": { "@lucide/svelte": "^1.21.0", "@tailwindcss/vite": "^4.3.1", diff --git a/src-tauri/src/git.rs b/src-tauri/src/git.rs index 7d25b81..a3a67c8 100644 --- a/src-tauri/src/git.rs +++ b/src-tauri/src/git.rs @@ -3415,16 +3415,47 @@ fn is_auth_error(details: &str) -> bool { || d.contains("authentication required") } +// Windows' CreateProcess rejects command lines longer than ~32K chars with +// "os error 206" (filename or extension too long). Staging/restoring a large +// number of files can easily exceed that, so split the paths across multiple +// invocations and concatenate their output. +const MAX_PATH_ARGS_CHARS: usize = 8_000; + fn run_git_with_paths( repo: &Path, base_args: &[&str], files: &[String], ) -> Result, String> { - let mut args = Vec::with_capacity(base_args.len() + files.len() + 1); - args.extend(base_args.iter().map(OsString::from)); - args.push(OsString::from("--")); - args.extend(files.iter().map(OsString::from)); - run_git(repo, args) + if files.is_empty() { + let args: Vec = base_args.iter().map(OsString::from).collect(); + return run_git(repo, args); + } + + let mut combined = Vec::new(); + let mut start = 0; + while start < files.len() { + let mut end = start; + let mut chunk_chars = 0usize; + while end < files.len() { + let len = files[end].len() + 1; + if end > start && chunk_chars + len > MAX_PATH_ARGS_CHARS { + break; + } + chunk_chars += len; + end += 1; + } + let chunk = &files[start..end]; + + let mut args = Vec::with_capacity(base_args.len() + chunk.len() + 1); + args.extend(base_args.iter().map(OsString::from)); + args.push(OsString::from("--")); + args.extend(chunk.iter().map(OsString::from)); + combined.extend(run_git(repo, args)?); + + start = end; + } + + Ok(combined) } fn run_git_with_paths_cancellable(