EteSync 1.0 (released 4+ years ago), was very much inspired by Git, and it indeed suffered from this problem. Each client had to replay the full log, and it only really worked well for lightweight data.
With version 2.0 of the protocol (released end of 2020), we changed it so that items (blobs of data) can be marked as changed and thus you only need to fetch the currently active items, rather than the full operations log. This works much better.
It would mean the server needs to keep an eternal log of operations, and each client must replay the log to perform a full sync.
This works with lightweight data like contacts and calendars.