Skip to content

Add patch file support (unified & context diffs)#46

Merged
joske merged 36 commits into
masterfrom
dev
Apr 7, 2026
Merged

Add patch file support (unified & context diffs)#46
joske merged 36 commits into
masterfrom
dev

Conversation

@joske

@joske joske commented Mar 15, 2026

Copy link
Copy Markdown
Owner

Summary

  • Parse unified and context diff formats into structured FilePatch / Hunk types
  • Auto-detect patch files by extension (.patch, .diff) or content signatures
  • Single-file patch: opens a two-pane diff view (original vs patched), right pane read-only
  • Multi-file patch: creates a directory comparison with symlinked originals and patched copies
  • Apply hunks with strict validation (apply_hunks) or best-effort with conflict markers (apply_hunks_best_effort)
  • "Apply all non-conflicting" button applies clean hunks right-to-left, skipping conflicts
  • Path sanitization strips leading //\ to make paths relative (like git apply), rejects .. traversal and Windows drive letters
  • Conflict coloring for failed hunks in multi-file patch view
  • Temp directory cleanup on window destroy, process shutdown, and SIGINT/SIGTERM
  • Temp directories created with 0o700 permissions (owner-only)

Tests

  • 26 unit tests for patch parsing, application, and conflict detection
  • Round-trip parse+apply integration tests
  • 13 UI integration tests:
    • Single-file patch (8): window title, pane content, chunk label, tab label
    • Multi-file patch (3): window opens, shows files and subdirectories
    • Detection (2): .diff extension auto-detected, Ctrl+W closes cleanly

Other changes

  • Fix criterion::black_box deprecation (use std::hint::black_box)
  • Fix clippy format_push_string warnings in patch tests

Test plan

  • cargo test --all-targets — all tests pass
  • cargo clippy --all-targets -- -D warnings -W clippy::pedantic — clean

🤖 Generated with Claude Code

joske and others added 18 commits March 12, 2026 10:23
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Multi-file patches now open as a directory comparison showing only
  files mentioned in the patch, not the entire base tree
- Left side uses symlinks to originals so saves write through to disk
- Added PatchKind (Modified/Added/Deleted) to handle /dev/null paths
- Fixed out-of-bounds panic when patch references lines beyond file end
- Added Kompare to README comparison table

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Apply-all button (⏪ icon) for file diffs and dir patch view
  - File diff: single undo operation, skips conflict-marker chunks
  - Dir view: handles modified, new (RightOnly), and deleted (LeftOnly) files
- Fix dir view showing temp paths in headers/tooltips for patch mode
  - Labels control display names, separate tooltip_dirs for hover text
  - Resolve symlinks in open_file_diff so diff headers show original paths
- Wire FileStatus::Conflict to color conflicted files red in dir view
- Clean up patch temp dirs on shutdown and SIGTERM/SIGINT (ctrlc crate)
- Filter Same entries and empty dirs from patch dir view
- Update README with patch usage examples and comparison table

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Sanitize patch file paths: reject `..` traversal and absolute paths
- Use unpredictable temp dir name and create_dir (not create_dir_all)
  to prevent symlink race attacks
- Read only 50 lines via BufReader for patch detection instead of
  entire file
- Remove unused --patch-format CLI flag
- Propagate temp dir creation errors instead of silently swallowing
- Add /dev/null detection and a/b prefix stripping to context diff
  parser for correct Added/Deleted classification
- Preserve trailing newlines in apply_hunks and apply_hunks_best_effort

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Check for lines starting with <<<<<<< and >>>>>>> instead of exact
string matches like "<<<<<<< original". Avoids false positives on
files that happen to contain those exact substrings mid-line.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ase handling

- sanitize_patch_path: reject backslash traversal (..\) and Windows
  drive letters (C:) in addition to Unix absolute paths
- Single-file patch mode: match patch entry by filename instead of
  blindly using first entry; error if multi-file patch has no match
- Missing base files in directory patch mode now write error to both
  left and right sides (shows as Modified/conflict, not as RightOnly
  which misleadingly looks like an added file)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…d bases

- Single-file mode: reject multi-file patches where multiple entries
  share the same basename (e.g. src/foo/config.rs vs tests/config.rs)
  instead of silently picking the first match
- Deleted-file entries with missing base now write error to both sides
  and mark as conflict, so they appear in the UI instead of vanishing

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…etection

