I ended up finding two solutions to this.
- Use
unison. This is a command line utility for mirroring a local directory on a remote server. It is similar to rsync but a little more sophisticated and ergonomic when dealing with many files. Their github repo is fairly active, even though the webpage says development has largely stopped, and the main drawback is that unison is a run-once utility rather than something that runs in the background. You could use something like cron to periodically run unison, but I'm not sure if that would result long sync lags (1 minute+) and how manual conflict resolution would work.
- Use
lsyncd. This program is designed for exactly my use case: It continuously monitors a given directory, and immediately syncs any changes within as little as 1 second. However the last commit was 2 years ago so I'm not sure how viable it is long term.
I ended up using lsyncd because it can run continuously. For lsyncd, you must provide a "profile", which is a Lua file that tells lsyncd which directory to sync where and how (eg. whether to ignore some files). I used the following profile:
settings {
nodaemon = true,
statusInterval = 1
}
sync {
default.rsync,
source = "/home/donentolon/github/my-awesome-codebase",
target = "remote-machine:/home/remote-user/my-awesome-codebase",
delay = 1,
exclude = { '/.git', '/.idea' }
}
This tells lsyncd to:
- Connect to the remote machine with SSH (my SSH
config is set up so that ssh remote-machine will connect to it)
- Use rsync for actual syncing
- Check for file changes at least every second (the
delay)
- Do not sync top level git and PyCharm files
When I turn on my computer, I open a terminal and run lsyncd my-lsyncd-profile.lua and it begins running and printing live updates about what it's doing. I leave the terminal open and do my development, and kill lsyncd at the end of the day when I'm done.
I don't use git to track changes on the remote directory, although I could. If I want to commit my changes to git, I run git commit and other commands on my local computer, which lsyncd syncs from. Because the local directory is actually local, and not a remote mounted locally, PyCharm features (like indexing) all work normally.
There is a background mode, but I didn't use it because I like seeing the lsyncd status. It can be configured to autostart using the standard Linux methods, but I prefer the manual method.
lsyncd's page helpfully lists some alternatives with similar use cases, so if you don't like this solution, you could take a look at those.