Follow-up from the Phase 5 review (#154 implementation).
GitDeployStateService parses human-readable git status --porcelain=v1 output. Three related edge cases stem from that choice:
- Rename lines are split on the last
" -> ", which mis-parses when the new path itself contains a literal " -> ".
- With default
core.quotePath=true, git octal-escapes any non-ASCII filename ("caf\303\251.md"); StripQuotes leaves the escapes intact, so the resulting pathspec matches nothing and deploy fails loudly with GitFailed.
- Quote-stripping is cosmetic rather than a real decoder.
All three fail safe (loud failure or Warning-level under-reporting; the publish-prefix staging filter always holds), which is why this was deferred rather than fixed pre-merge.
Fix: switch to git status --porcelain=v1 -z and git diff --name-only -z — NUL-separated fields are unquoted and renames are unambiguous (two consecutive NUL-separated paths). Update ParsePorcelainStatus, delete StripQuotes, and add tests for non-ASCII filenames and arrow-bearing paths in both positions.
Also worth considering while in the file: a Degraded flag on PublishStatusResult for the failed-status case, and a distinct WouldDeploy dry-run outcome.
Follow-up from the Phase 5 review (#154 implementation).
GitDeployStateServiceparses human-readablegit status --porcelain=v1output. Three related edge cases stem from that choice:" -> ", which mis-parses when the new path itself contains a literal" -> ".core.quotePath=true, git octal-escapes any non-ASCII filename ("caf\303\251.md");StripQuotesleaves the escapes intact, so the resulting pathspec matches nothing anddeployfails loudly withGitFailed.All three fail safe (loud failure or Warning-level under-reporting; the publish-prefix staging filter always holds), which is why this was deferred rather than fixed pre-merge.
Fix: switch to
git status --porcelain=v1 -zandgit diff --name-only -z— NUL-separated fields are unquoted and renames are unambiguous (two consecutive NUL-separated paths). UpdateParsePorcelainStatus, deleteStripQuotes, and add tests for non-ASCII filenames and arrow-bearing paths in both positions.Also worth considering while in the file: a
Degradedflag onPublishStatusResultfor the failed-statuscase, and a distinctWouldDeploydry-run outcome.