On the local machine:
Initialize the directory to be synced as a Git repository
Commit any existing code
git add -A
git commit -am "initial commit"
Set its remote to the server
git remote set-url origin user@server:/path/to/dir/on/server
Side-note: It's advisable to go password-less for SSH logins
On the remote machine:
Initialize an empty directory on the server
Set its config to ignore updates to checked out branch
git config receive.denyCurrentBranch ignore
This is needed because (quoting the exact error you'll get if you don't do this) "updating the current branch in a non-bare repository is denied, because it will make the index and work tree inconsistent with what you pushed, and will require 'git reset --hard' to match the work tree to HEAD." (we'll actually do just that in the next step).
Set up a
post-receive git hook:
Create a file
post-receive in the
.git/hooks directory, and open it in an editor:
Put the following in it:
git --git-dir=. --work-tree=.. checkout -f
Set its mode to executable:
chmod +x .git/hooks/post-receive
This will checkout your latest changes on the server dir whenever you push any.
One-liner for all of above:
dir=<dir>; mkdir $dir && cd $dir && git init && git config receive.denyCurrentBranch ignore && printf '#!/bin/sh\ngit --git-dir=. --work-tree=.. checkout -f' > .git/hooks/post-receive && chmod +x .git/hooks/post-receive
Now on the local machine you can do this:
git commit -am "Some changes"
and your local dir will be synced to the server dir.
An additional recipe that I use often: On local machine, I keep the
origin remote name for Github/Bitbucket which is the "home" of the project, and a special
server remote name which is where it gets deployed. I also create a git branch (which is also named)
server and configure it to always push to the
git config branch.server.remote server
git config remote.server.push server:master
This way whenever I'm on master branch it pushes to the
origin (Github/Bitbucket etc) and when I'm on the
server branch it pushes to the server.