# isn't variance adjusted patching horribly dangerous?

From: Tom Lord <lord_at_emf.net>
Date: 2003-04-09 00:15:21 CEST

There are times when variance adjusted patching would certainly do
"the right thing" --- and if you know you have such a situation, well,
heck it's a fine tool to add to the toolbox.

But in general, it seems quite dangerous precisely because it
accomplishes its goal of eliminating conflicts that would otherwise
arise from contextual changes.

Perhaps I've misunderstood how it works, so let me illustrate what I'm
thinking of:

Consider, for example, a common ancestor that starts with:

T:8 == B:1
----------

last = x;
val = 2 * x;
foo (val);

On the trunk:

T:19 (unchanged from T:8)
----

last = x;
val = 2 * x;
foo (val);

T:20 (second line changed from T:19)
----

last = x;
val = 2 * (counter += x);
foo (val);

And on the branch:

B:15 (first line changed from B:1)
----

last = x, counter += x;
val = 2 * x;
foo (val);

In this case, both the trunk and branch programmers added a needed
increment of `counter', but they did it in different ways, on nearby
but different lines.

The programmer wants to apply T:19-T:20 to B:15.

Between T:19 and T:20, only one line changed here (the assignment to
val). The context diff will be something like:

*** T:19
--- T:20
*****
last = x;
! val = 2 * x;
foo (val);
-----
last = x;
! val = 2 * (counter += x);
foo (val);

That will be adjusted to account for the changes between T:8 and T:19
(there are none), and then for the changes from B:1 to B:15. After
that adjustment (for an "in-range editted line"), the patch will look
like this:

*** T:19
--- T:20
*****
last = x, counter += x;
! val = 2 * x;
foo (val);
-----
last = x, counter += x;
! val = 2 * (counter += x);
foo (val);

which will apply without conflict to B:15, yielding:

B:16
----

last = x, counter += x;
val = 2 * (counter += x);
foo (val);

which (because of the duplicated assignments to counter) is likely to
be the wrong result.

Now, to be fair -- even regular textual patching, without the variance
algorithm, can introduce surprising bugs. Patching is inherently
dangerous that way.

But one of the ways we traditionally reduce that risk is by using
context diffs -- and variance adjusted patching appears to be a
mechanism precisely designed to undo the benefits of that safety
measure.

The example above illustrates a case where ordinary patching would do
the right thing, generate a conflict and help a programmer to notice
the bug, but variance adjusted patching will silently hide the bug.

A less aggressive form of variance adjustment would seem to me to be
safer: and that would be just to adjust the line offsets of hunks (not
their contents) in response to out-range additions and deletions.
That would defeat the window-size limitation of the patching tool

Referring to

that would be cases 1 and 2 of the two 7-case adjustment algorithms
(The text starting with "To adjust P, we first walk over the diff
T:8-T:19,").

Yet even _that_ kind of adjustment presents new dangers, and I don't
think I'd want it to be the default.

-t

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org