You can’t tell what the users intent was by simply diffing the old and new contents. The right approach is to capture the users intent directly from the software that they use to edit the value, and then preserve that intent through the synchronisation system.
This problem is also easy to reproduce with edits on lists / strings which contain repeated elements.
Changing 999999999 to 1000000001, do you increment by two or re-type the whole number?
It is difficult to make users think in (invisible) state changes.
Small commits are all about trying to preserve an explanation of change intent - but they're not ideal because you can end up doing a lot of incidental code just to keep them actually working if they get merged to master.
Whereas looking at the sum of a big commit, you just get a mess which doesn't tell you much of anything unless it's limited solely to inserting discrete blocks.
Whereas ideally what you really want to know is "there's 37 actions replacing the use of variable Y with a call to function X being passed Y" and the types are the same in all cases.
I'm trying to understand this part. Would you give an example of semantic diff losing intent signal?