Cover: path sanitization (mixed separators, hidden files, bare ..),
apply_hunks error paths (overlapping, past EOF, context mismatch),
delete-everything and empty-hunks-list cases, best-effort all-fail
and trailing newline on conflict, unified diff git prefixes and
no-newline-at-EOF marker, added/deleted file detection, context diff
multi-hunk, is_patch_file boundary at line 50, find_conflict_blocks
unmatched/nested markers, and conflict_at_cursor_fast boundaries.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@joske joske changed the title Dev Add patch file support (unified & context diffs) Mar 15, 2026
joske and others added 4 commits March 15, 2026 22:19
Also fix clippy format_push_string warnings in patch tests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Single-file patch (8 tests): window title, pane content, chunk label,
tab label. Multi-file patch (3 tests): window opens, shows patched
files and subdirectories. Detection (2 tests): .diff extension
triggers patch mode, Ctrl+W closes cleanly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds first-class support for opening and applying .patch/.diff files by parsing unified/context diffs into structured patch types, then presenting either a single-file two-pane diff or a multi-file directory comparison with conflict highlighting and “apply all non-conflicting” actions.

Changes:

  • Introduces patch module with unified/context diff parsing plus strict/best-effort hunk application and path sanitization.
  • Adds patch UI flow (CompareMode::Patch) including single-file patch diff view, multi-file patch directory view, conflict marking, and temp-dir cleanup.
  • Extends directory/diff views with conflict status styling and “Apply all non-conflicting” controls; updates docs/tests and bumps dependencies.

Reviewed changes

Copilot reviewed 18 out of 19 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/patch.rs Core patch parsing (unified/context) + hunk application + detection/sanitization + unit tests.
src/lib.rs Exposes new patch module and adds CompareMode::Patch.
src/main.rs CLI patch auto-detection and process/app shutdown cleanup wiring.
src/ui/patch_window.rs New patch-mode window builder for single-file and multi-file patch viewing.
src/ui/mod.rs Hooks CompareMode::Patch into UI dispatch; exports temp cleanup.
src/ui/common/mod.rs Adds FileStatus::Conflict for directory view/status encoding.
src/ui/dir_window.rs Conflict status handling/styling, tooltip overrides, filtering of Same, and bulk “Apply all” for directory view.
src/ui/diff_view.rs Adds per-diff “Apply all non-conflicting (R→L)” action/button; supports label overrides when opening file diffs from dir view.
src/ui/merge_state.rs Adds additional unit tests for conflict block detection helpers.
tests/ui_integration/test_patch_single.py UI integration coverage for single-file patch viewing.
tests/ui_integration/test_patch_multi.py UI integration coverage for multi-file patch directory view.
tests/ui_integration/test_patch.py UI integration coverage for detection via .diff and Ctrl+W close behavior.
tests/fixtures/left_to_right.patch Fixture patch used by UI tests (single-file).
tests/fixtures/dirs.patch Fixture patch used by UI tests (multi-file).
TESTING.md Updates testing checklist for patch mode and apply-all behaviors.
README.md Documents patch viewing/applying feature and updates comparison table.
benches/benchmarks.rs Updates criterion black_box usage.
Cargo.toml Version bump + adds ctrlc, updates clap/criterion.
Cargo.lock Lockfile updates for new/updated dependencies.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/ui/dir_window.rs Outdated
Comment thread src/ui/dir_window.rs Outdated
Comment thread src/patch.rs Outdated
Comment thread src/main.rs
Comment thread src/ui/patch_window.rs Outdated
- RightOnly apply now copies to real base dir (not temp symlink dir)
- LeftOnly delete resolves symlink to remove original file
- sanitize_patch_path docs updated to match strip behavior
- is_right_a_patch reuses patch::is_patch_file instead of duplicating
- cleanup_patch_temp_dirs clears vec after removal

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds first-class patch (.patch/.diff) support to mergers by parsing unified/context diffs into structured patch types, rendering single-file patches as a 2-pane diff, and rendering multi-file patches as a directory comparison backed by a temp “patched” tree (with conflict tracking).

Changes:

  • Introduces patch module: patch detection, parsing (unified + context), strict apply, and best-effort apply with conflict markers.
  • Adds patch UI mode: new patch window, conflict visualization in dir view, and “Apply all non-conflicting” actions.
  • Updates CLI mode selection and shutdown/signal cleanup; adds fixtures + UI integration tests; bumps dependencies (clap/criterion) and fixes benchmark deprecation.

