I was copying over some music to my phone (via jmtpfs and rsync), and I noticed that some of the files failed with “Input/output error”:
After a while it dawned on me what all these files had in common was that there’s a colon in the file names. And presumably the MicroSD card in the phone uses a VFAT file system, and those file systems don’t like colons in the file names at all.
So I thought: Surely there’s a simple switch I can give to rsync to translate file name characters. I mean, this problem can’t be that obscure: We’ve been copying media files to devices that use VFAT file systems for decades now.
But after reading the man page and Googling for hours: rsync doesn’t support this. I mean, I can somewhat understand why. Whatever you’re doing is going to be pretty hackish. You could get file name collisions or inconsistent rsyncs, perhaps. On the other hand, these devices are the end point for these files: We don’t really care much about the names…
It turns out that Matt McCutchen wrote a patch in 2007 that was never accepted. It adds a simple –tr :/- syntax that does exactly what I need.
The patch no longer applies cleanly, but it’s surprising how little work was needed to shoehorn it into the current rsync source code. They’ve obviously retained the basic structure of the files and the repo, for which I am thankful.
I put the resulting git fork up on Microsoft Github.
And there’s a few other gotchas when rsyncing to VFAT: It doesn’t support all the Linux file system flags or renaming in the way rsync does by default, so for reference, here’s the complete command line I ended up with that will (sort of) reliably copy over new files to my phone:
~/src/rsync/rsync -atvL \ --tr ':?"/-!' --inplace \ --ignore-existing \ /music/picks/ /mnt/sony/SD\ card/Android/music/
Your mileage will vary.