From df38e331ca780ea20864ab75d11909a109e023d1 Mon Sep 17 00:00:00 2001 From: Alexey Z Date: Sat, 30 May 2026 15:51:09 +0200 Subject: [PATCH] fix(windows): use cmd.exe-compatible syntax for git-log history pass The git-history popen command used `cd '%s' && git log ... 2>/dev/null`, which fails on Windows cmd.exe: single quotes are not recognized and /dev/null is not a valid path, producing "The filename, directory name, or volume label syntax is incorrect" at the git-history step of a full index. Switch to `git -C "%s" log ... 2>NUL` (POSIX: 2>/dev/null), which is valid on both cmd.exe and POSIX shells. Double-quoting the path is safe because cbm_validate_shell_arg already rejects ", $, backtick, backslash and the other active metacharacters before the command is built. Distilled from #325 onto current main (preserves the :%%ct commit-time field added since the PR branch). Closes #324. --- src/pipeline/pass_githistory.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/pipeline/pass_githistory.c b/src/pipeline/pass_githistory.c index 4be223092..da3546c80 100644 --- a/src/pipeline/pass_githistory.c +++ b/src/pipeline/pass_githistory.c @@ -225,10 +225,19 @@ static int parse_git_log(const char *repo_path, commit_t **out, int *out_count) } char cmd[CBM_SZ_1K]; +#ifdef _WIN32 + /* cmd.exe does not recognize single quotes, and '/dev/null' is a POSIX path. */ + const char *null_dev = "NUL"; +#else + const char *null_dev = "/dev/null"; +#endif + /* git -C "" works on both cmd.exe and POSIX shells. Double quotes are + * safe here because cbm_validate_shell_arg (above) rejects ", $, `, \ and the + * other shell metacharacters that would otherwise be active inside them. */ snprintf(cmd, sizeof(cmd), - "cd '%s' && git log --name-only --pretty=format:COMMIT:%%H:%%ct " - "--since='1 year ago' --max-count=10000 2>/dev/null", - repo_path); + "git -C \"%s\" log --name-only --pretty=format:COMMIT:%%H:%%ct " + "--since=\"1 year ago\" --max-count=10000 2>%s", + repo_path, null_dev); FILE *fp = cbm_popen(cmd, "r"); if (!fp) {