To Git, a branch is a branch, but it’s often useful to assign special meaning to different branches. For example, we’ve been using
master
as the stable branch for our example project, and
we’ve also used a temporary branch to add some CSS formatting. Temporary
branches like the latter are called topic branches because
they exist to develop a certain topic, then they are deleted. We’ll work
with two types of topic branches later in this module.Amid our exploration of Git branches, we’ll also discover that some merges cannot be “fast-forwarded.” When the history of two branches diverges, a dedicated commit is required to combine the branches. This situation may also give rise to a merge conflict, which must be manually resolved before anything can be committed to the repository.
If you’ve been following along from the previous module, you already have everything you need. Otherwise, download the zipped Git repository from the above link, uncompress it, and you’re good to go.
Continue the Crazy Experiment
Let’s start by checking out thecrazy
branch.Thegit
branch
git
checkout
crazy
git
log
--oneline
crazy
branch is a longer-running type of topic branch
called a feature branch. This is fitting, as it was created
with the intention of developing a specific feature. It’s also a
term that makes Git’s contribution to the development workflow readily
apparent: branches enable you to focus on developing one clearly defined
feature at a time.This brings us to my rule-of-thumb for using Git branches:
- Create a new branch for each major addition to your project.
- Don’t create a branch if you can’t give it a specific name.
Merge the CSS Updates
Note that the CSS formatting we merged intomaster
is nowhere
to be found. This presents a bit of a problem if we want our experiment to
reflect these updates. Conveniently, Git lets us merge changes into
any branch (not just the master
branch). So, we can pull
the updates in with the familiar git merge
command. Remember that
merging only affects the checked-out branch.As of Git 1.7.10, this will open your editor and prompt you for a message explaining why the commit was necessary. You can use the defaultgit
merge
master
git
log
--oneline
Merge
branch 'master' into crazy
. When you save and close the file,
you’ll notice an extra commit in your project history. Recall that our
first merge didn’t add any new commits; it just
“fast-forwarded” the tip of the master
branch. This
was not the case for our new merge, which is shown below.
master
into the crazy
branchcrazy
pointer
over to the tip of the master
branch? It’s not possible
without backtracking, which kind of defeats the idea of
“fast-forwarding.” We’re left with a new way to combine
branches: the 3-way merge.A 3-way merge occurs when you try to merge two branches whose history has diverged. It creates an extra merge commit to function as a link between the two branches. As a result, it has two parent commits. The above figure visualizes this with two arrows originating from the tip of
crazy
. It’s like saying “this commit comes from both
the crazy
branch and from master
.”
After the merge, the crazy
branch has access to both its history
and the master
history.The name comes from the internal method used to create the merge commit. Git looks at three commits (numbered in the above figure) to generate the final state of the merge.
This kind of branch interaction is a big part of what makes Git such a powerful development tool. We can not only create independent lines of development, but we can also share information between them by tying together their histories with a 3-way merge.
Style the Rainbow Page
Now that we have access to the CSS updates frommaster
, we can
continue developing our crazy experiment. Link the CSS stylesheet to
rainbow.html
by adding the following HTML on the line after the
<title>
element.Stage and commit the update, then check that it’s reflected in the history.<link
rel=
"stylesheet"
href=
"style.css"
/>
Notice that we skipped the staging step this time around. Instead of usinggit
status
git
commit
-a
-m
"Add CSS stylesheet to rainbow.html"
git
log
--oneline
git add
, we passed the -a
flag to git
commit
. This convenient parameter tells Git to automatically include
all tracked files in the staged snapshot. Combined with the
-m
flag, we can stage and commit snapshots with a single command.
However, be careful not to include unintended files when using the
-a
flag.Link to the Rainbow Page
We still need to add a navigation link to the home page. Change the “Navigation” section ofindex.html
to the
following.As usual, stage and commit the snapshot.<h2>
Navigation</h2>
<ul>
<li
style=
"color: #F90"
>
<a
href=
"orange.html"
>
The Orange Page</a>
</li>
<li
style=
"color: #00F"
>
<a
href=
"blue.html"
>
The Blue Page</a>
</li>
<li>
<a
href=
"rainbow.html"
>
The Rainbow Page</a>
</li>
</ul>
git
commit
-a
-m
"Link index.html to rainbow.html"
git
log
--oneline
Fork an Alternative Rainbow
Next, we’re going to brainstorm an alternative to the currentrainbow.html
page. This is a perfect time to create another topic
branch:Remember, we can do whatever we want here without worrying about eithergit
branch
crazy-alt
git
checkout
crazy-alt
crazy
or master
. When git branch
creates
a branch, it uses the current HEAD
as the starting point for the
new branch. This means that we begin with the same files as crazy
(if we called git branch
from master
, we would have
had to re-create rainbow.html
). After creating the new branch, our
repository’s history looks like:
crazy-alt
branchChange the Rainbow
Change the colorful list inrainbow.html
from:to the following:<ul>
<li
style=
"color: red"
>
Red</li>
<li
style=
"color: orange"
>
Orange</li>
<li
style=
"color: yellow"
>
Yellow</li>
<li
style=
"color: green"
>
Green</li>
<li
style=
"color: blue"
>
Blue</li>
<li
style=
"color: indigo"
>
Indigo</li>
<li
style=
"color: violet"
>
Violet</li>
</ul>
Then, add some CSS formatting to<div
style=
"background-color: red"
></div>
<div
style=
"background-color: orange"
></div>
<div
style=
"background-color: yellow"
></div>
<div
style=
"background-color: green"
></div>
<div
style=
"background-color: blue"
></div>
<div
style=
"background-color: indigo"
></div>
<div
style=
"background-color: violet"
></div>
<head>
on the line after the
<meta>
element:If you open<style>
div
{
width
:
300px
;
height
:
50px
;
}
</style>
rainbow.html
in a browser, you should now see
colorful blocks in place of the colorful text. Don’t forget to commit the
changes:The resulting project history is show below, with the first four commits omitted for the sake of presentation.git
commit
-a
-m
"Make a REAL rainbow"

