I was working on a project, a side project for fun with a friend, and she expressed a slight worry. We weren’t using any versioning on our theme or mu-plugins code. Or anything else for that matter. There were three of us. We thought about using GitHub until I pointed out I had git on my server, where I was hosting it all.
In many ways I don’t use git like a ‘normal’ person, or so I’ve been told. I don’t have public git repo of everything because some of it is just private. I don’t even have a public GUI interface for people to file issues on my private code. Public code? Sure, and I use GitHub for it. Personal stuff is not up there, and I don’t care to make it.
What I do instead is, since I do have Git installed on this server, is allow each user account to make a git repository folder off their home folder. Everyone has ~/repositories/
and in there they can store their code!
Here are the ones for mine:
~/repositories/ipstenu-code.git/ ~/repositories/ipstenu-mu-plugins.git/ ~/repositories/mothra.git/ ~/repositories/scripts.git/ ~/repositories/slides.git/
The two that start ‘ipstenu’ are for the website ipstenu.org and all it’s children. Mothra is some server scripts I want to keep backed up, scripts are user scripts, and slides are my slides.
But how do I get there, and how do I keep everything synced up? First is the basic setup for git:
cd ~/repositories/ mkdir projectname.git cd projectname.git git --bare init
From here it’s a simple git clone, too:
git clone user@example.com:/home/user/repositories/projectname.git
But… I have that project named ipstenu-mu-plugins. When I’ve checked in code, do I manually copy the files over? Of course not.
When you go into that git folder where I ran the init, you see this:
[~/repositories/ipstenu-mu-plugins.git]# ls ./ ../ branches/ config description HEAD hooks/ index info/ objects/ refs/
If you go into the hooks folder, you get a list of files:
ipstenu@ipstenu.org [~/repositories/ipstenu-mu-plugins.git/hooks]# ls ./ commit-msg.sample pre-applypatch.sample pre-push.sample ../ post-update pre-commit.sample pre-rebase.sample applypatch-msg.sample post-update.sample prepare-commit-msg.sample update.sample
You’ll notice I only have one file that isn’t a .sample: post-update
That’s my secret sauce.
#!/bin/sh export GIT_WORK_TREE=~/public_html/wp-content/mu-plugins git checkout -f master
This just uses git checkout, forces the master branch, and dumps the files where I want them. I set it up for each repo when I’m ready to start deploying, and then my dev process is this.
- Pull master and all remote branches to make sure I’m up to date
- Make a new branch to develop
- Push the new branch to origin when I’m sure it’s right
- Merge the new branch into master
- Push master
And in that moment, the push will copy my files live.
Since I don’t ever do dev work in master, this is safe for me. It’s five steps, but I actually have a script to run that first one every single day, so that’s almost step zero. When I work with other people, I always make a backup local branch of master as ‘last known good’ just so I can roll back fast if I’ve been phenomenally stupid. This is usually a date like “GOOD_20141117”, which I know is different from my actual release labels, that are always “REL_1.2.3” style. If it’s a weird thing, like when I was folding Ninja Forms in my site, it was “NINJAFORMS_1.0” because I wanted to be clear what that dev branch was for.
By the way, if you need to set up a shared repository, you should read Kovshenin’s “How To Create a Remote Shared Git Repository”. I don’t, since everyone logs in using SSH keys to the account (so on my shared project, everyone uses ssh projectaccount@projectdomain.com) since they actually need that access anyway.