Branko Čibej wrote:
> On the topic of storing patches, I'd like to propose an alternative
> implementation.
>
> Instead of saving a set of patches, save two sets of (untranslated
> pristine) files:
>
> * All currently modified files
> * Their pristine, unmodified versions (these are of course already in
> the pristine store and would only need an extra reference in the WC
> DB so that 'svn cleanup' doesn't delete them).
> The idea is that 'unshelve' could, instead of applying patches to the
> current working copy, invoke our built-in diff3 algorithm with whole
> (untranslated!) files. This is likely to produce much better results and
> saner conflict info than applying patches, which have limited context
> information.
Thanks for the thoughts.
Three-way merging should indeed produce better results than patching
when applying the results to a base other than the original base. We
know that patching is sufficient for many use cases, but we also know
there are cases that where a proper merge would be superior, and they
might turn out to be common in certain usage patterns. I would certainly
be happier if we could do that.
I can also imagine that other benefits might arise from integrating this
storage more tightly into the WC like this, although I am not sure
exactly what.
== What would we need to implement this suggestion? ==
For each shelved change we would need
* these two sets of files;
* the (~path-to-hash) index to those files;
* some (similar or other) storage for property changes;
* per-node metadata (revnums, copy/move info, ...?)
* patch metadata (at least a log message);
and to keep track of multiple shelved changes:
* an index from shelf-name to the above group of data.
Then we would need APIs to:
* store the result of a WC diff in that format;
* perform a merge, taking input from that storage, into the WC.
And it would be desirable to have a way to:
* generate a diff from that storage, to output for review or as a patch.
I presume a WC format bump would be necessary, making it incompatible
with the current WC format. (Can you see any way around that?)
== Advantages of using patch files ==
I see some advantages of using patch files for storage.
* WC format bump not needed -- compatible with current versions;
* user can more easily import and export the shelved patches, e.g.
transfer one to another user;
* forces us to make 'svn diff' and 'svn patch' feature-complete (and
this I think is highly significant even though it's not within the
stated purpose of shelving).
== Infinite Context ==
It comes to my mind that an alternative way to achieve storage of the
complete pristine versions, and so enable 3-way merge instead of patch,
is to write a patch file with 'infinite' context.
The algorithm commonly used by 'patch' tools including our built-in
version do not process context in that way and I expect they would
perform badly given such input, although I haven't tried. That would
negate one of the side benefits of using standard patch format for
storage, but perhaps that's OK. We would need to teach 'svn patch',
given an 'infinite context' patch, to use the standard 3-way merge
algorithm.
(That brings to my mind the question of intermediate-sized context: is
there an algorithmic continuum between the basic 'patch' algorithm which
is designed for small context and the basic '3-way merge' algorithm
which is designed for complete context? It would be interesting to see
whether anyone else has thought of this in the outside world.)
Anyway, that might be another option to try without needing so much
WC-layer implementation.
- Julian
Received on 2017-08-28 21:05:41 CEST