On the local machine:
Initialize the directory to be synced as a Git repository
git init
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
Where
Side-note: It's advisable to go password-less for SSH logins
On the remote machine:
Initialize an empty directory on the server
mkdir /path/to/dir/on/server
cd /path/to/dir/on/server
git init
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:
vim .git/hooks/post-receive
Put the following in it:
#!/bin/sh
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"
git push
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 server
remote:
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.