What to do about folders that differ only by case?

I had an interesting situation come up when sharing a folder from my Linux node to a friend’s Windows node. My node was a master for the folder and when the sync completed I noted that his node wanted to sync back a bunch of deletions.

Easy enough, click “override changes.” Those files are sent back. Immediately his node wanted to sync back deletions of different files. I knew he wasn’t at his computer so I started to think about what might be causing this, and once I saw the subfolder names I realized what was happening.

I had two folders whose names differed only by case. Obviously, Linux is fine with this and Windows winds up resolving this by deleting one of the two folders, and weirdness is the result. This is not really unrealistic behavior when you know what could be happening, but it’s definitely unexpected to users not familiar with these kinds of issues, and Syncthing doesn’t currently detect this situation.

Maybe Windows nodes, upon encountering a folder index that contains files or folders whose names differ only by case can throw up a big error on the Syncthing UI and just pause/suspend synchronization of that folder, since there is an extremely high probability that no matter what it chooses to do to resolve it locally, it’s going to be destructive to what’s on the other node when it syncs its resolution back.

Yeah, that’s a really sucky thing to have happen to you. It should be detected somehow.

Then again, it’s easy to see that having both foo.jpg and Foo.jpg in the same folder is broken on Windows - it can’t happen there, natively. However, what about foo/foo.jpg vs bar/Foo.jpg (that’s obviously fine) and in your case foo/bar.jpg vs Foo/quux.jpg? The latter two can coexist fine, and the index will end up looking like that if you have the first file, then rename the folder from foo to Foo and add quux.jpg into it… In fact, due to that bug you’ll even get both foo/bar.jpg and Foo/bar.jpg which is even less awesome…

The rename thing is somewhat easier to handle though, we just need to change how we detect deleted/renamed files…

Sorry, unstructured post, just thinking out loud here.

Right, so what we would expect is that we have either foo/bar.jpg and foo/quux.jpg OR we have Foo/bar.jpg and Foo/quux.jpg on Windows, then that gets synced back. Perhaps that was what was happening and I was misreading, but it looked like Windows decided to just delete either foo or Foo and lose the files in that subdirectory, retaining only one. Each time I clicked “override changes” it would want to delete the files in the other subdirectory. (It kept ping-ponging between wanting to delete foo and Foo each time I clicked.)

This scenario could probably bear some testing to see what the actual behavior is and what would happen when the Linux side isn’t a master. The possibilities I see are:

  1. One folder gets deleted. (This is what it looks like the Windows node wanted to do.)
  2. The folders’ contents get merged into one folder.
  3. The Windows node detects this and stops syncing, with a notice on the UI.

3 is preferable, of course. But if that’s not possible then I would say that 2 is the best option out of 1 and 2 – shuffling some files around is better than outright deleting them, IMO.

(Side note, I resolved this by manually applying 2 – merging the contents. Windows actually really didn’t like this for some reason, no matter how many times I tried to override changes. I had to move all of the contents of both folders into a new third folder, delete the other two, “override changes,” then once everything settled rename that third folder back where I wanted it. Then the Windows node was happy and fell into sync.)

So, what happened in your case is likely this:

  • You sync foo/file and Foo/Otherfile from Linux to Windows. These end up merged into the same directory there, lets say foo/file and foo/Otherfile.
  • The Windows box scans and finds foo/Otherfile which is new! (Or so it thinks, since it only knew about Foo/Otherfile from before.) It announces this update.
  • The master device gets this update but discards it.
  • You hit override, meaning “delete that file that I don’t have” (foo/Otherfile).
  • The Windows box deletes foo/Otherfile, as instructed.
  • The Windows box scans and notices Foo/Otherfile is missing - it’s been deleted! It announces this update.
  • The master device gets this update but discards it.
  • You hit override, meaning “create that missing file” and Windows creates Foo/Otherfile again.
  • Goto step two above.