Git Tutorial: Branching and Merging

By on Monday, October 24th, 2011 in Technical | Related Software Packages: | Keywords: ,

One of the most compelling features of the Git version control system (VCS) is its ability to create highly usable and lightweight branches, and the ease of merging those branches later. Branching creates multiple “copies” of the same repository and allows you to separate out a set of changes while you experiment with them, or to create different versions of a project, without affecting the main tree. It’s a feature that developers sometimes don’t make the most of, simply because branching is so much more costly in other VCSes that they’re not used to it, or they’re not aware of the many branch commands and tricks available in Git. Here’s a host of useful tips to get your Git branching and merging skills up to expert level in no time.

Since it’s so quick and easy to branch in Git, and equally easy to merge back into the main tree, it’s worth branching whenever you’re working on something new. It’s also good practice to use a branch when reviewing someone else’s patches before merging them with your own master branch.

The basic branch commands are:

  • git branch: list the current branches of the project.
  • git branch BranchName: create a new branch.
  • git branch -d BranchName: delete the named branch (use -D to force the delete even if data will be lost).
  • git checkout BranchName: update the current working directory to match, and work on, BranchName. git checkout -b BranchName will create the branch at the same time as it checks it out.

So to create a new branch of your project and call it V2, use git branch V2. If you do that, then type git branch to list all existing branches, you’ll see two branches, with a star by the one in use, which is still the “master” branch. To switch to the new branch, type git checkout V2. Make a change and commit it, then use git checkout master to switch back to the master, where your change will not be visible, because you made it to a different branch.

To merge V2 back into the current working branch, use git merge V2. Assuming you made no changes in the two branches that would conflict, V2 and the master branch are now identical, and git branch shows that the other branch still exists, so you can return to it and do more work. You need to have committed all your changes (or use git stash, which we’ll talk about in a moment) to merge. The merge will also fail if there are conflicts, in which case you can use git status to show the problem files, and edit them to resolve the conflict. Run git add file.txt for each edited file to add it to the scheduled commit, then git commit to finish the merge commit.

To show branches (and tags, which are used to mark important points in a project’s history) and make this process easier to track, use

git log --oneline --decorate

Another useful command is git checkout -. A bit like cd -, this command returns to the previously checked-out branch. It’s useful if you’re frequently jumping between branches. You can also use git checkout @\{-2\} to check out the second-last branch previously checked out, and similarly with any number. (The - symbol is just an alias for @\{-1\}.)

Merging and Rebasing

With a straight merge, the history shows the changes tracked on the new branch, then one big merge on the master branch. This can make it harder to keep track of what happened with which commit. An alternative is to use git rebase V2, which will “squash” the changes back into the master branch. A graphical illustration of this is available over at the Git Community Book. Rebasing can make things a bit clearer and tidier in some situations, but may get a bit complicated if there are conflicting changes on master and V2. git rebase can also be used in interactive mode to rearrange commits in more complicated ways.

If you’ve made changes on the master, then realized that you’d rather be working on a branch, you can easily make the switch using git stash:

git stash save "work for bug 123"
git checkout -b bug123branch
git stash pop

git stash save puts all your changes since your last commit into the stash (the “work for bug 123″ label is optional but helpful if you use the stash a lot). save is the default action if you just type git stash. git stash pop pops the most recent set of stashed changes off the stash stack and back onto the working tree. If you have multiple sets of stashed changes, use git stash list to see the stash names, then use git stash pop stash@{1} to apply the stash@{1} set of changes.

You can also use this technique to switch changes between non-master branches. git stash is also useful if you want to merge changes from another branch without committing your current set of changes – for instance, if you get a patch from elsewhere but your own patch isn’t ready to commit yet.

Checking Out Previous States

If you need to start work from an older state of code, you can create a branch that corresponds to a previous state of another branch. Use git reflog show master to show every commit that the master branch has pointed to, then git checkout -b branchX master@{7} to create a branchX that looks like master did after the master@{7} commit, without any of the commits since. Again, you can use any number here.

Working With Remote Branches

A neat Git option if you’re using branches on a remote server is tracking, which sets up a link between a local and a remote branch. This means that your local copy of the remote branch will reflect changes in the remote branch when you use git pull (which does a fetch plus merge) and git push (to share your own changes). Tracking means that you don’t need to specify the name of the remote branch when using these commands. Use

git push -u origin master

to push the “master” branch to the “origin” remote branch and set up tracking. Similarly, use

git checkout -t origin/newthing

to create and check out a “newthing” local branch that tracks “origin/newthing.” This allows you to make changes to a shared branch, then use git push to share your changes.

To list remote branches, use git branch -r. For a more nuanced list, you can use a command like

git branch -a --contains 50f3754

to filter the lists of branches, including remote branches (the -a flag) to those that include commit 5of3754 in their ancestors.

Cherry-picking

Another great Git command is git cherry-pick, which enables you to choose certain commits from the commit list and bring only those across to another branch. First, you’ll need to use git log on the branch with the changes (here, newbranch) to get the SHA of the commit(s) you want:

$ git log --oneline --decorate
4568f02 (HEAD, newbranch) editing file2
feda6bd adding file3
631dbb6 adding file2
49ba7da (master) Test 1

You now want to merge some of these newbranch commits back into master, but not all of them. Let’s say that you want only the file2-related changes – that is, commits 631dbb6 and 4568f02. Switch back to master, then use git cherry-pick:

$ git checkout master
$ git cherry-pick 631dbb6 4568f02
[master d7654a0] adding file2
 0 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 file2
[master a9bf224] editing file2
 1 files changed, 1 insertions(+), 0 deletions(-)
$ git log --oneline --decorate
a9bf224 (HEAD, master) editing file2
d7654a0 adding file2
49ba7da Test 1

master now has those two changes, without the intermediate change to file3. You can now carry on happily on either branch.

Similarly, you can also check to see which changes from a branch are already present on the master:

$ git checkout newbranch; git cherry -v master
- 631dbb65cb7c23aeed51abcbeda6ebf7dcde4de9 adding file2
+ feda6bd20c9e7429166580f9b754ab164f72095a adding file3
- 4568f028544c5f97b5aeed9baed0892505b032ec editing file2

git cherry master compares changes on the current branch to changes on the master, and marks those present on both (the file2 changes) with “-”, and those present only on the current branch (the file3 change) with “+”. The -v option shows the commit messages as well as the file IDs, which is useful if you don’t have a list of SHA IDs in your head.

Git is incredibly flexible and powerful. These are just a few of the insanely useful things you can do with branching. If you can think of something you might want to do, there’s probably a Git command for it. (And if not, you can always consider submitting a patch.) Try out the commands here, and see how much more productive you become.

See Open Source Trends for 2012

Related posts:

  1. Migrate from SVN to Git easily with git-svn
  2. Rewriting History with Git
  3. Getting Started with Mercurial
  4. Vim Undo Tips and Tricks
  5. Using Apache as a File Server with DAV and LDAP

Related Open-Source Packages

Git: See all Git Articles » Get Git Support at OLEX »

Juliet Kemp

Juliet Kemp has been messing around with Linux systems, for financial reward and otherwise, for about a decade. She is also the author of Linux System Administration Recipes: A Problem-Solution Approach (Apress, 2009).

3 Responses to “Git Tutorial: Branching and Merging”

  1. Skatox says:

    Great article, it helped me to understand better some stuff.

Leave a Reply

© 2012 OpenLogic, Inc. | Licensing | Privacy Policy | Terms of Use

Bad Behavior has blocked 2283 access attempts in the last 7 days.