Apply localization changes from change set versions [BETA]

Respresso's version management is great to preserve older states to allow you to make hotfixes. Although, we use VCS to track changes and merge them once we need them. For this purpose, Respresso was not really helpful, until we introduced change set versions.

Using change set versions, Respresso is now able to compute (not track, like Git) the changes made within a version. These computed changes can be applied to any other version so we introduced version merging for localizations that does just that.

Please note that this feature is in BETA! Some data types may not be properly updated automatically, especially when nested arrays of data - like localization languages - are concurrently edited. You should always check the merge results before applying them.

How to use localization version merging

  1. You need to create a new localization version by copying or patching an existing version. For instructions, visit the version control page. For feature or hotfix versions, we recommend you to use named versions.
  2. Make your changes in the newly created version.
  3. Once you are ready to apply those changes to another version, go to the target version (probably the original one you copied in the 1st step) and select the MERGE option.
    Start localization version merging from target version by pressing the merge button.
    Start merging from target version.
  4. Select your source change set version - the one created in 1st step - and select how you want to compute the changes. (By localization keys or by the underlying resource id.)
    Select change set version and base of difference computation.
    Select source change set version and base of difference computation
  5. Review all the computed changes and select those you want to apply and deselect those you don't. Finally, apply the changes.
    Review computed changes and apply them
    Review computed changes and apply them
  6. Apply the changes.

Merging can be executed multiple times, as changes are always recomputed. This allows you to apply the changes you know you need, and skip those you need to investigate.

When to use it and what not to do with it

Change set versions and merging can be really useful when used properly. But it can quickly turn into a mess if you don't understand how it works.

You must understand that it does NOT work like Git. To get a brief overview how it actually works, see the understand how it works section.

Although, if you follow the following rules, you can achieve a Git like workflow:

  • Do NOT chain change set versions if you want to merge them. In other words, a change set version should always be merged back to the same version it originated from. E.g. if you create a chain of version like a -> b -> c, then merging c to a, it will lack some of the changes made in b as it works like cherry-picking. You can fix it by merging c to b and then merging b to a.
  • Do NOT merge versions that has no common origins. Once again, merging works like cherry-picking, that does not work if the changes should be applied to not existing things. (It will create it instead, but this is not what you are used to in Git.)
  • Do NOT concurrently edit list data types. Currently, merging of list data is not supported, instead the whole list is overridden. E.g. if you add Spanish in one version and French in another then you merge both to their origin version, one will be lost. (Translations will be merged but not listed until the missing language is added manually again.) Localization variable list is similar, as changing only a single variable will imply the override of the whole list.

So, what should you use it for? It's simple: for single features or hotfixes then merge them back to their origin version.

Simple workflow:

  1. Let's assume you have a single version: 1.0.0 that is ready to be released.
  2. Copy 1.0.0 as develop.
  3. At this point, you should also finalize 1.0.0 and release your app, but it's optional.
  4. Create your feature branches by copying develop: feature-1 and feature-2
  5. Once the features are ready, you can merge them back to develop and delete them once you completely merged them.
  6. Once the develop version is ready to be released again, you just copy it as 1.1.0 or whatever version you want to release. You can jump back to the 3rd step for the next iteration.

Hotfix workflow:

  1. Patch or copy the released version you need to fix: 1.0.1 (You can also use a named version when you use copy instead of patch.)
  2. Change what you need to fix your issue.
  3. Finalize your hotfix version and release your app.
  4. Merge the hotfix version to the develop version. You can optionally merge it to all your feature versions.

Understand how it works

When you merge versions, there are always 3 versions in play:

  • S - The original state of the change set version. Conflict detection works properly only if this is the current or a previous state of T.
  • S' - The current state of the change set version.
  • T - The state of the target version.

To produce the computed changes, Respresso does something like the following formula:
Δ = (T + (S' - S)) - T

Basically, it computes the changes in the change set version, applies them to the target and calculates the changes between the current and resulting state of the target. In fact, it is far more complicated under the hood, but this is enough for you to understand the concept.

The main takeaway is that only those resources (~localization keys) are merged, that were changed in the change set version. This will not merge the resources that were not created/updated/deleted in the source change set. E.g. if you have two independent versions, copy one of them and start the merge to the other one, there will be no change detected.

You can think of change set versions like commits and merging as cherry-picking. Keep in mind, that this is a simplification to help you understand it, Respresso is not intended to work like Git.

Conflict detection

Respresso implements conflict detection to help you decide which changes are risky to apply and which ones are safe. To do so, it assumes that S is a copy of T or at least a previous version of it.

Concurrent changes are computed similarly to this formula:
Δ' = T - S

Conflicts are computed from the intersection of the changes:
Δ ∩ Δ'

If a resource (~localization key) have concurrent changes, Respresso detects whether the changed values are conflicting or not. If independent values are changed, then Respresso will auto resolve the conflict, but if the same value is changed