Skip to main content

📓 Git Branching

So far we've learned what Git and GitHub are, how to set up a project, track changes, push code to GitHub, and clone projects back down from GitHub into a local Git repository.

In this lesson we'll dive deeper into Git by exploring something called branching. In this lesson, we'll learn more about what it is, how it works, what benefits it offers, and how to create and maintain branches in our own projects.

To do this, we'll walk through creating an example project in the next two lessons. Together, we'll create and merge branches in this example project. Then, in an upcoming exercise you'll have the opportunity to work with branches on your own project with a partner.

Overview


In Git, branching is the act of creating multiple copies of similar code in the same repository. There are many reasons developers do this. Here are a few of the most common:

  • Multiple branches allow a team of developers to work together without "stepping on each others' feet", so to speak. If a team was all working on the same files at the same time, things could get messy very quickly. Branches allow each developer their own copy of the project to work on. When part of the project is done, the team can merge multiple branches together into a completed final product. We'll get plenty of practice with this when we work on group projects during team week.

  • Branching also allows us to experiment with changes without risking our final product. We can use branching to create a copy of our code separate from our final version to experiment with new features and code. If this new code causes any bugs, we can rest assured knowing our original code is still safe!

  • Branching allows us to pursue multiple options at once. Not sure which approach to a problem is preferable? With branching, you could always create multiple copies of your project, try implementing different code in each, and see which result is preferable.

Main Branch


You may be surprised to learn that you've been interacting with branches since the beginning of the course! At this point in the curriculum, you've most likely pushed several projects to GitHub already. Your current GitHub repositories should look something like this:

basic-github-repo

Notice the dropdown menu on the left side labeled Branch:

branch-dropdown-on-github

If we click this dropdown we see it contains one entry: main.

When you learned how to push a project to a remote GitHub repo, you pushed your local Git repositories to online GitHub repositories using a command like this:

$ git push al main

(The initials al in the command above are just an example; your own initials would be placed here.)

The main portion of this command instructs Git to push the current main copy of your local repository to the remote repository under the nickname al.

But what does main mean? Well, projects tracked in Git and GitHub may have multiple branches. The term main specifies that code should be pushed to the main branch on GitHub. Remember, we saw there was a branch named main in the dropdown menu on GitHub.

A branch is just another copy or version of the project's main code. Both Git and GitHub repositories may have multiple branches at once. There is always at least one branch in a project: the main branch.

Main is the name of the default branch. If you don't create or navigate between branches in your project, you will have one branch named main, and you will be located in it by default. When you have multiple branches in a project, the main branch is like the "final draft".

Branches that are not main are often referred to as feature branches, because they allow developers to experiment with new features before integrating them into the "final draft" main branch.

Example Project


Let's walk through a basic example of branching together. We'll craft a small website. Then, we'll create multiple branches to experiment with different CSS styles. We'll compare the styles, choose which we like best, and integrate the favored styles into our "final draft" (that is, our main branch). You and your partner should begin following along at this time.

Project Setup

First, we'll set up our basic site. Everything in this section should be review from previous lessons.

Project Directory

First, let's create a new project directory on our Desktop. Remember, whenever we start a new project we must create a new directory for it to reside in. First, we'll navigate to our Desktop:

$ cd Desktop

Then, we'll create a new directory called branching-test-project:

$ mkdir branching-test-project

If we run $ ls we can see our new branching-test-project directory. Next, use the $ cd command to navigate to the new project folder:

$ cd branching-test-project

Remember, if you're ever unsure of your location in the command line you can run the $ pwd command.

Git Initialization

Next, we'll initialize our Git repository:

$ git init

HTML File

Next, let's create an HTML file for our website's code:

$ touch branching-website.html

We'll open our project directory in VS Code:

$ code .

And add the following code to our branching-website.html file:

branching-website.html
<!DOCTYPE html>
<html lang="en-US">
<head>
<title>Branching Practice Site</title>
</head>
<body>
<h1>Branching</h1>
<h2>A website to practice branching with Git.</h2>
<p>This page has been created in order to practice branching with Git and GitHub. By creating branches, we can work on different versions of the same code in the same repository simultaneously!</p>
</body>
</html>

Committing Changes

