This is straightforward git read-tree
work. Make a bare git repo on the webserver, anywhere. Keep a manifest aka index for what's in your deployment directory and handle your updates with a pre-receive like so:
#!/bin/sh
while read old new ref; do [[ $ref = refs/heads/deploy ]] && {
export GIT_INDEX_FILE=$GIT_DIR/deployment-manifest
export GIT_WORK_TREE=/path/public-html
git read-tree -um `git write-tree` $new:directory2 || exit 1
}; done
Then push what you want deployed to the webserver's deploy branch, e.g. git push server master:deploy
git read-tree
loads the index, which is a manifest, a list of what was put where in the worktree, from any tree in the repository's object database. It reads the tree you name into the index. It's the workhorse for checkout and reset and merge, for instance with the -um
option it's what updates the worktree for a checkout or fastforward merge. You can keep any indexes you want, for any content you want. The convenience wrappers keep one index, for one set of content, and always update a reference named HEAD
to match whatever they're working with, but that's purely conventional.
Note that if some file being deployed this way has been changed in the deployment tree, the git read-tree
here and the push will fail because git won't overwrite content you haven't told it about.