Three-way merge configuration files
While revisiting issues discovered in our mod jam/convention event last year, I noticed this specific use-case:
- A mod has configuration file, let's say its initial values are
{ "foo": false, "bar": false, "baz": true } - For the jam event only, the mod author wishes to ship a different default config, where all 3 options are enabled:
{ "foo": true, "bar": true, "baz": true } - Some users wish to disable
fooand go ahead to edit config on their own, i.e. their configs are now{ "foo": false, "bar": true, "baz": true } - For various reasons, at a later time, the mod author wishes to ship another default config, in which
bazis now disabled by default:{ "foo": true, "bar": true, "baz": false }
To my knowledge, current packwiz-installer can either keep the config in scenario 3, or use the config from scenario 4, but the mod author expects this instead (syntax highlighting is JavaScript - so we can have // comments):
{
"foo": false, // user-modified value
"bar": true, // This one is kept unchanged
"baz": false // This one is based on latest changes
}
In other words, the mod author wishes to do a 3-way merge for configs from scenario 2, 3 and 4.
My understanding is that, to handle 3-way merging, we actually need to have a copy of config from scenario 2, for we need to generate diff between scenario 2 and 3, and between scenario 2 and 4. This original copy does not seem available, however; user might not keep a copy of the original, and packwiz does not store the original, either.
This feature may also require the modpack to be versioned. I haven't looked into this issue in deep, so I may be wrong on this.
Hmm.. this is interesting. A few things to note:
- I don't plan to support configuration file formats directly, as this adds a significant amount of complexity and might not handle edge cases properly - such a 3-way merge would need to be done based on text (similar to Git diff / various IDEs)
- The format packwiz-installer understands currently does not support any history (i.e. can't retrieve scenario 2) nor does packwiz-installer keep any local history
- Keeping local history is unlikely to be implemented - this would require essentially replicating a version control system or enforcing that one is used, which I don't want to do, particularly with respect to disk usage
- Retrieving history for files stored in the remote pack may be possible in future as I want to implement Git support
- I feel like this behaviour is something that should be configurable - some files (e.g. quests, resources, configs that need to sync with the server) should never be merged unless the user explicitly opts to carry out a 2/3 way merge
- For this I would probably add a per-file/folder flag that specifies which merge strategy should be used by default, as an extension of the current "preserve" functionality
- This also needs to be careful to not annoy the user, particularly with changes that are automatically made by mods (e.g. missing fields, config format updates,
.propertiestimestamps)
such a 3-way merge would need to be done based on text
I would agree.
I feel like this behaviour is something that should be configurable
Right now, for an entry in index.toml, we already have preserve to control whether we want to overwrite files. I am thinking that this could be expanded to allow a new value, say merge, which enables the merge behavior.
For files like quests, resources, we can already leave this false to always overwrite them.