Reviewed changes

Copilot reviewed 18 out of 19 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/patch.rs Implements patch detection/parsing and hunk application (strict + best-effort).
src/lib.rs Exposes new patch module and adds CompareMode::Patch.
src/main.rs Auto-detects patch inputs and wires temp-dir cleanup on shutdown/signals.
src/ui/patch_window.rs New patch-mode UI: single-file diff view and multi-file dir comparison via temp trees.
src/ui/mod.rs Registers patch window module and routes CompareMode::Patch to builder.
src/ui/diff_view.rs Adds “Apply all non-conflicting” in file diff view; updates open_file_diff to accept labels and resolve symlinks.
src/ui/dir_window.rs Adds Conflict status, conflict marker ingestion, tooltip overrides, and bulk-apply button.
src/ui/common/mod.rs Extends FileStatus with Conflict and status code mapping.
src/ui/merge_state.rs Adds extra unit tests for conflict marker block detection helpers.
tests/ui_integration/test_patch_single.py UI integration coverage for single-file patch window behavior.
tests/ui_integration/test_patch_multi.py UI integration coverage for multi-file patch directory view behavior.
tests/ui_integration/test_patch.py UI integration coverage for patch auto-detection and Ctrl+W close behavior.
tests/fixtures/left_to_right.patch Single-file patch fixture used by UI tests.
tests/fixtures/dirs.patch Multi-file patch fixture used by UI tests.
benches/benchmarks.rs Replaces deprecated criterion::black_box with std::hint::black_box.
TESTING.md Documents patch-mode and apply-all scenarios in the testing checklist.
README.md Documents patch viewing feature and updates comparison table/examples.
Cargo.toml Version bump + dependency updates (clap/criterion) and adds ctrlc.
Cargo.lock Lockfile updates for dependency changes.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/ui/dir_window.rs Outdated
Comment thread src/ui/dir_window.rs Outdated
Comment thread src/ui/patch_window.rs Outdated
Comment thread src/ui/patch_window.rs Outdated
Comment thread src/patch.rs Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds first-class patch (.patch/.diff) support to mergers, enabling users to open a patch against a file or directory and review/apply changes via the existing diff/dir UI.

Changes:

  • Introduces unified + context diff parsing and hunk application (strict + best-effort with conflict markers).
  • Adds a dedicated patch UI flow (single-file diff view; multi-file patch presented as a temp dir comparison with conflict highlighting).
  • Extends directory/diff UIs with conflict status + “Apply all non-conflicting” actions, and updates CLI/docs/tests accordingly.

Reviewed changes

Copilot reviewed 18 out of 19 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
tests/ui_integration/test_patch_single.py Adds UI integration coverage for single-file patch view (titles/panes/labels).
tests/ui_integration/test_patch_multi.py Adds UI integration coverage for multi-file patch dir view.
tests/ui_integration/test_patch.py Adds UI integration coverage for patch detection (.diff) and Ctrl+W close behavior.
tests/fixtures/left_to_right.patch Patch fixture for single-file patch tests.
tests/fixtures/dirs.patch Patch fixture for multi-file patch tests.
src/ui/patch_window.rs Implements patch-mode window creation, temp dir lifecycle, and single/multi patch presentation.
src/ui/mod.rs Wires new CompareMode::Patch into UI dispatch + exports temp-dir cleanup.
src/ui/merge_state.rs Adds additional unit tests around conflict-block detection helpers.
src/ui/dir_window.rs Adds conflict status, conflict coloring, store filtering, tooltip overrides, and bulk “apply all” for patch dir mode.
src/ui/diff_view.rs Adds “apply all non-conflicting chunks” action/button and improves patch-mode tab labeling/path resolution.
src/ui/common/mod.rs Adds FileStatus::Conflict code.
src/patch.rs New patch parsing/apply module (unified + context), sanitization, detection, and extensive unit tests.
src/main.rs Adds CLI patch detection and connects shutdown/signal cleanup for patch temp dirs.
src/lib.rs Exposes new patch module and adds CompareMode::Patch.
benches/benchmarks.rs Updates criterion::black_box usage to std::hint::black_box.
TESTING.md Documents new patch-related scenarios and test checklist items.
README.md Documents patch viewing/applying feature and CLI usage examples; updates comparison table.
Cargo.toml Bumps version, updates dependencies, adds ctrlc.
Cargo.lock Updates lockfile for dependency changes.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/ui/dir_window.rs Outdated
Comment thread src/ui/patch_window.rs Outdated
Comment thread src/ui/patch_window.rs Outdated
Comment thread src/patch.rs
Comment thread src/patch.rs Outdated
Comment thread src/patch.rs Outdated
…ation