Once this code is in place, we can make our first commit. First, we'll run $ git status to see there are new, uncommitted changes in our project. It should show that branching-website.html hasn't been committed yet. Untracked changes show up in red.

Then, we can run $ git add to add our new branching-website.html file to Git so it will track this file's changes:

$ git add branching-website.html

We can run $ git status again to see that our file is now being tracked, but has not yet been committed. Tracked changes show up in green.

Let's save our new HTML to the permanent history of the project by committing it. You'll use the $ git commit command to do this:

$ git commit -m "Add initial HTML file with explanation of branching practice site."

If we run $ git log we can see a new commit has been added to the history of our project:

$ git log
commit eb1774eee69d3e8fa1d74790dc9c64d70d1e9ec2
Author: Ada Lovelace and Enrique de la Fuente <ada@>
Date: Mon Oct 10 11:49:54 2016 -0700

Add initial HTML file with explanation of branching practice site.

When you run $ git log, the person who committed will be listed as the author.

Updating the Default Branch to Main

If needed, update the default branch from master to main:

git branch -M main

Adding Styles with CSS

Great! Now, earlier today you learned about CSS. Before we begin branching, let's create a basic CSS stylesheet for our example project. We'll make a folder called css in our existing project directory:

$ mkdir css

Then, we'll create a file called styles.css within our new css directory:

$ touch css/styles.css

Note that we don't have to cd into the css directory — we can just specify the directory where we want the file to be created!

Our project structure should look like this:

project-structure-with-css-in-atom

Note that the image above looks a little different because it uses a different text editor.

Next, let's tell our HTML document to use this new file for its CSS. We will include a link to the new CSS file in the <head> tags of our branching-website.html file, like this:

branching-website.html
<!DOCTYPE html>
<html lang="en-US">
<head>
<link href="css/styles.css" rel="stylesheet" type="text/css">
<title>Branching Practice Site</title>
</head>
<body>
<h1>Branching</h1>
<h2>A website to practice branching with Git.</h2>
<p>This page has been created in order to practice branching with Git and GitHub. By creating branches, we can work on different versions of the same code in the same repository simultaneously!</p>
</body>
</html>

Let's add these new changes to our Git repository:

$ git add .

And commit them to the history of our project:

$ git commit -m "Create stylesheet, link in head of website."

Next, we'll add a basic CSS rule to our stylesheet:

styles.css
h1 {
color: blue;
}

If we open the branching-website.html file in our browser, we should see that the text in the <h1> tags is blue:

blue-headings

Let's add and commit this new CSS rule to our project:

$ git add css/styles.css
$ git commit -m "Add CSS rule to make H1 headings blue."

If we run $ git log, we now have 3 commits:

$ git log
commit 982b0f21463be34d909c45dd67778d6ffe3d7668
Author: Ada Lovelace and Enrique de la Fuente <enrique@>
Date: Mon Oct 10 12:06:35 2016 -0700

Add CSS rule to make H1 headings blue.

commit 8e36f8bfd58643487565c5a4fbcb5250fed0808b
Author: Ada Lovelace and Enrique de la Fuente <ada@>
Date: Mon Oct 10 12:04:27 2016 -0700

Create stylesheet, link in head of website.

commit eb1774eee69d3e8fa1d74790dc9c64d70d1e9ec2
Author: Ada Lovelace and Enrique de la Fuente <ada@>
Date: Mon Oct 10 11:49:54 2016 -0700

Add initial HTML file with explanation of branching practice site.

Now that our basic website is set up, we can use it to learn about branching in the next section. Nice work!

Viewing a Project's Branches


Everything we've done thus far should be review. Now, let's explore the new concept at hand: Branching. First we'll run the following command:

$ git branch

The $ git branch command displays what branches are currently in our project. It also denotes which branch we're currently viewing with an asterisk *. After we execute this command, we should see this:

* main

This informs us that there is only one branch: main. And, we know we're currently located in that branch because there is an asterisk next to it. Remember, main is the default branch. If we do not create any branches, or move between any branches, we will be on main.

Creating a New Branch


Let's pretend we're unsure how to style our site. We want to test a couple different stylistic approaches, and see which looks best. To do this, we'll create several versions of our project with branches. We'll implement different styles in each branch.

