feat(diff): enable line-level patch selection and actions

Introduces granular control over diff operations by enabling users to select individual lines within a hunk. This refactors the core logic across multiple components, allowing for precise staging, unstaging, or discarding of specific changes rather than operating on entire hunks. The UI now features dedicated controls and visual feedback for line-level selection.

- Refactored patch parsing to track selected line IDs and calculate range information.
- Updated the diff view CSS and component structure to display interactive line selection bars.
- Extended action dialogs to support confirming operations on selected lines.
This commit is contained in:
Christoph Brandau
2026-07-26 22:10:33 +02:00
parent 38b7f1a536
commit 24201c1302
5 changed files with 350 additions and 70 deletions
+30
View File
@@ -6713,6 +6713,36 @@ mod tests {
"one\nTWO\nthree\nfour\n"
);
let staged_patch = get_file_patch(
repo.path.to_string_lossy().to_string(),
"old.txt".to_string(),
true,
)
.expect("staged patch should load");
let status = apply_file_patch(
repo.path.to_string_lossy().to_string(),
"old.txt".to_string(),
staged_patch,
"unstage".to_string(),
)
.expect("selected staged lines should unstage");
assert_eq!(status.files[0].staged, None);
assert_eq!(status.files[0].unstaged, Some(FileStatusKind::Modified));
assert_eq!(
git_output_test(&repo.path, ["show", ":old.txt"]),
"one\ntwo\nthree"
);
let selected_patch = "diff --git a/old.txt b/old.txt\n--- a/old.txt\n+++ b/old.txt\n@@ -1,3 +1,3 @@\n one\n-two\n+TWO\n three\n";
apply_file_patch(
repo.path.to_string_lossy().to_string(),
"old.txt".to_string(),
selected_patch.to_string(),
"stage".to_string(),
)
.expect("selected line should stage again");
let unstaged_patch = get_file_patch(
repo.path.to_string_lossy().to_string(),
"old.txt".to_string(),