Branches

If using git is like a time machine, then branches are parallel universes. You can use branches to to try out experiments, to isolate development of features or topics and, as we'll see later, they are used to collaborate with other repositories.

In some version control systems branching and (especially) merging are expensive operations. In git they are very easy and fast. In fact branching is just creating an alias to point to a particular commit.

git branch and git checkout

We can use the git branch command to see what branches we have. Initially we just have the one branch, by default called "master"

$ git branch
* master

We can create a new branch simply by appending the name

$ git branch crazy-idea

Now we have

$ git branch
  crazy-idea
* master

The asterisk indicates which branch we are currently on. To change the the new branch we use

git checkout crazy-idea

You could also do the last two steps in the one command

git checkout -b crazy-idea

If we add a new file, commit it, then change back to the master branch we see that the new file is no longer in the working directory.

If we decide that the branch is not needed we can delete it. If there are commits on that branch git will warn us

$ git branch -d crazy-idea 
error: The branch 'crazy-idea' is not fully merged.
If you are sure you want to delete it, run 'git branch -D crazy-idea'.
$ git branch -D crazy-idea
Deleted branch crazy-idea (was b85e41a).

git merge

Merging is the partner to branching. Suppose we have finished developemnt on a new feature in a branch and we want the code in the master branch, we do this using git merge

First make sure we are on the branch we want to merge in to

$ git checkout master

Then use git merge with the name of the branch we are merging in

$ git merge new-feature 
Updating f7a92c7..bf7762c
Fast-forward
 new-feature.md | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 new-feature.md

We can go ahead and delete the feature branch now. Git won't complain since the changes have been merged.

Merge conflicts

When git can automatically figure out how to merge it does, but it is sometimes the case that the same file has different edits in the same place. When this happens it is called a conflict and the output looks like this

$ git merge feature2
Auto-merging new-feature.md
CONFLICT (content): Merge conflict in new-feature.md
Automatic merge failed; fix conflicts and then commit the result.

Git has edited the file mentioned and added markers to draw your attention to where the conflicts are. It looks like

$ cat new-feature.md 
# Implementing the new feature

<<<<<<< HEAD
Here's how it looks in master
=======
Here's how it looks in feature2
>>>>>>> feature2

What we need to do now is use a text editor to change the file to the state we want then git add then git commit it.

If you are doing a lot of merging, say you have become the maintainer or release manager of a piece of software you should look in to the more sophisticated merge tools which can be configured with git mergetool.

Excercises

Exercise 1

Create and use a branch

  • examine what branches you have
git branch
  • create a new branch called experiment1
git branch experiment1
  • switch to your branch
git checkout experiment1
  • add a new file and commit it
nano new.md
git add new.md
git commit -m "new file containing vital info"
  • switch back to the master branch
git checkout master
  • delete the experiment1 branch
git branch -D experiment1

Exercise 2

Merge a feature

  • create a new branch called feature1 and check it out
git checkout -b feature1
  • add a new file and commit it
nano new.md
git add new.md
git commit -m "implement the new feature"
  • switch back to the master branch
git checkout master
  • merge in your feature branch
git merge feature1

Exercise 3

Create and resolve a merge conflit

  • Edit the same line in the same file in both the master and feature branches and commit it in both
# on the master branch
nano new.md
git add new.md
git commit -m "feature work in master"

# on the feature1 branch
git checkout feature1
nano new.md
git add new.md
git commit -m "more feature development"
  • Attempt to merge feature1 in to master
git checkout master
git merge feature1
  • Resolve the conflict
nano new.md
git add new.md
git commit -m "resolved conflict"
In [ ]: