Unrevert has these issues because it is implemented as a patch bundle.
This was probably the easiest way to do it but I think we can do better.
Suppose we store it as a normal patch (but still separate from the
normal patch inventories). I like to picture it as hanging off the
working state:
origin --r--> recorded --p--> pending --w--> working --u--> unrevert
where r are our recorded patches, p is the pending patch and u is the
unrevert patch. In an ideal world we could adapt u whenever we change w,
but w is not under our control, so we can't do that. So we have to
remember -- along with u itself -- as much of w as is needed to apply u.
This is what is called a "contexted patch" in the camp paper and I
believe is the same (modulo named prim patches which we don't have yet)
as what we have as Darcs.Patch.V2.Non. This extra context must be
adapted whenever we change r or p. Writing c:u for the contexted
unrevert, we arrive at
origin --r--> recorded --p--> pending --w--> working
\
--c:u--> unrevert
and the unrevert operation is then a merge of c:u with w, resulting in
some c':u' (we throw away the other branch) which we can apply on top of
w. Of course the merged c':u' can have conflicts, and I think unrevert
should support the usual conflict options (allow, no-allow, mark) with
--no-allow-conflicts as a sensible default.
How does this solve the issue at hand? Well, we never store conflicts in
the context of u (remember it is a list of prim patches, like the
pending patch p). When we calculate a new context (for u, after
modifying r or p, or for a reduced u', after merging with w) we only
need to consider the effects of any patch involved, which we add or
subtract and then simplify (re-group and coalesce) like we do with the
pending patch. At least that is what I think at the moment...
A nice side-effect is that we get rid the "this will make unrevert
impossible, proceed?" warning/prompt.
|