[remote] Intialize Remote Repo:
# ssh into remote
# initialze empty repo
git init
[local] Setup Local:
# where "user@ip:/path/to/repo.git" is your specific remote user, ip, and path
git remote add production user@ip:/path/to/repo.git
# note: The path to remote should lead to where your .git
# directory is - likely the root of your site
[local] Initial Push:
# Initial push to remote, settup upstream
# from the local production branch
git push -u
[remote] Configure Remote:
# checkout the newly pushed production repo
git checkout production
# enable repo to receive pushing from your localhost
git config receive.denyCurrentBranch updateInstead
# Why is this necessary?
# Because git push is designed for bare repos (ie: repos created for
# sharing, not managing changes). The recommended way in this case is to
# pull into the repo. But one of the goals of this workflow is to prevent
# having to SSH into the server... to keep things as simple and frictionless
# as possible.
# setup post-receive hook to reset remote working tree to newly pushed head
echo '#!/bin/bash' >> .git/hooks/post-receive
echo 'git --work-tree=/path/to/repo/root/ reset --hard' >> .git/hooks/post-receive
# make the post-receive hook executable
chmod a+x .git/hooks/post-receive
Debugging:
# View git config:
cat .git/config
# Test post-receive hook (from production root):
.git/hooks/post-receive
# View post-receive hook (from production root):
cat .git/hooks/post-receive
Dev-flow:
# Work...
# Make good use of Git's core goodness
git checkout development # or whatever branch
git add .
git commit -m "adds good commit message"
# Merge new code
git checkout production
git merge --no-ff development # or whatever branch
# Push
git push production
# or - leave our the "production" bit:
git push
# ...assuming the production branch is
# checked out and that its only remote
# is set to the production remote.
# eg (relevant bits, not comporehensive):
# > cat .git/config
# [remote "production"]
# url = user@ip:/path/to/repo.git
# [branch "production"]
# remote = production
Switched to using
updateInstead
forreceive.denyCurrentBranch
as a better approach to allow pushing into non-bare repo thanignore
. This option available as of git 2.3.0 (Feb 2015). Hat-tip to this SO answer where I learned of this.