Software projects should have three environments: development, staging, and production. These environments should essentially be identical. In practice this isn’t always possible but we should try to get as close as possible. Every developer has a development environment for each of their computers. This means WebDeveloperA could have one development environment on her laptop and a second development environment on her desktop. Each WebDev will code on her respective development environments, keeping both of them in sync with version control.
In the SVN (non-distributed version control) days, it was easy to visualize a software project. Let’s say a group of WebDevs want to make the GreatSite project. They start coding away at their computers. The make a GreatSiteRepo which will hold this GreatSite code. This is the version control repository. As WebDevs write good code, they put their good code into this GreatSiteRepo. The WebDev manager thinks the project is looking good and wants to release the first version of the code. All the WebDevs agree the code is in a good place and stop coding.
The GreatSiteRepo has just one trunk or master at this point, nothing has been branched yet. Since everyone agrees it is time to release the code, and everyone has stopped working, all the WebDevs do a final commit so their development environments are perfectly in sync with the GreatSiteRepo. (In the read world, some people won’t commit, but we’ll talk about that later) The WebDev manager makes a branch of this code, and she calls this branch R01_GreatSite. On the GreatSiteRepo, there now exists two branches, Master and R01_GreatSite.
The Ops Team sets up a staging environment and puts the R01_GreatSite code on it. The QA team comes and looks at the staging server and finds a laundry list of issues. QA reports to the WebDevs the fixes that need to be made. The first thing all the WebDevs do is change their branch from master to R01_GreatSite. Everyone is fixing bugs on R01_GreatSite now. The WebDevs do their work and come back a few days later with all the bugs fixed. Every WebDev makes sure her local development environment is in sync with the repository branch R01_GreatSite.
The Ops Team moves the new R01_GreatSite code to the staging server. QA looks at it and says all is good. The Ops Team move the R01_GreatSite code to the production server and the site goes live. Everyone is happy, there is a QAed site that looks great.
The WebDev Manager gets word about the new feature they need to implement. The WebDev manager knows the latest version of the code is on R01_GreatSite. She copies R01_GreatSite to the master branch. She tells all the WebDevs to change their local development environments to the master branch. All the WebDevs have their local development environments pointing to the master branch.
Back in the SVN days, the master was called a trunk. The software project (the tree) grew up from the ground. R01_GreatSite was a branch that popped out of the side of the trunk. When the WebDevs were working on QA’s fixes, they were coding (growing) the R01_GreatSite branch. When the branch was done and new requirement came in and it was time to continue coding and grow up (not out), the trunk became active again and grew straight up. In the Git days, we have a distributed trunk so it’s called a master and isn’t really a single tree anymore, but the concept is the same.
So now the WebDevs are working on the master branch, they are making release2’s coding changes. They finish all the requirements and sync their local development environments with the master branch, then stop coding for now because they are done. Ops or the WebDev manager cuts a new branch from master (i.e. copy master) to R02_GreatSite. QA is looking at R02_GreatSite and is finding a host of problems, keeping them very busy.
Oh no! Someone finds a serious security hole in the live production site, something must be done right away. One of the star WebDevs is WebDev3000. The WebDev manager tells WebDev3000 to fix the security hole that is on the production server. WebDev3000 puts the R01_GreatSite code branch into her local development environment. She quickly finds the issues and makes the fixes. She saves and syncs her code with the R01_GreatSite branch. The WebDev manager tells QA about what is happening. QA has been working on finding bugs in R02_GreatSite but the QA Manager tells her best QA person, QA3000 to look at the security hole fix. The Ops team makes a staging server with the new R01_GreatSite code. QA3000 says the fix looks great, she signs off on sending it live. The Ops Team goes to the production server and updates the local code (which is the R01_GreatSite from the GreatSiteRepo) to it’s newest version.
The production server is patched and everyone wipes the sweat off their brows. The QA team is finished with the R02_GreatSite bugs findings on the staging server. WebDev3000 changes her local development environment to R02_GreatSite as do all the other WebDevs. The WebDev teams works on all the R02_GreatSite bugs. The WebDev team is done. The Ops Team put the R02_GreatSite code into staging for QA. When QA signs off that R2 is done, the Ops Team changes the production code from the newest R01_GreatSite to R02_GreatSite. The whole team celebrates the second release of their software.
The WebDev manager gets requirements for Release3. The Ops Team or the WebDev Manager copy the R02_GreatSite code to the master branch. All the WebDevs switch their local development environment to use the master branch. And it continues.
The above story is long but is shows the principles of version control branches. With branches you can always fix the live production code (in a branch) and you can also do new development on the main (the trunk of the master) codebase.
For this to work, you want the systems in development, staging, and production to be as similar as possible. Most of the time, WebDevs have different machines and that is okay. It is really important for the staging and production machines to be essentially identical. If WebDav2000 is running WAMP and her code runs just fine, but the production site runs LAMP, it is important for the staging server to also run LAMP so that in the QA cycle any environmental differences come to the surface. In many software houses, the WebDev team isn’t allowed to touch the production server. This is to keep everyone safe from themselves. WebDevs touch development, QA touches staging, and the Ops Team is the only one who touches production. This really helps stop errors from happening because each group focuses on what they do best.
Version control helps reduce stressful situations with the production server. However, in the short term
it creates some work for the WebDevs to operate within the version control system and deal with merges
conflicts. A merge conflict happens when your code (on your local box) and the code in the repository are
conflicting. The version control system isn’t smart enough to know which version of the code is the good
code to keep. The version control system will annoy you with messages about the merge conflict. Everyone
hates merge conflicts. Here is the dirty secret, merge conflicts don’t go away: If you put them off your
merge conflict list grows. As WebDevs, it is your job to fix the merge conflicts. No one likes to do it, but it
must be done.
I have found ways to avoid most merge conflicts. Understanding the scenario at the beginning of this blog
explaining branches on the GreatSite is important: The details matter. I like to start my day getting the most
recent code from the repo. In git this is called pulling. The first thing I do every morning at work is to pull
code from the repository I am working on. I also pull a few times a day and before and after I make big
changes to the code base. While this is likely overkill, it is easy to pull and deal with merge conflict less
The next gotcha is your local development environment. I use at least two computers in a given week for software development. It is really easy to sit at computerA, do some work, walk away, go to computerB, do some work and create merge conflicts. For this reason, every time I leave a computer for any period of time I commit and push my code. This really cuts down on merge conflicts because at the next computer, I will pull the code and since I just commited and pushed beforehand, my code is in sync. (The commit and push is git speak, SVN was simpler because a commit did the same thing as a git commit and push). The geeky details about git is that you are commiting to your local repo’s brains, and when you push you are pushing back up the branch you are working on. That keeps you and branch in sync and you and the other WebDevs in sync.