crazy-alt
branchEmergency Update!
Our boss called in with some breaking news! He needs us to update the site immediately, but what do we do with ourrainbow.html
developments? Well, the beauty of Git branches is that we can just leave them
where they are and add the breaking news to master
.We’ll use what’s called a hotfix branch to create and test the news updates. In contrast to our relatively long-running feature branch (
crazy
), hotfix branches are used to quickly patch
a production release. For example, you’d use a hotfix branch to fix a
time-sensitive bug in a public software project. This distinction is useful for
demonstrating when it’s appropriate to create a new branch, but it is
purely conceptual—a branch is a branch according to Git.Change the “News” list ingit
checkout
master
git
branch
news-hotfix
git
checkout
news-hotfix
index.html
to match the
following.And, create a new HTML page called<h2
style=
"color: #C00"
>
News</h2>
<ul>
<li><a
href=
"news-1.html"
>
Blue Is The New Hue</a></li>
</ul>
news-1.html
with the following
content.We can’t use<!DOCTYPE html>
<html
lang=
"en"
>
<head>
<title>
Blue Is The New Hue</title>
<link
rel=
"stylesheet"
href=
"style.css"
/>
<meta
charset=
"utf-8"
/>
</head>
<body>
<h1
style=
"color: #079"
>
Blue Is The New Hue</h1>
<p>
European designers have just announced that<span
style=
"color: #079"
>
Blue</span>
will be this year's hot color.</p>
<p><a
href=
"index.html"
>
Return to home page</a></p>
</body>
</html>
git commit -a
to automatically stage
news-1.html
because it’s an untracked file (as
shown in git status
). So, let’s use an explicit git
add
:Test these additions in a browser to make sure that the links work, it’s typo free, etc. If everything looks good, we can “publish” the changes by merging them into the stablegit
add
index.html
news-1.html
git
status
git
commit
-m
"Add 1st news item"
master
branch. Isolating this in a separate branch isn’t
really necessary for our trivial example, but in the real world, this would
give you the opportunity to run build tests without touching your stable
project.Publish the News Hotfix
Remember that to merge into themaster
branch, we first need to
check it out.Sincegit
checkout
master
git
merge
news-hotfix
master
now contains the news update, we can delete the hotfix
branch:The following diagram reflects our repository’s history before and after the merge. Can you figure out why was this a fast-forward merge instead of a 3-way merge?git
branch
-d
news-hotfix
git
branch

