So You Want to Build Software For a Living (Your First Programming Class)

In this post, I’m going to give you, the potential Computer Scientist, the information you’ll need to get through that first computer programming class.  This is not an infomercial and I’m not selling anything.  My goal is to try and help students who are not learning the material because their class size is astronomical or their instructor is disorganized, busy or complacent.

Let’s assume you know nothing about how a computer works.  You watched too many Hollywood movies and your idea of a computer is that it is a synthetic brain that can think on its own.  Now, let me correct your assumptions.  A computer is nothing more than a machine.  Literally, a computer is as smart as a toaster.  Yup, you heard that right.  It’s not any smarter than a coffee maker or a refrigerator.  It just does what it was designed to do, or in the case of a computer it does what you tell it to do.  So when you write a program, the program is nothing but a baby language that you must tediously type in step by step to instruct the computer to do “exactly” what you want it to do.  What do I mean by “exactly?”  I mean, you have to break your steps into tiny little steps, like what to print on the screen.  What to do when someone clicks on a button.  What to do when the program ends. 

So the first thing you’ll need to understand is that a program is executed from top to bottom.  Just like reading a book.  Most languages have a defined starting point and you’ll learn where that is.  From that starting point, the program will execute the line of code at the starting point, then it’ll move down to the next line and execute that line.  Then it will move to the next line.  Until it runs out of lines, or you put in a line of code that tells the computer to stop or end.

Compilers and Editors

Every language has a compiler and there are editors that you can use to create the text that represents your program.  For Java, the most common compiler/editor is the Eclipse IDE.  What does “IDE” stand for?  It just stands for Integrated Development Environment.  That means that you can type in your program like you’re typing a Microsoft Word document and then there is a button that runs your code and you can even use some built-in tools to test your program (more on this later).  I’ll be using Eclipse for my examples (you can download it free by clicking here).
 

Hello World

Every language out there has a “hello world” program.  It’s a demonstration of the simplest program you can write that does something.  So for Java, here’s a sample “hello world” program:

