Repository navigation
Conversation
…nvas Git leaves paths that only contain spaces unquoted, so the header for "my notes.txt" is "diff --git a/my notes.txt b/my notes.txt". _paths_from_diff_header split it with shlex and took the third and fourth words, which yields "a/my" and "notes.txt". Text edits hid this because the following "--- a/..." / "+++ b/..." lines overwrite the path. Deleted files (+++ /dev/null), binary files and mode-only changes have no such line, so the canvas named them "notes.txt" and then appended the real path from changed_files as a second, hunk-less "modified" entry. Without a rename or copy, both header names are the same path behind their prefixes. For unquoted headers, split at the space where the two names match after removing their first path component, or where they are identical (diff.noprefix). Renames and copies keep the previous fallback and are still corrected by their "rename from/to" lines. Quoted headers are unchanged. Fixes Code-Amadeus#280
5 of 7 tasks
Lucas1479
approved these changes
Nov 3, 2026
Lucas1479
left a comment
Member
There was a problem hiding this comment.
Thank you for the precise path-parsing fix and regression test. Independent real-Git checks confirm that deleted, binary and mode-only files with spaces retain their names and no longer produce duplicate canvas entries. The branch has been updated against main; the original patch is unchanged, and merge will wait for CI on this updated head. The comment about copy headers is broader than the current parser supports, but that is a separate existing copy-detection case and does not block this fix.
Lucas1479
added a commit
that referenced
this pull request
Nov 3, 2026
## What and why Fixes #281. Git patch lines are delimited by LF. Python's `splitlines()` also splits form feeds, vertical tabs and Unicode separators that belong inside a source line, producing truncated text, phantom changes and incorrect line numbers in the Work diff canvas. The parser now splits only on LF and retains its existing CRLF display handling. The Host's new-file patch generator uses the same LF framing, preserves empty/trailing blank lines and emits the missing-final-newline marker based on LF. Final Git-delta assembly no longer strips source whitespace from the last patch line. Owning layers: `server/unified_diff.py` and `server/work_artifact_registry.py`. Existing output schemas, permissions and attribution rules are unchanged. The generator is shared by Git-untracked files and new files in non-Git workspaces. ## Change class - [x] Routine bug fix with regression coverage - [ ] Product-semantic or public-contract change - [ ] Isolated experiment ## Evidence - The author's parser regression and real Git examples demonstrate the original count/text corruption. - Eight generator-to-parser cases cover embedded separators, other control characters, empty files, blank/trailing blank lines, CRLF, missing final LF and bare CR. - Three end-to-end attempt cases cover Git-tracked, Git-untracked and filesystem-new files, including trailing form-feed/space preservation. - New regressions were observed failing before their corresponding fixes. - On Windows/Python 3.12.10, `python -X utf8 -m pytest tests/test_local_git_provider_diff.py tests/test_work_artifact_registry.py tests/test_unified_diff_canvas.py tests/test_work_export_integration.py -q`: **61 passed** on head `9b8bbe869901b53ca707eb1486a721b0218d1ade`, including merged #284 and #282. - Ruff on all four changed files and `git diff --check`: passed. - No live provider calls or local Electron journey were needed for this parser/generator change; hosted checks cover the broader application. ## Final check - [x] One coherent content-preservation fix - [x] No new dependency, schema, fallback or public configuration - [x] No secrets, personal state or restricted assets - [x] CPU/model-less baseline retained --------- Co-authored-by: Lucas1479 <sli776@aucklanduni.ac.nz>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What and why
Git leaves paths that only contain spaces unquoted, so the header for
my notes.txtisdiff --git a/my notes.txt b/my notes.txt._paths_from_diff_headersplit it withshlex.splitand took the 3rd and 4th words, so the paths becamea/myandnotes.txt.Ordinary text edits hid this because the following
--- a/.../+++ b/...lines overwrite the path. Deleted files (+++ /dev/null), binary files and mode-only changes have no such line. The canvas named themnotes.txtand then appended the real path fromchanged_filesas a second, hunk-less "modified" entry (details in #280).Without a rename or copy, both names in the header are the same path behind their prefixes. That is also how Git itself splits an unquoted header. For unquoted headers, the parser now splits at the space where the two names match after removing their first path component, or where they are identical (
diff.noprefix). Renames and copies keep the previous fallback and are still corrected by theirrename from/rename tolines. Quoted headers are unchanged.Fixes #280
Linked Issue for product-semantic or public-contract changes: none (routine fix)
Change class
Owning layer:
server/unified_diff.py, the parser that turnsgit diffoutput into the provider-neutral diff canvas shape.User-visible effect, or
none: in the Work attempt diff canvas, deleted, binary and mode-only files whose paths contain spaces keep their real path and are listed once.Compatibility or migration impact, or
none: none. The output shape is unchanged.Evidence
Commands and manual journeys run:
python -m pytest -q tests/test_unified_diff_canvas.py tests/test_work_export_integration.py: 29 passed (Linux,uv sync --locked --extra dev).python tests/test_unified_diff_canvas.pyalso passes.The new test
test_parse_unified_diff_keeps_spaced_paths_without_marker_linesfails onmainand passes with this change.python -m ruff check server tests/test_unified_diff_canvas.py: passed.Parsed real
git diff HEADoutput from a scratch repository after deletingmy file.txtand editing the binarymy img.bin. Before:file.txt(deleted),img.bin, plus duplicatemy file.txt/my img.binentries. After:my file.txt(deleted) andmy img.binonly.Relevant Python tests pass
CPU/model-less baseline remains supported
Electron
npm run buildpasses when Electron code changedDependency audit passes when dependencies changed
Before/after screenshots are attached for visible UI changes
Documentation/examples are updated for changed settings or contracts
Final check