We can create a new branch by running the $ git branch command and including the name of the new branch after it, like this:

$ git branch blue_theme

This creates a new branch named blue_theme. Branch names should be short and meaningful, and describe the reason for the branch. In our case, this branch will contain styles that use the color blue throughout.


If we run $ git branch again, we can see our project now contains two branches:

$ git branch

blue_theme
* main

Notice the asterisk is still next to main. We created a new blue_theme branch, but we're still located on main. We can switch branches like this:

$ git checkout blue_theme

The $ git checkout command navigates to the specified branch. We can run $ git branch again to confirm we've successfully entered the blue_theme branch:

$ git branch

* blue_theme
main

The asterisk is now next to blue_theme, so we know we've successfully navigated to that branch. Now, let's look at our project in VS Code. Despite being located in our new branch, everything should look the exact same.

When you create a branch, the new branch is "branched off" from the branch you are located in when the command to create a new branch is executed. This means the new branch will contain all code and commits from the branch it was branched off from. In our case, since we were located in main when we created blue_theme , blue_theme contains all code and commits that main contained at the time of the new branch's creation.

We can confirm this by running $ git log. We should see our new branch contains the same commits we made on main:

$ git log

commit 982b0f21463be34d909c45dd67778d6ffe3d7668
Author: Ada Lovelace and Enrique de la Fuente <enrique@>
Date: Mon Oct 10 12:06:35 2016 -0700

Add CSS rule to make H1 headings blue.

commit 8e36f8bfd58643487565c5a4fbcb5250fed0808b
Author: Ada Lovelace and Enrique de la Fuente <ada@>
Date: Mon Oct 10 12:04:27 2016 -0700

Create stylesheet, link in head of website.

commit eb1774eee69d3e8fa1d74790dc9c64d70d1e9ec2
Author: Ada Lovelace and Enrique de la Fuente <ada@>
Date: Mon Oct 10 11:49:54 2016 -0700

Add initial HTML file with explanation of branching practice site.

Working on a Branch


We now have a separate, isolated version of our project to experiment with. We can safely test code in blue_theme without risking the integrity of code in main. We can change, add, and commit whatever we'd like in blue_theme and main will remain completely unaffected. Let's add more CSS to the styles.css stylesheet:

styles.css
h1 {
color: blue;
text-align: center;
}

h2 {
font-style: italic;
text-align: center;
color: teal;
}

p {
color: gray;
}

body {
background-color: skyblue;
}

If we refresh our page in the browser, we can see these new styles:

test-site-blue-theme

As always, we'll add these changes to our Git repository and commit them:

$ git add css/styles.css
$ git commit -m "Add styles to h1, h2, p, and body to fit blue theme."

Separation of Commits Between Branches


Let's run $ git log again to see a summary of our commits:

$ git log

commit 268363ae7b81a7ee91540d93f82e3f9285c575dd
Author: Ada Lovelace and Enrique de la Fuente <enrique@>
Date: Mon Oct 10 12:24:38 2016 -0700

Add styles to h1, h2, p, and body to fit blue theme.

commit 982b0f21463be34d909c45dd67778d6ffe3d7668
Author: Ada Lovelace and Enrique de la Fuente <enrique@>
Date: Mon Oct 10 12:06:35 2016 -0700

Add CSS rule to make H1 headings blue.

commit 8e36f8bfd58643487565c5a4fbcb5250fed0808b
Author: Ada Lovelace and Enrique de la Fuente <ada@>
Date: Mon Oct 10 12:04:27 2016 -0700

Create stylesheet, link in head of website.

commit eb1774eee69d3e8fa1d74790dc9c64d70d1e9ec2
Author: Ada Lovelace and Enrique de la Fuente <ada@>
Date: Mon Oct 10 11:49:54 2016 -0700

Add initial HTML file with explanation of branching practice site.

The blue_theme branch now contains the commits it inherited from main, and the new commit we've just made. Before we continue, let's return to our main branch for a moment using the $ git checkout command:

$ git checkout main

As always, we can double-check we're on main by running $ git branch and confirming that main has an asterisk next to it:

$ git branch

blue_theme
* main

