packwiz-installer icon indicating copy to clipboard operation
packwiz-installer copied to clipboard

Three-way merge configuration files

Open 3TUSK opened this issue 2 years ago • 3 comments

While revisiting issues discovered in our mod jam/convention event last year, I noticed this specific use-case:

  1. A mod has configuration file, let's say its initial values are
    {
       "foo": false, 
       "bar": false, 
       "baz": true
    }
    
  2. 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
    }
    
  3. Some users wish to disable foo and go ahead to edit config on their own, i.e. their configs are now
    {
       "foo": false, 
       "bar": true, 
       "baz": true
    }
    
  4. For various reasons, at a later time, the mod author wishes to ship another default config, in which baz is 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.

3TUSK avatar Jul 01 '23 22:07 3TUSK

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, .properties timestamps)

comp500 avatar Jul 02 '23 01:07 comp500

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.

3TUSK avatar Jul 02 '23 01:07 3TUSK