Developing a WordPress application with multiple developers? In this situation you definitely need to setup a proper version control system to prevent the project to end in chaos. A version control tool makes it possible to experiment: you can try out some new code and if it does not work simply roll back to the previous (stable) version. If it does work, roll it out.
Next, use different environments to work in. A dev environment for the developers to work in, a staging environment where the client (or the manager) can check the newest features when ready for a release and finally, a production environment where the latest stable release lives.
But how does all this fit together? Hang on and in this 2 part blogpost I’ll talk you through it. In this post, I’ll describe the workflow for an application or website build with WordPress, but the same workflow can be used for other CMS or frameworks.
Git and WordPress: setting things up
It can be a little overwhelming in the beginning. Sometimes you just want to go back to the good old days of cowboy coding where you worked on the production site using FTP. But wait a minute: you are here to learn something new and this will definitely improve your coding standards!
So let’s start up a local WordPress site using MAMP (assuming you are on a Mac) or WAMP (for windows). Create a database using phpMyAdmin, download the latest WordPress version and change the wp-config.php with the database credentials and run the famous 5 minutes install.
Starting with Git
Now it is time to setup the Git repository. A repository can be thought of as a large depot in which you can put down some containers. More on those in a minute.
You initialize Git with the following command. Yes, you have to do this using the command line. There are off course graphical user interfaces out there but in my opinion you have to learn things the hard way and once you master them, let go and do it the easy way. So, go ahead and type the following command (assuming you cd’d to the directory where you installed WordPress).
Messages in Git are very verbose and self explanatory. After running Git init you get the following message.
Initialized empty Git repository in <WordPress directory>
The repository (your depot) is empty. But wait one minute before filling it. Maybe there are files you don’t want to include in version control. For example, because they contain credentials or files that should be different in the various environments. These files can be written in the so-called .gitignore file (one per line). You can make this file by hand but luckily there are tons of .gitignore examples out there. For the major CMS systems they are in an online repository on GitHub. The standard .gitignore file for WordPress looks like this.
Just download this file and put it in the root directory. Now we create a Readme file which is just a little text file in which we describe what this project is about. Then it is time to put the files in this directory under version control. Because of the .gitignore Git knows which files to add and which to… yes… ignore!
Your first initial commit
Now it is time for your first initial commit. There will be plenty of initial commits in future projects, but there can be only one first initial commit! Committing in Git is a two-step process. First you select the files that should be committed using the git add command. The selected files will be staged and they are ready for the commit. With the git commit command you actually commit the staged files. The -m ‘your message here’ argument is used to give your commit a message. Use a descriptive message to know what files you added or changed since the last commit. Note that the -m ‘your message’ argument is required. A default text editor (vi) will automatically open if you forget it to let you add the message.
git add . git commit -m 'Initial commit of the project.'
Congratulations! You made it to your first commit. To come back to our depot: one container has been put in the depot automatically with this commit and it is called master.
Branches in Git
After our first commit it is time to setup our Git workflow. This will heavily depend on branches. Coming back to the example: you can view a branch as another container in the depot (you may give it a name of your liking). Upon creation of the branch, all the code in the master branch (or the branch the new one is created from) is copied to the new container. When you work on the code in this branch it will not affect the code in the other containers. That is the beauty of branches. Git keeps a reference to each commit so you can go roll back to whatever version you had in the past. This brings up another important point: commit regularly (I generally do it a few times per hour).
So we were talking about the workflow. I will introduce the Git workflow of Vincent Driessen. He uses the following terminology and starts with at least the develop and release branches. These branches follow the code environments this post started with. Hence, we will keep the code in the release branch synced with the staging environment, the code of the develop branch synced with your local environment and the code in the master branch is running on the production server. So go ahead and create these branches:
git checkout -b develop master git checkout -b release master
At this point in time, it doesn’t matter in which branch you look, the code is equal in all branches. You typically start developing in the develop branch and once you have created some templates for your WordPress theme or did some other stuff involving the files of the WordPress install, the develop branch contains code that the other branches don’t.
But what exactly happens when you switch branches with the command
git checkout release
In fact Git will change the files in your working directory to contain the code of the release branch. Try it out yourself: make some changes when in the develop branch and do some commits. Then change branches and see how the files have changed. Changing back to the develop branch and there they are: your neatly crafted changes!
There are to more important (and often used) commands you’ll need to learn:
git status git branch
De status command will return something like this:
On branch develop Your branch is up-to-date with 'origin/develop'.
Quite self explanatory right? You are in the develop branch and this branch is synced with the remote branch. If you do not entirely understand the last line, don’t worry, remote branches will be treated in part 2.
The branch command will return something like:
* develop master release
This means you have three branches and develop is the active one.
Merging your branches
When your code in the development branche is more or less stable it is time to merge it into the release branch. This is done by entering the release branch (git checkout) and merge. These operations quite often work automatically. You get a message that the release branch will be fastforwarded and all is fine. Congratulations again!
git checkout release git merge develop
But sometimes (more often when working with two or more developers in the same branch and it is time to merge each others changes) you will get a merge conflict. Some lines of code in the same file are different on your version compared to the version of your co-developer. Then it is time to solve this conflict by hand. Open the file in a text editor and find the lines that cause the conflict. Discuss the issue with your co-developer and choose the right way the code should be. When done, just commit this one file and the conflict is solved and the merge turned out to be successful.
This blogpost is already quite lengthy so the rest of it will be available in Using Git in team development (part 2). Here we will discuss pushing and pulling code from a remote repository (required to work together on a project) and talk more about deployment of the code to the staging and production environments.