Conversation
When `git diff-files --unified=0` emits hunks for a file, each hunk's `+Y` value reflects the cumulative line shift of every preceding unstaged hunk in that file. Staging only a subset of those hunks with `git apply --cached --unidiff-zero` uses `+Y` to position each change, so carrying over the full-diff offset causes the patch to land at the wrong line whenever unselected hunks contributed to the shift. Two fixes are applied: For `git_stage_patch`, a `rewrite_hunk_y` helper is introduced in `hunk.rs` that recomputes each selected hunk's `+Y` from the net line change of the preceding *selected* hunks only. A `cumulative_offset` accumulates `(additions - removals)` as hunks are assembled, and each header is rewritten before the patch is handed to `git apply`. For `git_stage_patch_lines`, the `HunkHeader` struct previously preserved `new_start` from the original full-diff header and then applied it as an offset to the sub-hunk. That offset was wrong for the same reason. The field is removed and `build_sub_hunk` now derives `new_start` directly from the sub-hunk's own content: for replacements and pure removals it equals `old_start`; for pure insertions it equals `old_start + 1`. Regression tests are added for both tools covering the scenario where an addition hunk is staged while an unrelated removal hunk higher in the file remains unstaged. Signed-off-by: Jean Mertz <git@jeanmertz.com>
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.
When
git diff-files --unified=0emits hunks for a file, each hunk's+Yvalue reflects the cumulative line shift of every preceding unstaged hunk in that file. Staging only a subset of those hunks withgit apply --cached --unidiff-zerouses+Yto position each change, so carrying over the full-diff offset causes the patch to land at the wrong line whenever unselected hunks contributed to the shift.Two fixes are applied:
For
git_stage_patch, arewrite_hunk_yhelper is introduced inhunk.rsthat recomputes each selected hunk's+Yfrom the net line change of the preceding selected hunks only. Acumulative_offsetaccumulates(additions - removals)as hunks are assembled, and each header is rewritten before the patch is handed togit apply.For
git_stage_patch_lines, theHunkHeaderstruct previously preservednew_startfrom the original full-diff header and then applied it as an offset to the sub-hunk. That offset was wrong for the same reason. The field is removed andbuild_sub_hunknow derivesnew_startdirectly from the sub-hunk's own content: for replacements and pure removals it equalsold_start; for pure insertions it equalsold_start + 1.Regression tests are added for both tools covering the scenario where an addition hunk is staged while an unrelated removal hunk higher in the file remains unstaged.