Great. Now, let's look at the commits on our main branch again:

$ git log

commit 982b0f21463be34d909c45dd67778d6ffe3d7668
Author: Ada Lovelace and Enrique de la Fuente <enrique@>
Date: Mon Oct 10 12:06:35 2016 -0700

Add CSS rule to make H1 headings blue.

commit 8e36f8bfd58643487565c5a4fbcb5250fed0808b
Author: Ada Lovelace and Enrique de la Fuente <ada@>
Date: Mon Oct 10 12:04:27 2016 -0700

Create stylesheet, link in head of website.

commit eb1774eee69d3e8fa1d74790dc9c64d70d1e9ec2
Author: Ada Lovelace and Enrique de la Fuente <ada@>
Date: Mon Oct 10 11:49:54 2016 -0700

Add initial HTML file with explanation of branching practice site.

Notice that the new commit we just made on blue_theme is not present in main! Our blue_theme branch's most recent commit reads "Add styles to h1, h2, p, and body to fit blue theme." Whereas main's most recent commit reads "Add CSS rule to make H1 headings blue." And if we refresh our page in the browser again, we can see our blue styles are no longer present:

no-blue-theme

Also, if you view the styles.css stylesheet in Visual Studio Code, you'll notice that the CSS rules we just added are gone. Don't worry; this is entirely normal. Because we switched branches, the version of the project we're seeing in VS Code is different. The main branch does not have the same CSS rules as the blue_theme branch.

Remember, when we create a branch the new branch will inherit all commits from the branch it is branched off from. That is, the branch we are located in when we create the new branch. However, when we make new commits on our new branch, they remain on that branch. The organization of our current commits between branches look something like this:

flowchart-of-branches

We can see our first three commits on main. When we branched off of main to create blue_theme, it inherited all of main's commits. However, when we made subsequent commits in blue_theme they remained exclusive to blue_theme and were not shared with main.

Working with Multiple Branches


Let's create another branch with a different set of CSS styles for our site. Remember, you may branch off from any existing branch. The new branch will contain all code and commits from whatever branch you were located within when the new branch was created.

Creating a New Branch

Let's branch from main again. We'll run $ git branch and confirm we're located in main:

$ git branch

blue_theme
* main

Then, we'll create another new branch named red_theme, like this:

$ git branch red_theme

We'll run $ git branch again to confirm our new branch has been created:

$ git branch

blue_theme
* main
red_theme

Next, we'll switch to our new red_theme branch using the $ git checkout command:

$ git checkout red_theme

Switched to branch 'red_theme'

We can run $ git branch to confirm we've successfully navigated into the red_theme branch:

$ git branch

blue_theme
main
* red_theme

And, if we run $ git log we can see red_theme has inherited all commits from main, as expected:

$ git log

commit 982b0f21463be34d909c45dd67778d6ffe3d7668
Author: Ada Lovelace and Enrique de la Fuente <enrique@>
Date: Mon Oct 10 12:06:35 2016 -0700

Add CSS rule to make H1 headings blue.

commit 8e36f8bfd58643487565c5a4fbcb5250fed0808b
Author: Ada Lovelace and Enrique de la Fuente <ada@>
Date: Mon Oct 10 12:04:27 2016 -0700

Create stylesheet, link in head of website.

commit eb1774eee69d3e8fa1d74790dc9c64d70d1e9ec2
Author: Ada Lovelace and Enrique de la Fuente <ada@>
Date: Mon Oct 10 11:49:54 2016 -0700

Add initial HTML file with explanation of branching practice site.

Working on a Branch

Our styles.css file should look like this:

styles.css
h1 {
color: blue;
}

Again, notice that it does not contain the CSS we just committed in the blue_theme branch. The new red_theme branch was branched off of main. Therefore, it contains all of main's commits and code. It does not contain the code we committed on the blue_theme branch, only the main branch. Let's add styles to this branch's version of the styles.css file now:

styles.css
h1 {
color: darkred;
text-align: center;
}

h2 {
font-style: italic;
text-align: center;
color: red;
}

p {
color: crimson;
}

body {
background-color: salmon;
}

If we refresh our page in the browser, we can see our new CSS at work:

red-theme-styles

