Branching is, undoubtedly, one of the best and most important features in Git. If you already understand the basics of Git, you can take your knowledge one step further and get the most out of the popular distributed SCM by using one of its core capabilities: tracking relationships.
Relationships Between Branches
In Git, one branch has nothing to do with any other branch in your repository. From a technical standpoint, this is exactly what you want: clearly and completely separated contexts for different lines of development.
From a semantic point of view, however, it can make great sense to have some kind of connection between two branches; especially when it comes to exchanging data between your local code and a remote repository. A situation like the following is fairly common in many real-world projects:
- You have a local branch that you work with. Let's call it "development."
- To share your work, you publish this work on a remote repository in a new remote branch.
- Since this remote branch should act as a counterpart for your local "development" branch, you name it the same (leaving you with "origin/development").
This is when you explicitly want some kind of connection between the two branches. And this is where tracking relationships come into play.
When preparing for writing my online book on Git, I was surprised by how few Git users knew about tracking relationships, which suggested that this small article explaining the feature might be useful.
With a tracking set up between two branches, Git will inform you when one branch contains new commits that the other one doesn't have:
- If your local branch contains commits that haven't been published/pushed to the remote repository, your local branch is "ahead" of its remote counterpart branch by some commits.
- If your teammates have uploaded commits to the remote, the remote branch will have commits that you haven't downloaded/pulled to your local branch yet. Your local branch is then "behind" its remote counterpart branch.
If you run
git status, Git will then inform you about any discrepancies (Figure 1).
You can then:
- pull from the remote to receive the new commits that you don't yet have in your local repository.
- push the commits to the remote that you haven't yet published and make them available to your teammates.
Your goal should be to create and keep parity between the two branches. Setting up a tracking relationship helps you stay up-to-date about this.
However, keep in mind that the information (about remote branches, remote commits, etc.) that you have in your local repository is only as fresh as the last snapshot that you requested. This is because remote data in Git is updated only when you explicitly request it. It does not happen "automagically" in the background. In practice, this means that you should remember to update remote data by performing a simple
git fetch <remote-name> from time to time.
Defaults for Push and Pull
There's another benefit you get from a tracking connection: It provides Git with defaults for pushing and pulling. Let's see how this can make life easier.
By default, the
git push and
git pull commands look as follows:
$ git push <remote> <branch> $ git pull <remote> <branch>
Both commands expect us to provide a remote repository and a branch as arguments.
With a tracking connection set up, we've defined a "remote counterpart" branch for our local branch. Git then uses this information and lets us use the
pull commands without further arguments.
How to Create a Tracking Relationship
Creating a tracking connection is easy. When creating a new local branch that is based on an existing remote branch, you simply use the
git checkout command with the
--track flag set, for example:
$ git checkout —track origin/development
This command will create a new local branch called "development," which is based on "origin/development." It will directly perform a checkout on this new local branch and (thanks to the
--track option) make sure that a tracking relationship is set up properly.
When you first want to publish your local HEAD branch on a remote, you can use the
-u flag with the
$ git push -u origin development
This command tells Git to publish our current local HEAD branch on the "origin" remote under the name "development." The
-u flag makes sure a tracking connection is set up.
Keeping Track of Trackings
To know which trackings are set up in your project, you can use the
git branch command with the
$ git branch -vv
Figure 2 shows typical results (Git provides the tracking information in the square brackets in Figure 2).
If you're curious how this works on a technical level, Git records your tracking connections in its .git/config file (see Figure 3).
Easy, Cheap, and Useful
Tracking relationships are very easy to set up, very easy to handle, and extremely useful: They save you a lot of typing (and thinking) and thereby prevent mistakes.
Use them whenever you can. They make branching in Git even easier than it already is.
Tobias Günther is part of the team behind Tower, the popular Git client for Mac, and the author of the free online book Learn Version Control with Git: A Step-by-Step Course for the Complete Beginner.