- Use tempfile crate for secure temp dir creation (0o700, collision-resistant)
- Check conflicts before content comparison so identical-content conflicts
  still show as Conflict
- Use stripped paths (not raw headers) for /dev/null detection in both
  unified and context diff parsers
- Validate hunk old_count/new_count against actual line counts in apply_hunks
- parse_patch returns error when no file headers found

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds first-class support for opening/applying .patch/.diff files in the UI and CLI, including conflict-aware application flows and supporting UI affordances (conflict status + bulk apply).

Changes:

  • Introduces a patch parsing/apply engine (parse_patch, apply_hunks, best-effort conflict markers) supporting unified + context diffs.
  • Adds a new Patch compare mode wired through CLI and GTK UI (single-file patch diff view; multi-file patch as a temp dir-based directory comparison).
  • Extends directory/diff UIs with conflict status + “Apply all non-conflicting” bulk-apply actions, plus temp-dir cleanup hooks.

Reviewed changes

Copilot reviewed 18 out of 19 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/patch.rs Implements parsing (unified/context) into FilePatch/Hunk and hunk application (strict + best-effort).
src/lib.rs Exposes new patch module and CompareMode::Patch.
src/main.rs Detects patch inputs, routes to Patch mode, and adds temp-dir cleanup on shutdown/signals.
src/ui/patch_window.rs New patch-mode window implementation for single/multi-file patch viewing and temp-dir lifecycle.
src/ui/mod.rs Wires Patch mode into UI dispatcher and re-exports cleanup function.
src/ui/diff_view.rs Adds “Apply all non-conflicting” action/button and improves patch-mode labels/path resolution.
src/ui/dir_window.rs Adds Conflict status handling, conflict marker ingestion, tooltip overrides, filtering of Same/empty dirs, and bulk apply-all for directories.
src/ui/common/mod.rs Adds FileStatus::Conflict and status code mapping.
src/ui/merge_state.rs Adds test coverage for additional conflict-marker edge cases.
tests/ui_integration/test_patch_single.py UI integration coverage for single-file patch mode.
tests/ui_integration/test_patch_multi.py UI integration coverage for multi-file patch mode.
tests/ui_integration/test_patch.py UI integration coverage for detection (.diff) and Ctrl+W close behavior.
tests/fixtures/left_to_right.patch Adds fixture patch for single-file patch tests.
tests/fixtures/dirs.patch Adds fixture patch for multi-file patch tests.
TESTING.md Updates manual/automated coverage checklist for patch/apply-all features and conflict coloring.
README.md Documents patch viewing/applying feature and CLI examples; updates comparison table.
benches/benchmarks.rs Updates black_box usage to std::hint::black_box.
Cargo.toml Bumps crate version and adds deps (ctrlc, tempfile), plus dependency updates.
Cargo.lock Lockfile updates for new/updated dependencies.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/ui/dir_window.rs Outdated
Comment thread src/ui/dir_window.rs
Comment thread src/ui/patch_window.rs
- Disable apply-all button when panes are swapped in patch mode
- Swap tooltip overrides alongside dirs/labels in swap handler
- Log and mark as conflict when fs::write fails for patched files

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds first-class support for opening/applying .patch/.diff files in the mergers UI, including parsing unified/context diffs, rendering single-file patches as a 2-pane diff, and multi-file patches as a directory comparison with conflict visualization and bulk-apply helpers.

Changes:

  • Introduce patch module to parse/apply unified & context diffs with path sanitization and best-effort conflict markers.
  • Add patch UI mode (single-file diff view / multi-file dir comparison) with temp-dir lifecycle management and conflict highlighting.
  • Extend UI directory/diff views with “Apply all non-conflicting” actions and patch-specific labeling/tooltips; add UI integration tests and docs updates.

Reviewed changes