We'll add these changes to our Git repository, and commit:

$ git add css/styles.css
$ git commit -m "Add styles to h1, h2, p, and body to fit red theme."

As always, we can run $ git log to see a summary of our commits:

$ git log

commit 5f2d9510cdc76736c7c5cf7e5d56264cd405fcd1
Author: Ada Lovelace and Enrique de la Fuente <enrique@>
Date: Mon Oct 10 12:51:11 2016 -0700

Add styles to h1, h2, p, and body to fit red theme.

commit 982b0f21463be34d909c45dd67778d6ffe3d7668
Author: Ada Lovelace and Enrique de la Fuente <enrique@>
Date: Mon Oct 10 12:06:35 2016 -0700

Add CSS rule to make H1 headings blue.

commit 8e36f8bfd58643487565c5a4fbcb5250fed0808b
Author: Ada Lovelace and Enrique de la Fuente <ada@>
Date: Mon Oct 10 12:04:27 2016 -0700

Create stylesheet, link in head of website.

commit eb1774eee69d3e8fa1d74790dc9c64d70d1e9ec2
Author: Ada Lovelace and Enrique de la Fuente <ada@>
Date: Mon Oct 10 11:49:54 2016 -0700

Add initial HTML file with explanation of branching practice site.

Perfect. We now have the commits that came along with the new branch when we branched from main, and the new commit we've just made on the red_theme branch. Our organization of commits between branches currently looks like this:

flow-chart-2

Now, let's say we want to improve the styles in red_theme even further by changing the site's text. We'll include the following additional CSS rules in styles.css:

styles.css
h1 {
color: darkred;
}

h2 {
font-style: italic;
color: red;
}

p {
color: crimson;
}

body {
background-color: salmon;
font-family: sans-serif;
text-align: center;
}

Here, we denote that everything located in the <body> tags should have sans-serif style font that is center-aligned. Because we're now styling everything in <body> tags we can remove text-align: center; from the existing h1 and h2 CSS rules. The <h1> and <h2> tags exist within the <body> tags, so this rule will automatically apply to them too. We can save our changes and refresh the site to see our new styles:

red-theme-sans-serif

Again, we'll add these changes to our Git repository:

$ git add css/styles.css

And commit them with a descriptive message:

$ git commit -m "Make all font sans-serif style."

Let's run $ git log. We can see that in addition to the 3 commits inherited from main, the red_theme branch also has 2 of its own commits:

$ git log

commit d5bae6406669988e154608ce990e08fed51e9cb3
Author: Ada Lovelace and Enrique de la Fuente <enrique@>
Date: Mon Oct 10 13:00:42 2016 -0700

Make all font sans-serif style.

commit 5f2d9510cdc76736c7c5cf7e5d56264cd405fcd1
Author: Ada Lovelace and Enrique de la Fuente <enrique@>
Date: Mon Oct 10 12:51:11 2016 -0700

Add styles to h1, h2, p, and body to fit red theme.

commit 982b0f21463be34d909c45dd67778d6ffe3d7668
Author: Ada Lovelace and Enrique de la Fuente <enrique@>
Date: Mon Oct 10 12:06:35 2016 -0700

Add CSS rule to make H1 headings blue.

commit 8e36f8bfd58643487565c5a4fbcb5250fed0808b
Author: Ada Lovelace and Enrique de la Fuente <ada@>
Date: Mon Oct 10 12:04:27 2016 -0700

Create stylesheet, link in head of website.

The commits across all branches of the project currently look like this:

flow-chart-3

Benefits of Branching


Are you beginning to see how branching can be beneficial? It allows us to experiment with code and ensure it works correctly before saving it to our "final draft" main branch. When developers integrate new features into projects, they commonly do so in a branch. This allows them to make a copy of the entire project, experiment with new code, and confirm it does what it is supposed to before saving it into the final version.

This prevents bugs or issues from affecting the project. If the new code a developer adds breaks anything, it won't cause issues on main, only on that isolated branch. This allows developers room to iron out any issues with code before integrating it into the final version of the project.

When code is fine-tuned and tested in the branch, and we know it works, we can add it into main. This process is called merging, and we'll explore it in detail in the next lesson as we continue to work with this example project.