MoonshotAI / MoonshotAI/kimi-code

fs git_status mangles non-ASCII paths (quoted porcelain output parsed verbatim)

Open
#3,414 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
7.5k
Forks
1.2k
Avg merge
11h 53m
Merged PRs (30d)
350

Description

Summary

A tracked file whose path contains non-ASCII characters (e.g. output/2026-08-31-总能等到回踩的.md) shows up in the kimi code web/desktop changes tree as a bogus directory chain like:

"my-ai-workspace
  output
    2026-08-31-bilibili-BV175t86pEre-26.8.31-
      346
        200
          273
            ...
              204.md"

Root cause

git status --porcelain=v1 --branch is invoked without -z in both engines:

  • v2: packages/agent-core-v2/src/app/git/gitService.ts (status())
  • v1: packages/agent-core/src/services/fs/fsGitService.ts (status())

With git's default core.quotePath=true, any path containing non-ASCII bytes is C-quoted in the output:

 M "my-ai-workspace/output/...-\346\200\273\350\203\275....md"

parsePorcelain (v2 agent-core-v2/src/app/git/gitParsers.ts, v1 agent-core/src/services/fs/fsGit.ts — the two parsers are byte-identical copies) then:

  1. takes the quoted string verbatim as the path (never strips the surrounding quotes, never decodes the octal escapes), and
  2. runs it through a posix() helper that does replaceAll("\\", "/") (v2) / split(path.sep).join("/") (v1, on Windows), which turns every \3xx octal escape into a fake path segment.

The resulting wire key is "my-ai-workspace/output/...-/346/200/273/.../204.md", which the web/desktop changes tree splits on / — producing the directory chain above.

Impact

  • Changes tree renders non-ASCII paths as nonsense directory chains (leading quote glued to the first segment, trailing quote after .md).
  • Clicking such a file requests a diff for the mangled path → diff fails.
  • Rename entries are mangled the same way (the -> new half stays quoted).
  • pathFilter matching silently misses these paths.
  • ASCII-only paths are unaffected.

Reproduced against real git

$ git status --porcelain=v1 --branch
 M "my-ai-workspace/output/2026-08-31-bilibili-BV175t86pEre-26.8.31-\346\200\273\350\203\275\347\255\211\345\210\260\345\233\236\350\270\251\347\232\204.md"

$ git status --porcelain=v1 -z | od -c   # raw UTF-8, NUL-terminated, never quoted

$ git -c core.quotePath=false status --porcelain=v1
 M my-ai-workspace/output/2026-08-31-bilibili-BV175t86pEre-26.8.31-总能等到回踩的.md

With -z, rename records become XY new\0old (new path first, no -> separator).

Suggested fix

Add -z to the porcelain invocation and parse NUL-separated records in parsePorcelain (both engines). The posix() helpers can be dropped entirely — git porcelain already emits / separators on every platform, and keeping them would mangle legitimate POSIX filenames containing backslashes.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with status() in packages/agent-core-v2/src/app/git/gitService.ts and packages/agent-core/src/services/fs/fsGitService.ts, then compare parsePorcelain in the two parser files named in the issue. Trace how porcelain records reach the changes tree, including rename handling. Done means NUL-separated output preserves non-ASCII and backslash-containing paths, while path filtering and renames continue to work in both engines.

Written by the indexing model from the issue text.

Assessment

Tech stack
git, typescript
Domain
cli, devtools
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.