Copilot reviewed 18 out of 19 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/patch.rs New patch parsing/apply engine for unified/context diffs + tests.
src/lib.rs Exposes new patch module and adds CompareMode::Patch.
src/main.rs Detects patch inputs and wires shutdown/signal cleanup.
src/ui/patch_window.rs New patch-mode window builder (single & multi-file workflows).
src/ui/mod.rs Registers patch UI module and routes CompareMode::Patch.
src/ui/common/mod.rs Adds FileStatus::Conflict for UI state.
src/ui/dir_window.rs Conflict-aware scan/filtering, tooltip overrides, bulk apply-all for dir view.
src/ui/diff_view.rs Adds apply-all-non-conflicting action for chunk copy R→L; label support for opened diffs.
src/ui/merge_state.rs Adds edge-case tests for conflict block detection helpers.
tests/ui_integration/test_patch_single.py UI integration coverage for single-file patch viewing.
tests/ui_integration/test_patch_multi.py UI integration coverage for multi-file patch viewing.
tests/ui_integration/test_patch.py UI integration coverage for patch detection and Ctrl+W close.
tests/fixtures/left_to_right.patch Fixture patch for single-file patch tests.
tests/fixtures/dirs.patch Fixture patch for multi-file patch tests.
README.md Documents patch viewing/applying support.
TESTING.md Expands patch-mode manual/automated test checklist.
Cargo.toml Bumps version and adds dependencies for temp dirs and signal handling; updates clap/criterion.
Cargo.lock Locks dependency updates.
benches/benchmarks.rs Replaces deprecated criterion::black_box usage.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/patch.rs
Comment thread src/ui/dir_window.rs Outdated
The GTK ListStore walker can't be unit tested without main-thread
init. Replace stub matches!() tests with focused predicate tests
covering: status filtering (Different/RightOnly/LeftOnly included,
Conflict/Same excluded), mixed-status filtering, and non-patch mode
LeftOnly exclusion.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds first-class patch-file support to mergers, enabling unified/context .patch/.diff files to be opened as either a single-file diff view or a multi-file directory comparison with conflict highlighting and “apply all non-conflicting” workflows.

Changes:

  • Introduces src/patch.rs with patch detection, parsing (unified + context), path sanitization, and strict/best-effort hunk application.
  • Adds patch UI mode (src/ui/patch_window.rs) and integrates it into CLI + UI routing (CompareMode::Patch).
  • Extends directory/diff UIs with conflict status + bulk apply behaviors, plus adds fixtures and UI integration tests for patch mode.

Reviewed changes

