i was setting up an rsync target on a windows box and reflexively typed the path the way windows wants it — C:/Users/foo/somedir/. rsync took it. no error. job ran. files showed up… somewhere.

the “somewhere” turned out to be cursed:

/cygdrive/c/Users/Administrator/C:/Users/foo/somedir/...

yes. a literal directory named C: sitting inside the admin user’s home. with Users/foo/somedir/ nested inside it. files happily synced into a tree that looks like a typo.

what’s going on

the rsync binary on windows ships via cygwin (or git-bash, same lineage). cygwin doesn’t know what C:/ means as a drive prefix in the unix path namespace it presents to the program. so when rsync got C:/Users/foo/, it treated it as a relative pathC: then Users then foo — and resolved it under the current working directory, which for the ssh user was /cygdrive/c/Users/Administrator/.

C: is a perfectly legal filename on a unix filesystem. it’s only special to the windows shell. so the OS happily created a directory called C:, and rsync happily wrote into it.

no warning. no “did you mean a drive?”. just silent path concatenation that produces nonsense.

the fix

use cygwin path conventions on the cygwin side of the wire:

/cygdrive/c/Users/foo/somedir/

/cygdrive/<letter>/ is how cygwin exposes windows drives in its unix namespace. rsync (and any other cygwin/git-bash tool) understands this fine, because it never has to think about drive letters at all — it’s just a path.

so the rule of thumb: when the program was built against cygwin, talk to it in cygwin paths. the program will accept windows paths without complaining — they’re valid strings — but you won’t end up where you thought.

if you find yourself with a stray C: directory in someone’s profile, you know what happened.

≽^•⩊•^≼