Using git to manage a web site

From Wiki

Jump to: navigation, search

git is a very powerful version control system. There is plenty of documentation for it, but mostly this seems to focus on git's fancy features the complicated workflows these allow. What if you're just one person who wants to use git to manage your web site? Here's how:

On your workstation or your test server, create your very own git repository. This assumes your documents are at /var/www/htdocs/www.example.com, adjust as needed:

$ mkdir ~/www.example.com.git && cd ~/www.example.com.git 

Set the work tree to be wherever your source resides on the test server:

$ git --work-tree=/var/www/htdocs/www.example.com --git-dir=/home/someuser/www.example.com.git init

(can't use ~/www.example.com... for some reason it chokes on the ~)

Makes the logs more readable and stops git commit from complaining so much:

$ git config --global user.name "stocksy"
$ git config --global user.email "stocksy@stocksy.co.uk"

There will be certain things that you don't want on the live server, tell git:

$ git config --global core.excludesfile ~/.gitignore
$ cat <<EOF > ~/.gitignore
.DS_Store?
ehthumbs.db
Icon?
Thumbs.db
._*
.Spotlight-V100
.Trashes
# or whatever else you don't want to put on the live web server
my-super-secret-dir/*
EOF

Add the files to git's staging area and get them committed:

$ git add .
$ git commit -m "Initial commit of www.example.com DocumentRoot"

Create an ssh keypair and drop your public key on the remote server. Tell ssh to use this private key for connections to the live host:

$ cat <<EOF > ~/.ssh/config
Host www.example.com
  HostName=www.example.com
  IdentityFile=~/.ssh/www.example.com_dsa
EOF

Now, ssh to the live server and create a git repo to which your changes will be pushed:

$ mkdir ~/www.example.com.git && cd ~/www.example.com.git
$ git init --bare
$ vi config

[core]
        repositoryformatversion = 0
        filemode = true
        bare = true
# Set this to be the live document root:
        worktree = /var/www/htdocs/www.example.com/

I want git to automatically check out into the document root any changes that are pushed to it:

$ cat <<EOF > hooks/post-receive
#!/bin/sh
sudo git --work-tree="/var/www/htdocs/www.example.com/" checkout -f
EOF
$ chmod +x hooks/post-receive

This will need passwordless sudo for the user who will perform the checkout:

$ visudo

freddy   ALL=(ALL) NOPASSWD: /usr/bin/git

Now that's done, add the live server as a remote repository on the test server:

$ git remote add live ssh://freddy@www.example.com/home/freddy/www.example.com.git
$ git push live master
Counting objects: 479, done.
Compressing objects: 100% (477/477), done.
Writing objects: 100% (479/479), 6.14 MiB | 111 KiB/s, done.
Total 479 (delta 248), reused 0 (delta 0)
To ssh://karen@www.example.com/home/freddy/www.example.com.git
 * [new branch]      master -> master

Now whenever I want to deploy changes from the test server, it's simply:

$ git add .
$ git commit -m "Swaffled the pig and felched the camel"
$ git push live

Useful commands

See also: http://cheat.errtheblog.com/s/git

What's going on?:

$ git status
$ git log

Show exactly what was done in each commit giving patch files:

$ git log -p 

Undo the last commit:

$ git revert HEAD

...or the second-to-last commit:

$ git revert HEAD^

...or the fourth to last commit (you get the idea!):

$ git revert HEAD~3

And if you pushed the change:

$ git commit -m "Oh cock!"
$ git push live

You've cocked something up horribly in the document root and want to revert to the last commit:

$ git reset --hard HEAD

I want to remove something from the git repository, but I don't want to remove it from the working tree (document root):

$ git rm --cached somefile.php

Undo changes on an uncommitted file

$ git checkout <path>