Copilot reviewed 18 out of 19 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/patch.rs Patch parsing/apply core logic, detection, and path sanitization with extensive unit tests.
src/ui/patch_window.rs New patch-mode window: single-file patch diff view + multi-file temp-tree directory view.
src/ui/dir_window.rs Adds Conflict status, conflict coloring, hides .mergers-conflicts, tooltips override, and bulk “apply all”.
src/ui/diff_view.rs Adds “apply all non-conflicting chunks right→left” action/button; updates open_file_diff to accept labels and resolve symlinks.
src/ui/common/mod.rs Adds FileStatus::Conflict and status code mapping.
src/ui/mod.rs Wires CompareMode::Patch to the new patch window and exports cleanup helper.
src/main.rs CLI patch autodetection, new Patch mode selection, and temp-dir cleanup on shutdown/signals.
src/lib.rs Exposes patch module and adds CompareMode::Patch.
tests/ui_integration/test_patch*.py UI integration coverage for single-file patch, multi-file patch, and .diff autodetect/close behavior.
tests/fixtures/*.patch Patch fixtures used by UI tests.
TESTING.md / README.md Documents patch viewing/applying capabilities and updates testing checklist.
Cargo.toml / Cargo.lock / benches/benchmarks.rs Adds deps (ctrlc, tempfile), bumps versions, and updates benchmark black_box usage.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/ui/dir_window.rs Outdated
Comment thread src/ui/patch_window.rs
Comment thread src/patch.rs Outdated
Comment thread src/patch.rs Outdated
Comment thread src/patch.rs Outdated
…marker filter

- sanitize_patch_path: normalize backslashes to forward slashes so
  Windows-produced patches create correct dir structure on Unix;
  return String instead of &str
- apply_hunks/apply_hunks_best_effort: don't append trailing newline
  when output is empty (delete-everything case)
- read_dir_entries: remove hardcoded .mergers-conflicts skip that hid
  real user files with that name in non-patch mode
- tempfile::TempDir::keep() returns PathBuf in tempfile 3.26 — no fix
  needed (copilot comment was incorrect)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds first-class support for opening and applying .patch/.diff files, integrating patch parsing/application into the existing GTK diff/dir UI and CLI mode selection.

Changes:

  • Introduces a new patch module to parse unified/context diffs and apply hunks (strict + best-effort with conflict markers).
  • Adds a new Patch UI flow: single-file patch opens a 2-pane diff; multi-file patch materializes temp left/right trees and opens a directory comparison with conflict highlighting and bulk “apply all non-conflicting”.
  • Extends CLI + UI plumbing to auto-detect patch inputs, wire a new CompareMode::Patch, and clean up patch temp dirs on shutdown/signals.

Reviewed changes

Copilot reviewed 18 out of 19 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
tests/ui_integration/test_patch_single.py UI integration coverage for single-file patch view behaviors.
tests/ui_integration/test_patch_multi.py UI integration coverage for multi-file patch directory view.
tests/ui_integration/test_patch.py UI integration coverage for patch detection and close behavior.
tests/fixtures/left_to_right.patch Fixture patch for single-file patch tests.
tests/fixtures/dirs.patch Fixture patch for multi-file patch tests.
src/ui/patch_window.rs New patch-mode window builder (single-file diff or multi-file dir compare) + temp-dir cleanup registry.
src/ui/mod.rs Wires CompareMode::Patch into UI builder and exports cleanup helper.
src/ui/merge_state.rs Adds additional unit tests around conflict marker detection helpers.
src/ui/dir_window.rs Adds conflict status handling, conflict coloring, Same-entry pruning, tooltip overrides, and bulk apply-all for non-conflicts.
src/ui/diff_view.rs Adds diff-view “apply all non-conflicting right→left” action + label override support for dir-opened diffs.
src/ui/common/mod.rs Extends FileStatus with Conflict and status code mapping.
src/patch.rs New patch parsing + application implementation with unit tests.
src/main.rs Adds patch auto-detection and Patch mode selection; installs shutdown/signal cleanup hooks.
src/lib.rs Exposes the new patch module and adds CompareMode::Patch.
benches/benchmarks.rs Updates black_box import to std::hint::black_box.
TESTING.md Documents patch-mode and apply-all test matrix.
README.md Updates feature list and usage examples to include patch viewing/applying.
Cargo.toml Bumps version and adds dependencies (ctrlc, tempfile, clap/criterion updates).
Cargo.lock Locks new/updated dependency versions for the new features.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tests/ui_integration/test_patch_multi.py Outdated
Comment thread tests/ui_integration/test_patch.py Outdated
Comment thread src/patch.rs
Comment thread src/ui/diff_view.rs Outdated
Comment thread src/ui/dir_window.rs Outdated
Comment thread src/ui/dir_window.rs Outdated
Comment thread tests/ui_integration/test_patch_single.py Outdated
- is_context_diff/is_patch_file: require both separator and file header
  pair to avoid mis-routing unified diffs containing "***************"
- parse_patch: return error when context parsing yields no file entries
- apply-all: skip chunks containing any conflict marker line, not just
  paired markers, to handle conflict blocks split across chunks
- Bulk apply: re-mark directories as saving per file to extend the
  600ms watcher suppression window across the entire operation
- read_dir_entries: use symlink_metadata for size/mtime; treat
  fs::read errors as Different instead of Same (fixes symlink-to-dir
  misclassification)
- Remove unused Python test imports

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds first-class support for opening/applying unified + context diff patch files within the GTK UI, integrating patch workflows into existing diff/dir comparison views.

Changes:

  • Introduces a patch parser/apply engine (FilePatch/Hunk, strict + best-effort application, path sanitization, patch detection).
  • Adds a new patch UI mode: single-file patch opens a two-pane diff; multi-file patch builds a temp dir tree + dir comparison with conflict highlighting and bulk-apply.
  • Updates CLI/app lifecycle for patch detection, temp-dir cleanup (shutdown + SIGINT/SIGTERM), and expands UI/tests/docs accordingly.

Reviewed changes

Copilot reviewed 18 out of 19 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/ui_integration/test_patch_single.py Adds UI integration coverage for single-file patch viewing.
tests/ui_integration/test_patch_multi.py Adds UI integration coverage for multi-file patch viewing.
tests/ui_integration/test_patch.py Adds UI integration coverage for .diff auto-detection + Ctrl+W close.
tests/fixtures/left_to_right.patch Adds a single-file unified diff fixture.
tests/fixtures/dirs.patch Adds a multi-file unified diff fixture (incl. subdir).
src/ui/patch_window.rs New patch window implementation (single-file diff + multi-file dir view).
src/ui/mod.rs Wires CompareMode::Patch and re-exports cleanup for temp dirs.
src/ui/merge_state.rs Adds additional unit tests for conflict marker detection helpers.
src/ui/dir_window.rs Adds conflict status, conflict styling, tooltip overrides, and “apply all non-conflicting” for dir views.
src/ui/diff_view.rs Adds “apply all non-conflicting chunks” action/button and label-aware file-diff tabs with symlink resolution.
src/ui/common/mod.rs Extends FileStatus with Conflict.
src/patch.rs New patch parsing/applying module (unified + context diff).
src/main.rs Adds patch auto-detection, new CLI mode routing, and temp-dir cleanup on shutdown/signals.
src/lib.rs Exposes new patch module and CompareMode::Patch.
benches/benchmarks.rs Updates black_box usage to std::hint::black_box.
TESTING.md Documents patch workflows and new apply-all behaviors (test checklist updates).
README.md Documents patch viewing/applying feature and CLI examples.
Cargo.toml Bumps version, adds runtime deps (ctrlc, tempfile), updates clap/criterion versions.
Cargo.lock Lockfile updates for dependency/version changes.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/patch.rs Outdated
Comment thread src/ui/dir_window.rs Outdated
Comment thread src/ui/patch_window.rs
…ode, make right pane read-only

- Unified diff parser: remove is_empty() special case that treated
  blank lines as context, which could misparse patches with blank
  separator lines between hunks
- scan_tree: only read .mergers-conflicts marker file in patch mode
  to avoid misclassifying files in normal directory comparisons
- Single-file patch: set right text view to non-editable since it
  shows generated patched output
- Add right_text_view to DiffViewResult for patch mode access

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds first-class support for opening and applying .patch/.diff files in the mergers UI by introducing a patch parser/applicator and new UI flows for single-file and multi-file patch viewing, including conflict highlighting and bulk “apply all non-conflicting” actions.

Changes:

  • Added patch module to parse unified/context diffs into FilePatch/Hunk and apply them strictly or best-effort with conflict markers.
  • Added patch-mode UI: single-file patch opens a two-pane diff; multi-file patch builds a temp dir comparison tree with conflict coloring and an apply-all workflow.
  • Updated CLI mode selection to auto-detect patch inputs, added temp-dir cleanup on shutdown/signals, and refreshed docs/tests accordingly.

Reviewed changes

Copilot reviewed 18 out of 19 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/patch.rs New patch parsing + application logic (unified + context diffs), sanitization, and unit tests.
src/ui/patch_window.rs New patch window implementation for single- and multi-file patch viewing, temp-dir lifecycle handling.
src/ui/dir_window.rs Adds Conflict status, conflict marker integration, tooltip overrides, filtering/pruning, and “apply all non-conflicting” for dir views.
src/ui/diff_view.rs Adds “apply all non-conflicting” for chunk-level diffs; improves patch-mode labels and symlink path resolution.
src/ui/common/mod.rs Extends FileStatus with Conflict.
src/ui/mod.rs Wires patch window + exports patch temp-dir cleanup.
src/main.rs Adds patch detection, new CompareMode::Patch wiring, and cleanup hooks (shutdown + ctrlc).
src/lib.rs Exposes patch module and adds CompareMode::Patch.
tests/ui_integration/test_patch*.py UI integration tests for patch detection + single/multi patch windows.
tests/fixtures/*.patch Patch fixtures for UI tests.
README.md / TESTING.md Documentation updates for patch viewing/applying and test matrix.
Cargo.toml / Cargo.lock Adds dependencies (ctrlc, tempfile) and bumps versions; criterion black_box deprecation fix support.
benches/benchmarks.rs Switches to std::hint::black_box.
src/ui/merge_state.rs Adds edge-case tests for conflict-block detection helpers.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/ui/patch_window.rs
Comment thread src/patch.rs Outdated
Comment thread src/patch.rs Outdated
Comment thread src/patch.rs Outdated
@joske joske merged commit 809e261 into master Apr 7, 2026
4 checks passed
@joske joske deleted the dev branch April 7, 2026 12:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants