WinMerge Basic Architecture
There are three basic layers in WinMerge:
- diffengine (LibXDiff for file compare)
- middle layer processing differences (merging etc)
- GUI visualizing file compare
In WinMerge 1.x and 2.x the GNU diffutils was used as file compare engine. This caused quite a lot of problems since we had to attach to internals of diffutils code. And do some modifications to diffutils internals itself. It mean that updating diffutils code from (now ancient) version to new version proved to be impossible to do without risking breaking lots of things.
WinMerge 3 will use LibXDiff as compare engine for files. LibXDiff is mature and well maintained library (for example Git uses it). LibXDiff isn't nearly as flexible as diffutils (as it is library not program) so we need to add ourselves all the filtering etc above it.
Observations about LibXDiff so far:
- easy to build in Windows and Linux - creating QMake file was easy too
- required to use libxdiff managed buffers for compared data
- pretty simple to use for two file compare
- there are no options for the compare other than context lines - no whitespace ignore etc
The last item is something we need to think about. Diffutils offers us some nice options for compare for "free". With LibXDiff we need to implement these ourselves. It certainly is not trivial task to add even these basic options/filters. But weighting against integration problems with diffutils it may still be a win. Hard to really say.
There is another view for this also: if we implement our own "filtering" above simple diffs it is a lot more flexible and powerful than we can have with diffutils. We can pretty easily add things like ignoring whitespaces in begin/end of lines. We kind of move all these "diff options" to post-compare filtering.
This is the meat of the WinMerge. Diffengine tells which lines are different between two files. Middle layer maps that to actual differences in the files and tells the GUI what to show to the user. And when user does something for the files (edits, merges differences) middle layer updates files, merges differences, asks new results from diffengine.
Important part of the middle layer is filtering. Diff engine tells us which lines are different. After that we must apply our custom filtering to filter out differences user doesn't want to see. In WinMerge 2.x we used regular expression to match lines that we wanted to remove from diffs. Even though there were lots of problems with the implementation the idea is solid.
GUI gets the data from middle layer and visualizes it for the user. GUI doesn't do any file or difference processing it just tells middle layer what user wants to do.
Qt Plugin Architecture
I think we should take Qt's plugin architecture heavily into use. I don't mean "plugins" as in WinMerge 2.x. But I mean plugins as in Qt Creator. We can have many features implemented as plugins. Meaning pretty lightweight core and then possibility to expand it with the plugins. For example things like filtering fits naturally implemented as plugins.
Using Qt Creator plugins?
We need to study if we could use some of the work done by Qt Creator, in editor, version control integration etc. That would mean we can use heavily tested (in practice) code instead of writing our own versions.