This is how I would do it.
Each developer has his own git repository to develop his code. You as merger hold a third repository, and this repository has separate branches for each developer, for your test system and your production site.
Your developers can push their changes to you, or you can pull their changes from them into branches specifically for them. You hold a branch that you control which contains the merged code in a state for testing. You either use git-cherry-pick, or maybe just git-merge to pull their changes into your testing branch were you test things (and possibly make your own changes - or fire bug reports of to the develops and you re-incorporate their changes). When you are happy you will merge off to a "production" branch. This is normally initially derived from the test branch, but with changes necessary for the live system (I always find there is something, even if its just the database name and password).
I normally use a git hook with some code which checks which branch I am on and then uses rsync over ssh to push the code to my production site.
#!/bin/bash
branch=$(git branch | sed -n s/^\*\ //p)
version=$(git describe --tags)
cd "$git rev-parse --show cdup)"
if [ "$branch" == "production" ]; then
echo "?php echo '$version';?>" > web/version.inc
rsync -axq --delete web/ site:public_html/
fi