Branches

Marie-Hélène Burle

training@westgrid.ca

What is a branch?

A branch is a pointer to a commit (under the hood, it is a small file containing the 40 character hash checksum of the commit it points to)

What is a branch?

This is what On branch main means in the output of git status

This is also what (HEAD -> main) means when you run git log

Why use multiple branches?

  • If your changes break code, you still have a fully functional branch to go back to if needed

  • You can create a branch for each alternative approach. This allows you to jump back and forth between various alternatives

  • You can work on different aspects of the project on different branches. This prevents having messy incomplete work all over the place on the same branch

  • Mostly, branches are great for collaboration: each person can work on their own branch and merge it back to the main branch when they are done with one section of a project

How to create branches?

Initial branch (main)

When you run git init to initialize a repository, a branch gets created and it is called main (you could rename it to something else if you wanted—that initial branch, despite its name, has nothing special)

How to create branches?

Additional branches

You can create additional branches with:

git branch <branch-name>
Example:
git branch test

How to create branches?

Notice that HEAD still points to main

How to switch between branches?

You switch to a branch with:

git switch <branch-name>
Example:
git switch test

How to switch between branches?

Creating & switching in one go

When you create a branch, most of the time you want to switch to it. There is a handy way to create a branch and switch to it immediately:

git switch -c <branch-name>

Deleting branches

You can delete a branch with:

git branch -d <branch-name>

Getting information on branches

List local branches (current branch marked with *)

git branch
git branch -v   # show sha1 and commit message for each head
git branch -vv  # also show upstream branch

List remote branches

git branch -r

List all branches

git branch -a

Merging branches

Fast-forward merge

Here is a classic workflow with branches

You just switched to the branch test:

Merging branches

Fast-forward merge

Now you make a series of commits on that branch:

Merging branches

Fast-forward merge

Now you make a series of commits on that branch:

Merging branches

Fast-forward merge

You want to merge them back into the main branch

First, you switch to main (to merge, you need to be on the branch you want to merge into):

git switch main

Merging branches

Fast-forward merge

Merging branches

Fast-forward merge

Then you merge test into main:

git merge test

Merging branches

Fast-forward merge

Merging branches

Fast-forward merge

This merge is called a fast-forward merge: the branch main could be fast-forwarded to the branch test

Now, you can delete the branch test which has become useless:

git branch -d test

Merging branches

Fast-forward merge

Merging branches

Merge commit

Let’s consider another common workflow with a branch test2 starting from the same situation (you just created and switched to test2):

Merging branches

Merge commit

You create a number of commits on test2:

Merging branches

Merge commit

You create a number of commits on test2:

Merging branches

Merge commit

Then you switch to main:

Merging branches

Merge commit

and you create commits on main:

Merging branches

Merge commit

and you create commits on main:

Merging branches

Merge commit

To merge test2 into main, you need to be on main, but that’s already the case.

So you can run:

git merge test2

Merging branches

Merge commit

and you get:

Merging branches

Merge commit

Note that in order to make the merge in this scenario, Git had to create a new commit, called a merge commit and that this commit has 2 parents

Finally, you can now delete the test2 branch with git branch -d test2:

Resolving conflicts

If the same section of a file is changed on different branches, Git cannot know which version you would like to keep. The merge gets interrupted until you resolve the conflict

You can use a merge tool (run git mergetool --tool-help to get help setting this up)

Many GUI applications for Git as well as powerful text editors such as Emacs and Vim offer merge tools

Resolving conflicts

You can also resolve the conflict manually in any text editor:

When a merge gets interrupted due to a conflict, Git tells you which file contains a conflict. Open this file and look for a section that looks like this:

<<<<<<< HEAD
Version of this section of the file on the current branch
=======
Alternative version of the same section of the file
>>>>>>> alternative version

The <<<<<<< HEAD, =======, and >>>>>>> are markers added by Git to identify the alternative versions at the location of the conflict

You have to decide which version you want to keep (or write yet another version), remove the 3 lines with the markers, and remove the line(s) with the version(s) you do not want to keep

Questions?