Working with branches in your local repo is so easy with git that using feature branches is the normal workflow for most users of git.

Unlike with subversion, branches and tags are distinctly different. A branch is dynamic and moves with each commit. Whereas a tag is static and points to a specific point in the history of the repository.

A default master branch is usually created by git during repository initialization. It is best to think about this branch as equivalent to Subversions trunk. In theory, you can rename or delete the master branch, but it’s best to just leave it alone.

Creating Branches

Let’s create a branch off of master in our ~/repos/example/ repository we created early:

[1]$ cd ~/repos/example
[2]$ git checkout master
[3]$ git branch
[4]$ git branch train/stuff
[5]$ git branch
[6]$ git checkout train/stuff
[7]$ git branch

Now you should have a branch called train/stuff and have it checked out.

You can also checkout and create a branch at the same time:

[8]$ git checkout -b train/doodle master
[9]$ git branch

Notice that we were still on the train/stuff branch, but we created a new branch called train/doodle relative to master without having to checkout master first.


Merging Branches

Let’s make a change on the train/doodle branch:

[10]$ echo '# Change on doodle branch' >> hello
[11]$ git add hello
[12]$ git commit

Now make a change on the train/stuff branch:

[13]$ git checkout train/stuff
[14]$ echo '# Change on stuff branch' >> hello
[15]$ git add hello
[16]$ git commit

Now the fun begins. Let’s go back to the master branch and merge the changes from the train/doodle and train/stuff branches:

[17]$ git checkout master
[18]$ git merge train/doodle
[19]$ git merge train/stuff   # <-- Oops! We got a merge conflict!

Before we can move on with our work, we need to fix the merge conflict:

[20]$ git mergetool
[21]$ git status
[22]$ git diff
[23]$ git diff --cached
[24]$ git commit
[25]$ git log --oneline --graph


You can configure git to use the mergetool of your choice (see Diff Tool and Merge Tool Configuration).

Deleting Branches

Once you have merged all the changes on your feature branch back to master, you can delete the branch:

[26]$ git checkout master
[27]$ git branch -d train/doodle
[28]$ git branch

You can also delete a branch that you consider a dead end without merging it back to master (or some other branch):

[29]$ git checkout -b train/deadend master
[30]$ echo '# this is a deadend branch' >> hello
[31]$ git add hello
[32]$ git commit
[33]$ git checkout master
[34]$ git branch
[35]$ git branch -d train/deadend  # <-- Notice that git fails here
[36]$ git branch -D train/deadend
[37]$ git branch