master
to the
news-hotfix
branchmaster
branches in two directions), which means we should expect to see another merge
commit in the near future.Complete the Crazy Experiment
Ok, let’s finish up our crazy experiment with one more commit.Note that the news article is nowhere to be found, as should be expected (this branch is a completely isolated development environment).git
checkout
crazy
We’ll finish up our crazy experiment by adding a news item for it on the home page. Change the news list in
index.html
to the following:Astute readers have probably observed that this directly conflicts with what we changed in the<h2
style=
"color: #C00"
>
News</h2>
<ul>
<li><a
href=
"rainbow.html"
>
Our New Rainbow</a></li>
</ul>
news-hotfix
branch. We should not
manually add in the other news item because it has no relationship with the
current branch. In addition, there would be no way to make sure the link works
because news-1.html
doesn’t exist in this branch. This may
seem trivial, but imagine the errors that could be introduced had
news-hotfix
made dozens of different changes.We’ll simply stage and commit the snapshot as if there were no conflicts:
Look at all those experimental commits (marked with asterisks below)!git
commit
-a
-m
"Add news item for rainbow"
git
log
--oneline
*42fa173
Add news item for rainbow*7147cc5
Link index.html to rainbow.html*6aa4b3b
Add CSS stylesheet to rainbow.htmlb9ae1bc
Merge branch 'master' into crazyae4e756
Link HTML pages to stylesheet98cd46d
Add CSS stylesheet*33e25c9
Rename crazy.html to rainbow.html*677e0e0
Add a rainbow to crazy.html506bb9b
Revert "Add a crazzzy experiment"*514fbe7
Add a crazzzy experiment1c310d2
Add navigation links54650a3
Create blue and orange pagesb650e4b
Create index page
Publish the Crazy Experiment
We’re finally ready to merge ourcrazy
branch back into
master
.You should get a message that reads:git
checkout
master
git
merge
crazy
Auto-merging index.html CONFLICT (content): Merge conflict in index.html Automatic merge failed; fix conflicts and then commit the result.This is our first merge conflict. Conflicts occur when we try to merge branches that have edited the same content. Git doesn’t know how to combine the two changes, so it stops to ask us what to do. We can see exactly what went wrong with the familiar
git status
command:We’re looking at the staged snapshot of a merge commit. We never saw this with the first 3-way merge because we didn’t have any conflicts to resolve. But now, Git stopped to let us modify files and resolve the conflict before committing the snapshot. The “Unmerged paths” section contains files that have a conflict.#
On branch
master
#
Changes to be committed:
#
#
new file: rainbow.html
#
#
Unmerged paths:
# (use "git add/rm <file>..." as appropriate to mark resolution)
#
#
both modified: index.html
#
Open up
index.html
and find the section that looks like:<<<<<<< HEAD <li><a href="news-1.html">Blue Is The New Hue</a></li> ======= <li><a href="rainbow.html">Our New Rainbow</a></li> >>>>>>> crazyGit went ahead and modified the conflicted file to show us exactly which lines are afflicted. The format of the above text shows us the difference between the two versions of the file. The section labeled
<<<<<<< HEAD
shows us the version in the
current branch, while the part after the =======
shows the version
in the crazy
branch.Resolve the Merge Conflicts
We can change the affected lines to whatever we want in order to resolve the conflict. Edit the news section ofindex.html
to keep changes from
both versions:The<h2
style=
"color: #C00"
>
News</h2>
<ul>
<li><a
href=
"news-1.html"
>
Blue Is The New Hue</a></li>
<li><a
href=
"rainbow.html"
>
Our New Rainbow</a></li>
</ul>
<<<<<<<
, =======
, and
>>>>>>>
markers are only used to show us the
conflict and should be deleted. Next, we need to tell Git that we’re done
resolving the conflict:That’s right, all you have to do is addgit
add
index.html
git
status
index.html
to the
staged snapshot to mark it as resolved. Finally, complete the 3-way merge:We didn’t use thegit
commit
-m
flag to specify a message because
Git already gives us a default message for merge commits. It also gives us a
“Conflicts” list, which can be particularly handy when trying to
figure out where something went wrong in a project. Save and close the file to
create the merge commit.The final state of our project looks like the following.

crazy
branch into
master
Cleanup the Feature Branches
Since our crazy experiment has been successfully merged, we can get rid of our feature branches.As noted in the last module, thegit
branch
-d
crazy
git
branch
-d
crazy-alt
git branch -d
command
won’t let you delete a branch that contains unmerged changes. But, we
really do want to scrap the alternative experiment, so we’ll follow the
error message’s instructions for overriding this behavior:Because we never mergedgit
branch
-D
crazy-alt
crazy-alt
into master
, it
is lost forever. However, the crazy
branch is still accessible
through its commits, which are now reachable via the master
branch. That is to say, it is still part of the structure of the
repository’s history, even though we deleted our reference to it.
Conclusion
This module demonstrated the three most common uses of Git branches:- To develop long-running features (
crazy
) - To apply quick updates (
news-hotfix
) - To record the evolution of a project (
master
)
We used the permanent
master
branch as the foundation for all
of these temporary branches, effectively making it the historian for our entire
project. In addition to master
, many programmers often add a
second permanent branch called develop
. This lets them use
master
to record really stable snapshots (e.g., public
releases) and use develop
as more of a preparation area for
master
.This module also introduced the 3-way merge, which combines two branches using a dedicated commit. The 3-way merge and the fast-forward merge are actually what makes branching so powerful: they let developers share and integrate independent updates with reliable results.
Next, we’ll learn how to clean up our repository’s history. Using a new Git command, we’ll be able to better manage merge commits and make sure our history is easy to navigate.
Quick Reference
git commit -a -m "<message>"
- Stage all tracked files and commit the snapshot using the specified message.
git branch -D <branch-name>
- Force the removal of an unmerged branch (be careful: it will be lost forever).
Comments
Post a Comment