In short, directory local variables are variables that are set for every file that is opened that belongs to the target directory, in this case, our project directory.

With the Firestarter package, we assign the firestarter variable to a function and the package will execute it each time a file in our project is saved. The only question left is "What function should we use to sync our project with our server?"

We'll call rsync from within Emacs, we want it to obey the .gitignore rules as well, and maybe also send the .git directory so that we have all the commits and everything in the server (these options should all be customizable)

Create a .dir-locals.el file in the root of the project directory, then insert the following things here (I'm synchronizing my current folder with a test folder in my server that has user nope and IP 40.756.140.43 (yes, 756 is not in the IP range, this is on purpose so bots don't go pinging this IP), therefore the whole path looks like [email protected]:test/

( ( nil . ( ( firestarter . ( let* ( ( rsync--obey-gitignore t ) ( rsync--exclude-git nil ) ( args ` ( "-aP" "'ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'" "--delete" , ( when ( and rsync--obey-gitignore ( file-exists-p ".gitignore" ) ) "--filter=':- .gitignore'" ) , ( when rsync--exclude-git "--exclude='.git/'" ) , ( projectile-project-root ) [email protected] :test/" ) ) ) ( apply 'start-process "rsync" nil "rsync" args ) ) ) ) ) )

Update Thank you @wasamasa for the suggestion on not using async-shell-command

I hope this is useful to someone that has had issues with TRAMP before as well. Rsync will manage to only copy stuff that is different. But I don't know how good it is with binary data, but I know git is not good with it. Please comment if this is an issue.