I am planning to implement automatic conflict resolution for text files in some of my synced folders. The system is based on using a three-way merge with git merge-file to merge the chosen file with the conflicting file, as described here. The article describes how syncthing versions can be used as the base file of git merge-file to provide git with more context about what changes were made in both the chosen and conflicting file. However, that only works if a version exists on the machine running the merge.
My thought is that if every device that is sharing a folder has file versioning turned on, a common ancestor that was the base for changes that were made by both the chosen file and conflicting file of a syncthing conflict is necessarily stored on one of the devices.
An exception would be if the conflicting file was newly created on both devices, so no version exists since the base would be an empty file.
If I use external file versioning on each device sharing a folder I want to apply this automatic conflict resolution to, such that I store the versions in a folder that is itself synced with syncthing, I will have all versions from every device available to each device, not only the versions that were created by that device.
Therefore, everytime a syncthing conflict arises and a git merge-file <current> <base> <conflict> is executed, there should exist a common ancestor of <current> and <conflict> in the shared versions folder to use as the <base> (assuming the versions folder is synced up to date).
I’d like to respectfully ask if there are any flaws with this to see if I’m missing something obvious before I put it in practice.
is there a way to ensure that the right version is used, e.g. a consistent correlation between the syncthing conflict file timestamp and the version file that was created for the respective conflicting sync?
I don’t think this will work like you’d expect. Let’s say you have two nodes (A & B), files are in sync, your versioning gambit has worked somehow so far so both have some sort of common ancestor in the versioning directory somehow.
You edit the file on A. It syncs to B. Repeat that a few times. Both will have the latest file, B will have the previous version in the versioning directory, A will have a much older version because it hasn’t received any incoming updates. In general, I don’t think you’ll have the same version in the versioning directory on two devices, because they are created under different circumstances.
(I really suggest just using git with a git remote instead. And whatever you do, I hope you’re not syncing an actual git repository, because that will mess it up at some point.)
If I use external file versioning on each device sharing a folder I want to apply this automatic conflict resolution to, such that I store the versions in a folder that is itself synced with syncthing
It sounds like you missed this part of the original post. I plan on storing the versions in a directory that is synced with syncthing, so each device can access versions created by other devices. What are your thoughts on this?
I really suggest just using git with a git remote instead
I understand this sentiment, but for my usecase, it’s valuable to not need to manually commit in order to sync.
And whatever you do, I hope you’re not syncing an actual git repository, because that will mess it up at some point.
I just want to clarify that git merge-file works on files outside of a git repository, so it acts as a general purpose utility to do a three-way merge on three files.
Thanks for the response, but it seems like there may have been a misunderstanding of my original post. Would you mind giving it another read? I appreciate your input.
I can comment on this part, as I used to sync versions like that (albeit just for backup purposes). I think there are two caveats with it:
You need to set up the versioning on a single device only. If you set it up on multiple devices pointing at the same path, you will end up in a never-ending versioning loop, where each side keeps versioning items inside the versions folder.
I eventually stopped syncing versions, because they ended up taking too much space and eating too much bandwidth, delaying synchronisation of other files in the process. I assume you could mitigate this part with external versioning, e.g. by skipping larger files, etc., which isn’t available in the built-in versioning schemes.
Oh no, in my case it was just that I wanted to have versions available everywhere (including the device where the changes took place). I normally use the built-in staggered versioning method, which creates a lot of versions, which is why I had to abandon the idea for bandwidth and storage reasons.
If you create your own solution with external versioning, then I assume you can make it work to your liking. One thing that I like about the built-in thing is its ability to clean old versions up automatically. If you switch to external versioning, you will need to recreate the whole cleanup mechanism from scratch.