public class hello_world 
{
    public static void main(String[] args

    {
        System.out.println(“Hello World!“);
    }
}

That’s it.  That is the whole program.  All it does is print the sentence “Hello World!” in the output box.   So how does this program work?  Well, in Java, the program starts with a class.  In this example the class is called “hello_world” and the curly brackets (“{” and “}”) are used to group everything that is owned or contained in the class.  This part of the program can be ignored until you get to the lesson on what “objects” and “classes” are.  For now, just type it in like it’s shown.

The next line is the “main” (it’s shown as “public static void main(String[] args)).  This is the beginning of the first “method” or function call.  Basically your class can contain one or more of these methods which are used to group your program into “mini-programs” so you can break your problem into smaller chunks.  Again, you can just copy and paste this as-is for any of your intro programs.  In this case, you must keep the name “main”, otherwise Java doesn’t know where to start.

The next part of this program is the print line (shown as “System.out.println“).  The println or print line command will print one line of code.  It will print the text that is inside the double-quotes.  

What About Those Brackets?

OK, let’s look at the curly brackets.  In order to group things together, you can use curly brackets (“{” and “}”).  In the hello world program, there is only one line of code so it doesn’t make a whole lot of sense to use the brackets.  For this sample program, the brackets are used to contain the code that is owned by the class and method.  The method called “main” is owned by the class called “hello_world” and the code that is executed (using the println command) is owned by the method called “main”.  Let’s look at another example program and brackets should become a little more clear:

public class hello_world 
{
   
public static void main(String[] args
    {
        int myNumber = 5;
       
        if (myNumber == 5)
        {
            System.out.println(“Hello World!“);
        }
        else
        {
            System.out.println(“Goodby Cruel World!“);
            System.out.println(“I’ll miss you!“);
        }
    }
}

This is a bigger program, and I’ve introduced some new “syntax”.  First, the “int” is a keyword for an integer variable.  Variables are a box where you can store something.  In this case, we’re creating a box named “myNumber” as an integer.  So the box can only hold an integer (which is a whole number, no decimal).  You can put one number in the box and if you read from the box you’ll get your number back.  The number will stay in the box until you change it.  In the above program, the box contains a 5.  Why?  Because I assigned the variable “myNumber” to 5 on the first executable line of code (int myNumber = 5;).  You’ll also notice the use of a semi-colon on many lines of code.  That just tells the computer that it’s the end of the line of code.  This semi-colon is part of the syntax of the Java language and you learn when to use a semi-colon and when not to use a semi-colon as you write programs and practice your syntax.  For now, all variable declarations end with a semi-colon.

The next line is blank.  That blank line of white-space does nothing.  Don’t expect the computer to do anything with this line.  It’ll see that there is no command on that line and go “Nothing to see here, movin‘ on…”.  The purpose of white space is for readability.  You use spacing to make your program easy to read.  Indenting lines of code is used for readability too.  Because Java doesn’t care about white space, you can write a program that crams everything together like this:

public class hello_world{public static void main(String[] args){int myNumber=5;if(myNumber==5){System.out.println(“Hello World!“);}else{System.out.println(“Goodby Cruel World!“);System.out.println(“I’ll miss you!“);}}}

Do you know what the above program will do?  Same as the previous program.  The computer will execute it just the same.  The problem is that nobody can read that!

OK, back to the “readable” program.  After the blank line there is an “if” statement.  This is known as a conditional statement.  When the computer comes to this line it will evaluate what is inside the parenthesis and compute a true or false result.  In this example “myNumber == 5” is tested to see if the box “myNumber” is equal to 5.  It is, so true is returned to the “if” statement.  Why use double “=” signs?  Here’s the problem: The equal sign is used to signify “assignment”.  As the first line of code showed, a “5” is “assigned” to the box or variable named “myNumber”.  So the difference between assign and equal is that the equal comparison operator uses a double-equal sign.

Again, you’ll get used to the “syntax” of Java as you write more and more programs.  Java is not the only language that uses the double-equal.  C, C++ and C# also use this syntax, and the reason is that they all came from the same language, which is C.  

Back to the “if” statement.  The “if” statement will evaluate to a boolean or true/false result.  If the result is true, then the next line is executed.  If false, then the “else” statement is executed.  In cases where you don’t have code in your “else” statement, you can leave off the entire else part.  For now, just understand that the “If” statement has two possible paths to follow.  Since the result is true, we see that there is a curly bracket in the next line.  This bracket matches the closing curly bracket and every line of code in-between is grouped together and executed one line at a time.  There is only one line of code between the brackets.  That is the line of code that prints “Hello world!”, then the program will skip over the “else” part (the else will only execute if the result was false).  After the else part of the program, there is no more code to execute, so the program stops.

Now, let’s change the varialble to 6:

public class hello_world 
{
   
public static void main(String[] args
    {
        int myNumber = 6;
       
        if (myNumber == 5)
        {
            System.out.println(“Hello World!“);
        }
        else
        {
            System.out.println(“Goodby Cruel World!“);
            System.out.println(“I’ll miss you!“);
        }
    }
}

In this example, the “myNumber” box or variable is set to 6.  The “if” statement will evaluate to a false because 6 is not equal to 5.  Therefore the Hello World!” line is skipped over and the else block of code is executed.  The first line of code between the brackets prints “Goodby Cruel World!” and then the next line of code will print “I’ll miss you!”.  Then the program ends because there is nothing more to execute.

Some Programming Etiquette

I’ve already described the usefulness of the curly brackets.  The next thing you need to pay attention to is the cleanliness of your code.  Indentation is very important for readability.  Here’s an example of poor indentation:

public class hello_world 
{
   
public static void main(String[] args
    {
        int myNumber = 6;
       
        if (myNumber == 5)
        {
            System.out.println(“Hello World!“);
             }
             else
             {
        System.out.println(“Goodby Cruel World!“);
        System.out.println(“I’ll miss you!“);
        }
    }
}

The problem with the appearance is that it doesn’t match the functionality of the program itself.  The “else” should always line up with the “if” statement.  Each open curly bracket (“{“) should line up vertically with the close bracket (“}”).  This is for your own good.  Follow this practice, even when you are just typing in a line of test code.  Keep it clean at all times.  Otherwise, you’ll pull your hair out trying to figure out what is wrong with your program when the problem is buried inside an improperly nested section of code.

Some practices break the open and close curly brackets on different lines, like this:

public class hello_world {
   
public static void main(String[] args) {
        int myNumber = 6;
       
        if (myNumber == 5) {
            System.out.println(“Hello World!“);

        }
        else {
            System.out.println(“Goodby Cruel World!“);
            System.out.println(“I’ll miss you!“);

        }
    }
}

Don’t do it!  It’s difficult to visualize where your blocks of code start and where they end.  It’s much easier to visually line up the brackets so you can see which brackets match.

Another bad practice, which is legal syntax is to not use brackets for one line of code under an “if” or “else” statement.  Here’s an example:

public class hello_world 
{
   
public static void main(String[] args
    {
        int myNumber = 6;
       
        if (myNumber == 5)
            System.out.println(“Hello World!“);
        else
        {
            System.out.println(“Goodby Cruel World!“);
            System.out.println(“I’ll miss you!“);
        }
    }
}

This program works exactly as above.  Why?  Because the “If” statement always executes one statement after it, if the statement evaluates to true.  The same with the else part, except we have two statements in the else part, so brackets need to be used.  This syntax is legal and the computer doesn’t care.  However, if you are working on a program and you later go back and add a line under the if” statement, you might not realize that there are no brackets and indent your program correclty, only to find out that it doesn’t work.  Like this:

public class hello_world 
{
   
public static void main(String[] args
    {
        int myNumber = 5;
       
        if (myNumber == 5)
            System.out.println(“Hello World!“);

            System.out.println(“Line 2!“); 
        else
        {
            System.out.println(“Goodby Cruel World!“);
            System.out.println(“I’ll miss you!“);
        }
    }
}

 
What will this program do?  It will complain about the “else” statement:

 

Yikes!

Any time you use an “if” statement, put in the curly brackets.  This practice should become habit.  Also, any time you type an open bracket, type in the close bracket, then move the cursor to the inside and type in your code.  Nothing is worse than forgetting a bracket and then trying to figure out where the missing bracket is.

About Those Semi-Colons

Remember the semi-colon that you used to end the “myNumber” variable assignment line?  Notice how there is no semi-colon at the end of the “if” statement.  If you put a semi-colon at the end of the “if” statement, the computer will educate you on the nuance of Java syntax.  In this example:

public class hello_world 
{
   
public static void main(String[] args
    {
        int myNumber = 6;
       
        if (myNumber == 5);
        {
            System.out.println(“Hello World!“);
        }
        else
        {
            System.out.println(“Goodby Cruel World!“);
            System.out.println(“I’ll miss you!“);
        }
    }
}

You’ll get the same error as above “Syntax error on token “else”, delete this token”.  Not a helpful error message, since the real error is that tiny little semi-colon at the end of the if statement.  The problem is even worse if you have code that does not have an “else” part.  Like this:

public class hello_world 
{
   
public static void main(String[] args
    {
        int myNumber = 6;
       
        if (myNumber == 5);
        {
            System.out.println(“Hello World!“);
        }
    }
}

Guess what that code does!  It prints “Hello World!”.  If you look closely, you’ll see that “myNumber” is assigned the number 6 and is not equal to 5.  A false should skip over the next block of code which prints the “Hello World!”.  If you change the “myNumber” variable to 5, this program will still print “Hello World!”.  In fact, the “if” statement only excecutes the next line which is the semi-colon, then it moves on to the block of code that prints “Hello World!”.  

Troubleshooting this is difficult because you don’t get any error at all.  The program just doesn’t do what you expected.  This is what we call a “bug”, or a run-time error.  Because the error only occurs when the program is run and doesn’t occur at compile time like the earlier errors.

Debugging

Five seconds after you write your first program, you’ll need to learn how to debug it, or fix it to make it perform the way you expected it to perform.  Debugging is the process of removing bugs.  Compile time bugs are immediate and they must be fixed before the program will run.  You can usually gain some information from the error message that is presented, but sometimes that can be obscure.  Sometimes the computer doesn’t recognize that there is a bug until several lines of code down the line.  Which is what happened earlier with the bug being reported at the “else” statement, even though both bugs I introduced were a the “if” statement. 

Here’s a simple example bug:

public class hello_world 
{
   
public static void main(String[] args
    {
        int myNumber = “a“;
    }
}

You’ll see a red circle to the left of the “myNumber” declaration:

 

Hold your mouse over the red circle or over the red underlined section of code.  You’ll get the following error:
 
 

What this error means is that you are trying to save a string into an int or integer value.  A string contains letters, but an int can only contain an integer or whole number.  In order to fix this problem, you’ll need to change your variable type to a “String” or change the value you are trying to assign to an integer.

Break Points

You put a break point in your program.  Basically, you can right-click on the vertical bar on the left side of the editor, next to the line of code you want to stop at, then toggle-breakpoint.  This will put a little blue circle on the bar.  Then you run your code in debug mode by clicking on the “debug” button:

 

A bunch of other window panes will show and you can see your variables (in this case there are two variables, your “myNumber” variable and the “args” variable which you can ignore).  The program will stop on your line of code that has the break-point and wait for you to tell it to continue.





 

You can see the green line where my program is waiting.  The variables window looks like this:

 

Notice how the “myNumber” variable already contains a “5″.  Now you can step to the next line of code using the “Step Over” command.  You can also use the “Step Into” for this sample, but it has another use that does not apply to this simple program.  The Step Over” button looks like this:

 

Notice how the program prints “Hello World!” right after you step over the print command.  You can use the step commands to observe exactly how your program is executing your code.  This can be helpful when you can‘t figure out why your program is going into your “if” statement or not.

How to Get Started on Your Class Assignment

OK, your teacher has given you an assignment, you read through the instructions and nothing comes to mind!  What do you do?  The first thing you need to do is break the problem down.  Inside the description of your problem will be individual pieces that you can probably write in code.  Create an empty program.  Put in one or two lines of code and run it.  See if it does what you expect it to do.  Maybe the assignment expects you to read in a number.  Look through your school notes and find out how to read from the input.  You can also check with Google.  I can assure you that someone out there has read something into their program using the Java language.

Type in enough code to read something in.  Put a break-point in your program and debug to the input statement.  Type something into the keyboard.  Step to the next line.  Check to see if your variable contains the input you typed in.  Now go to the next part of your assignment.

Even though your are taking your first class and it should be an exercise in syntax, you can’t create a program with just syntax and no algorithm.  So you’ll have to learn a simple algorithm.  Some instructors will give you the algorithm, some will give the name of the algorithm to use.  You can lookup the algorithm on-line and see how it is performed.  Let’s pretend you are given the task of writing a program that prints the maximum of two integers.  Your input requires you to input two integer numbers and then you must print whichever number is the largest.

First of all, how would you do it if you didn’t have a computer?  I’m sure you can do it in your head, but this is a simple example.  Get out a piece of paper and write down two boxes.  Name them input1 and input2.  Now, put a number in input1 and a different number in input2.  What computer statement would you use to determine which number is larger?  The “if” statement comes to mind.  At this point, you should be able to create a program that reads in two variables and then compares the two with an “if” statement using a greater than symbol:

if (input1 > input2)
{
           
}
else
{
            

}

You can run this program and it will not print anything, but you’re almost there.  You just need to add the print statements.  Inside the if brackets, you‘ll need to print the number from input1.  Why?  Because you’ll get a true if input1 is larger than input2.  The else statement should print the value of input2.  

Yes, this is a very trivial example, and it doesn’t handle the case where the values are equal.  The purpose of showing this is that you need to break your problem down into tiny little baby steps.  If you can’t get your brain wrapped around the problem, break it down.  If you can’t get the computer to perform your algorithm or you don’t know how to code it, do it on paper by hand.  Once you figure out how to do the algorithm by hand, you can write a program to perform the same steps.

Where to Get More Help

First of all, you should start writing your program as soon as your assignment is available.  It will take you a long time to write a program at first.  You don’t know the syntax or any algorithms so you need to stumble around and figure stuff out.  After you’ve written a program or two, you might be thinking that you need more practice with writing programs.  This is correct.  You should go to places like hackerrank and do some practice problems:

Go here: https://www.hackerrank.com/domains 

Select Java, and start at the top.  Solve some problems.  The hackerrank system will give you immediate feedback on your solution.  You can submit your problem as many times as it takes to get it accepted.  This is where you will get practice.  Like learning to play a musical instrument.  Practice!

You can also go to Coursera and do a Java course.  I would recommend doing a course before you start school or do it on a weekend if you have the available time.  You’ll get duplicate information, but there will be items that don’t overlap due to differences in teaching methods.  There are other on-line courses that you can take.  Some cost money, some are free.

Buy a book or check out a book from the library.  Make sure the book is an entry level book and doesn’t dive into something too complicated.  Type in some of the book code samples and step through them.  

The Internet is full of information on programming.  When I graduated from college the internet was just getting started.  Google wasn’t invented yet.  My resources while I was taking classes involved using FTP to known code sites or using AOL or Compuserve.  Now I find a lot of stuff on Stack Overflow (though their answers are sometimes beyond the expected answer for an entry level class, buyer beware) and Google.

Good luck with your programming.

 

So You Want to Build Software For a Living (Introduction)

I’ve been building software since about 1978 and I’ve kept up with the technology.  I discovered that I wanted to write software as a career soon after I purchased my own computer in 1984 (ah yes, the Macintosh).  Many of my friends and family have asked me how hard it is to get into the software development industry and I usually steer them towards testing their interest.  Here’s my expert advice: 

“Take an entry level programming class.  If you make it through one class and you think you would enjoy doing something like that as a 9 to 5 job, then go for it.”   

The flip-side of this coin, and the reason I recommend taking one class, is that people who can’t hack the first class have no hope of making it their career.  The bottom line is that you have to have the drive and the interest to be successful.  For me, programming is a hobby.  If I don’t get enough programming done at work in a week, I’ll start writing a program or designing a project at home as a hobby.  I have to get it out of my system.  I’m what you would call “driven.”  I’m the type of person that companies look for when they need a programmer.  In fact, when I interview prospective programmers, I usually ask them what they do for a hobby.  If their hobby relates to programming or they do programming as a hobby, then it’s a sure bet that they are good at it.

So if you’ve stumbled onto this blog and you are sitting on the fence trying to decide if you want to pursue a degree in Computer Science, then you’ve come to the right blog.  In this post, I’m going to try and give you an idea what it takes to get a degree in Computer Science.

So let’s pretend that you’re not quite sure what this “programming” thing is all about.  You’ve been accepted by a university and you’ve declared your major as Computer Science.  You’re about to start your first class and you’re going to jump in head-first.  Except, you’re not sure what that first class is all about.  The first class you take will be a language class.  You’ll need to learn the basic syntax of a structured high-level language.  What does this mean?  It means that you’ll probably learn C or Java.  It doesn’t matter which language is “better” or which is the most used language in the marketplace, because you’re just learning your first language.  By the time you graduate, you’ll have learned at least 4 languages, and probably more.  In fact, you’ll start to discover that there are really only about 3 or 4 language “types” in the world and once you learn one language of each type, learning another is just as easy as learning to drive a different model care from the same manufacturer.  The controls are a bit different, but the operation is the same.  You’ll learn even more languages after you graduate.  I’ve learned at least 16 languages in my lifetime so far.

So what is this “syntax” that I’m talking about.  Well, the syntax is the patterns that are used by the language.  C and Java use very similar syntax.  When I was at the University of Michigan I learned Pascal.  Before that, it was FORTRAN, Basic and COBOL.  In any language, there is a syntax that must be learned first.  The only way to learn the syntax of a language is to write programs.  If you write enough Java programs, you’ll know the syntax of Java like the back of your hand.

The next step in your education will involve algorithms.  Algorithms are hard to escape.  In fact, programming is worthless without an algorithm and even the tiniest program is following some sort of elementary algorithm.  In Computer Science, there are lots of algorithms to handle different situations.  Once you have a few hundred algorithms under your belt, you’ll be able to write programs to perform almost any task.  To learn algorithms, you need to write more programs.  Writing programs that use different algorithms will teach you how to troubleshoot problems in your code and recognize how the algorithms actually work.

After you complete your algorithms classes, you’ll move onto specific upper level 300 and 400 level classes.  These are narrow in subject and they will also focus on algorithms, but they will focus on problems that are specific.  Subjects such as encryption, simulation, compilers, graphics, database design, etc.  Once you have crossed into these classes you’ll start to narrow your interest into subjects that you enjoy and ones that you’ll avoid.  Don’t be surprised by what you discover.  I found that the computer theory and compiler classes held my interest even though they are both about processing streams of text.  My database class was dry and boring, but my career in database design is anything but boring.  Sometimes the classwork doesn’t match real-world.  

So what do you do if you survive the first programming class?  This would be gut-check time.  Are you willing to continue with classes that are going to be like the one you just took?  Did you find the course material to be easy or are you still lost?  Did any of the programs get your blood pumping?  Or did they cause you to pull your hair out?  

In my next blog post, I’m going to try and help you through the first class.  I’ll give you some hints up-front that you should follow to ensure that you do well and learn the material.  Just passing the class, but not learning the material will be of no use.  This degree program requires you to understand and apply your knowledge.  The Computer Science career path is about solving problems.  Similar to solving math word problems (I still hate those), but in this case you’ll be solving real-world computer problems.

 

Source Control – Branching and Merging

Summary

In this blog post I’m going to talk about branching and merging your software in a multi-team development environment.

The Community Branch

A common mistake in branching is assuming that fewer branches are better.  The logic behind this assumption revolves around the idea that fewer branches translate to fewer merges.  Technically this is true, but each merge is very large and complex.  A larger number of smaller branches are easier to manage than a small number of larger branches and I’m going to show why this is true.

But first, I’m going to describe what I call the “community branch.”  The community branch is a branch that contains many different projects, shared by a large group of programmers.  The idea is that the branch is just an abstract place to put code (like a development branch) and that change sets can be moved around as though they are independent of each other.  

Here’s a simple example diagram of such a setup:


I want to stop and mention that I’m trying to explain a very complex “issue” here.  So I’m going to make this explanation as simple as possible and ignore any QA or stage testing process.  I’ll just assume that the process goes from development to deployment and demonstrate problems that occur when projects are mixed on one branch.

In the above diagram I have a main branch which is the branch that contains the latest software deployed to the production system.  The first operation (point B) is a branch for the start of development work (C).  Two teams of developers are working on the software.  The first team completes some of their work and checks it into the development branch at point D.  Project team 2 begins work after this point (for simplicity of this example) and they then check their software in at point E.  Project team 2 then merge their version into the main branch and the software is deployed.  Project team 1 is still working on their software and they continue to check in changes (point G).

Now for the problem in this scheme.  First, points D, E, and G are change sets.  If the change sets are all merged back to the main branch in the same order that they are checked into the development branch, then everything will work correctly.  Also, if at any point the team who merges to main performs a merge of all change sets from their point to the beginning, everything will work out (assuming all software is ready to go).  

However, if project 1 requires a refactoring of common code that project 2 is dependent on, then there is a problem.  If change set E is merged, but relied on changes made at change set D, then the merge to main will be broken (even though it worked on the development branch).  The only way to fix the merge to main is to manually make changes on the main branch to compensate for the modified common code that was made in the development branch.  The entire change set D cannot be merged with main at this point because project 1 is a partially completed project.

Every community branch will experience this issue if the branch is allowed to live long enough.  It’s unavoidable.  The problem will get worse as more changes are made to the branch that are not deployed.  The reason code might not be deployed can be due to long development time projects, projects that get placed on the back-burner or projects that get cancelled.


Project Branches

The correct method of branching is to isolate projects on their own branches.  Each team of programmers work with their own branch.  If a deployment to main is made from another project (or bug fixes, hot fixes, etc.), then the main branch is re-merged with the local project branch.  Each programming team must assign an owner to their project branch who must ensure that the branch is always up to date.  Once the project (or the sprint) is complete, then the branch can be merged into main.  

Here’s an example:

In this example project team 1 forms their own branch, which we will refer to as the project 1 branch.  Project team two form their own branch, called the project 2 branch.  Each branch is always formed from the main branch because that is the latest deployed software.  When project team 2 complete their sprint or project, they are authorized to merge with main.  The merge is made and since there are no other changes on main, they should get a clean merge.  Then the software is deployed to the production system.  After deployment, each branch must be re-merged from main.  In this example, project team 1 will merge changes from main back to their own branch.  If there are any common object changes, then they will need to be updated on the project 1 branch.  In this instance, project 1 will be ready to merge clean into the main branch after point G.  Any common objects changed by project 1 do not need to show up in the software created by project 2 until deployed to main by project 1.  It is also project team 1 who is responsible for the update to all software that is touched by the refactoring of common software.  Later down the line, project team 1 will merge with main and the merge will be clean.

Each time software is merged with main, all branches must re-merge from the main to obtain the latest changes that were deployed.  

Using a QA Branch

OK, so let’s show an example using a QA branch.  First, the QA branch is created from main and lives forever.  This is a special branch, and no work is to be performed directly on this branch.  The QA branch should only contain changes merged from other branches.  Once QA testing has been completed, then the results of the QA branch can be merged with main and deployed.  At the point of deployment, the QA branch should equal the main branch (i.e. a software source code comparison should be identical, minus any config files specific to the QA environment).  

Here’s an example:

In this example, all the rules from the previous example still apply.  When a deployment occurs, all live branches must re-merge from main (not from QA).  In the diagram above, project 1 starts first and the branch is created from main (C and D).  Project 2 starts after and it is also created from main (E and F).  Then each project in this example are completed and selected for the next deployment cycle (G and I).  Both branches are merged with QA (H and J).  Then an bug is detected during QA and project team 2 must fix this bug.  They must fix the bug in their branch and then merge their latest change sets down to QA for re-testing (K and L).  Once QA has been completed and the software is ready for release, it can be merged with main and deployed (M and N).  

One other note: When a project is completed and deployed, then the branch for that project should be closed.  If any bugs are detected after this point, it should be treated as a bug and not part of the original project.  The reason for closing the branch is to reduce the maintenance required.  There is no reason to keep maintaining branches that belong to completed projects.

Other Branches

I’m sure by now you can visualize adding a permanent branch called “stage” that would perform a similar function to the QA branch.  In such a setup, the stage branch would be the destination of the QA branch upon completion of quality checking.  Alternatively, merging to stage could occur right after software is merged into QA and continuously merged from QA to stage as updates are made.  That would provide the ability to test in a QA environment and a stage environment in parallel.  The completed software would be merged from stage down to main for final deployment.

One wrench in the works are bugs.  Bug fixing is usually performed in a short period of time.  Many software shops will create a bug branch, fix bugs and merge these into QA or directly to main.  Bugs would need to be bundled together to prevent too many changes to main which would trigger re-merges with project branches.  It’s recommended to perform bug fixes and merge into the QA branch at the time when projects are first merged.  Then QA can be performed on the bugs, the projects and merged toward main at one time.  Once everything is merged in main and deployed, then all changes can be re-merged back to any open project branches.

Hot fixes or emergency bugs also need to be accounted for.  Hot fixes can also have a special branch that lives forever.  This branch would probably bypass the QA branch since a hot fix is usually something that must go out right away.  Once a hot fix is deployed, all branches, including QA should re-merge the changes from main.

Potential Issues

One branching issue occurs when a database change must be performed.  A branch that requires a change in a database must somehow merge those changes into the QA environment database and then down to the main database(s) (in production) at the right time.  I’m not going to cover this issue in this blog post because it applies to the community branch just as well as project branching scheme.

Automated deployments must account for constantly changing branches.  The automated deployment system should be setup to allow any branch to be deployed to any environment.  The most efficient setup would involve virtual development environments that can be cloned from your production environment with nearly identical configurations.  This will reduce the amount of time it takes developers to fix problems related to differences in environments.  It also increases the success rate of the final deployment since configuration variables are removed at development, QA and staging time.  I’m not going to go into automated deployment systems in this article but hard-coding an environment to a branch is bad practice and should be avoided.