Commit dbe79bd
committed
paths: make
The `line_shift` value is used when combining diff hunks from two or
more stacks together, and has an important invariant: at any point
where a diff hunk from another stack could be inserted, the cumulative
`line_shift` value must be the net lines (lines added less lines
removed) of all the diff hunks prior to that point.
This is so that the combiner knows how to shift the diff hunks. For
example, suppose the combiner needs to combine two stacks; the second
stack has a diff that adds a line at line 100. Suppose the combined
effect of all diff hunks in the first stack prior to line 100 is a net
reduction of 42 lines: the total `line_shift` value of all those diff
hunks must thus be -42, so that the combiner knows that the change that
the second stack has must be added at line 58 instead of line 100.
Point A: Note that this invariant only needs to apply at any point
where a diff hunk from another stack could be inserted. If, in a
stack, there are two hunks adjacent to each other, no diff hunk may be
inserted between them, so as long as their total `line_shift` value is
correct, they may have any `line_shift` value they want. (In fact, it is
sometimes not possible to determine what each `line_shift` value should
be.)
This invariant is not met by the current algorithm, so I switched the
calculation for something that does. The main principles are:
- If applying a hunk causes other hunks to completely disappear, the
incoming hunk must bear responsibility for the `line_shift` values of
the hunks that disappear by adding their values to itself.
- If a hunk splits into two (only possible when applying a hunk in the
middle of an existing hunk), the two resulting hunks must split the
original `line_shift` value between them. Due to Point A above, the
exact proportion does not matter (the two resulting hunks sandwich
the hunk that split them, and all three are adjacent to each other),
so I have chosen to distribute the `line_shift` value based on their
sizes.
- If applying a hunk causes another hunk to be reduced in size, but
not completely disappear, the exact distribution of `line_shift`
values in between these two hunks does not really matter, since they
are adjacent (and thus Point A applies). But I have chosen to take
some `line_shift` from the reduced-size hunk to give to the incoming
hunk, analogous to how a completely disappearing hunk cedes all its
`line_shift` to the incoming hunk, to make the `line_shift` values
more reasonable (well, reasonable to me, at least).
There is some code duplication due to how the diff hunks of an
individual stack are combined. I thought of rewriting the combining
algorithm before writing this commit (to reduce or eliminate the
code duplication needed), but there were some inconsistencies in how
zero-line hunks were handled, so I thought it best to correct the
`line_shift` issue before making further changes.line_shift calculation correct1 parent 7608fa2 commit dbe79bd
File tree
4 files changed
+353
-164
lines changed- crates/but-hunk-dependency
- src/ranges
- tests
- tests/hunk_dependency
4 files changed
+353
-164
lines changed
0 commit comments