Skip to content

Instantly share code, notes, and snippets.

@khalsah
Created January 3, 2012 22:59
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save khalsah/1557423 to your computer and use it in GitHub Desktop.
Save khalsah/1557423 to your computer and use it in GitHub Desktop.
Experimental git sync & deploy hooks
#!/bin/sh
LOCAL_BRANCH="master"
LIVE_BRANCH="live"
REMOTE_NAME="deploy"
if [ "$(git symbolic-ref -q HEAD)" != "refs/heads/${LOCAL_BRANCH}" ]; then
echo "Not on ${LOCAL_BRANCH}, not deploying"
exit 1
else
echo "Syncing and deploying"
git push ${REMOTE_NAME} ${LOCAL_BRANCH}:master
git pull ${REMOTE_NAME} ${LIVE_BRANCH}
git push ${REMOTE_NAME} ${LOCAL_BRANCH}:master
fi
#!/bin/sh
cd "$(dirname $0)/.."
export GIT_DIR="."
export GIT_WORK_TREE=".."
if [ "$(git symbolic-ref -q HEAD)" != "refs/heads/live" ]; then
echo "Not on live, not deploying"
exit 1
elif ! ./hooks/sync; then
echo "Sync failed"
exit 1
elif ! git merge --ff-only "refs/heads/master"; then
echo "New changes on live, not deploying"
exit 1
else
echo "Changes deployed"
exit 0
fi
#!/bin/sh
cd "$(dirname $0)/.."
export GIT_DIR="."
export GIT_WORK_TREE=".."
if [ "$(git symbolic-ref -q HEAD)" != "refs/heads/live" ]; then
echo "Not on live, not syncing changes"
exit 1
elif ! git diff-index --exit-code --quiet --cached HEAD --; then
echo "Changes exist in index, not syncing"
exit 1
elif [ -z "$(git status --porcelain)" ]; then
echo "No changes to commit"
exit 0
else
git add --all $GIT_WORK_TREE
git commit -m "$(date "+SYNC %F %T")"
exit 0
fi
@jcanfield
Copy link

@khalsah I'm digging it so far. I think that the merging of the branch to master for deployment is great and the usage rev-parse is great and I have rarely seen --porcelain used but all in good practice.

@jcanfield
Copy link

@khalsah Working great on two Wordpress projects with the daily cron job.

* 0 * * * /home/username/domain.com/.git/hooks/sync

@jcanfield
Copy link

Interesting error message. (Obvious locations left out-- but you get the gist of it. Heh-- stupid puns).

username:websitename-com_staging projectdir$ git add --all
username:websitename-com_staging projectdir$ git commit -m "Adjustment to Wordpress Login logo."
[master 13a3096] Adjustment to Wordpress Login logo.
 4 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 wp-admin/images/logo-login.jpg
 rewrite wp-admin/images/logo-login.png (94%)
 rewrite wp-content/themes/website-com/shared/websitename-logo.png (97%)
username:websitename-com_staging projectdir$ ./deploy.sh
Syncing and deploying
To ssh://username@server.com/home/username/staging.website.com/.git
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to 'ssh://username@server.com/home/username/staging.website.com/.git'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes (e.g. 'git pull') before pushing again.  See the
'Note about fast-forwards' section of 'git push --help' for details.
From ssh://server.com/home/username/staging.website.com/
 * branch            live       -> FETCH_HEAD
warning: Cannot merge binary files: wp-content/themes/website-com/shared/websitename-logo.psd (HEAD vs. 1b1a18fae966975944d4997bece945771131bba3)

Auto-merging wp-content/themes/website-com/shared/websitename-logo.psd
CONFLICT (content): Merge conflict in wp-content/themes/website-com/shared/websitename-logo.psd
Automatic merge failed; fix conflicts and then commit the result.
To ssh://username@server.com/home/username/staging.website.com/.git
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to 'ssh://username@server.com/home/username/staging.website.com/.git'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes (e.g. 'git pull') before pushing again.  See the
'Note about fast-forwards' section of 'git push --help' for details.

@jcanfield
Copy link

I just did the git commit -m and ./deploy.sh again and all was well.

@khalsah
Copy link
Author

khalsah commented Jan 6, 2012

Sounds like the file somehow diverged between your local copy and what was on the server. When you ran deploy it tried to pull in the sync from the server which failed with a conflict. When you did a commit you created a merge that picked which version to use allowing the commit to be deployed. Can't tell you why the files diverged though.

@jcanfield
Copy link

jcanfield commented Jan 6, 2012 via email

@jcanfield
Copy link

I encountered that issue again this morning. I think it had something to do with the CRONJOB running /hooks/sync at midnight and when I went to deploy I got the same message spit at me. Odd. This is still more effecient than my previous deployment methods for WP sites.

@jcanfield
Copy link

Forgot to ask you today. When I am setting up these 'web' or 'deploy' repositories on the client's server (to deploy too), I do a basic git init since we discussed not using git --bare init on these repositories. I've had to add git config receive.denycurrentbranch=ignore to each repository. That makes sense, right? If I don't add that, the push does not work at all because of the fast-forward. (Correct, or am I thinking about that the wrong way?). Only reason I ask, is because that's how I am setting up a new repo right now.

# From Remote machine
git init
git config receive.denycurrentbranch=ignore
git add --all
git commit -m "Initial Commit"
git remote add origin git@bitbucket.org:username/websitename.git
git push origin master
git branch -l deploy
touch .git/hooks/post-receive && chmod +x .git/hooks/post-receive #Add post-receive content
touch .git/hooks/sync && chmod +x .git/hooks/sync #Add sync content

# From Local Machine
git init
git remote add origin git@bitbucket.org:username/websitename.git
git remote add deploy ssh://user@server.com/home/user/websitename.com/.git/
git add --all
git commit -m "Initial Commit."
touch ./deploy.sh && chmod +x ./deploy.sh # Add Deploy content
./deploy.sh

That all makes sense, right?

@jcanfield
Copy link

Added [ -f /usr/local/bin/growlnotify ] && growlnotify -s -m "Project has been Deployed" || echo "Project has been deployed" for Mac OSX Growl Notification. Quick check to see if Growl is Installed (in the proper place) then notifies that the project has been synchronized with a fall-back using echo. Nice for those large commits that take a little while. I'll jump over to another window or screen and work on something-- then am notified that the Sync was complete.

It's all about the simple things in life.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment