Git: remote-tracking branches

Remote-tracking branches is an advanced concept not easily understood by newcomers to the Git world. But you have to deal with them as you soon as you master the Git basics and, of course, if you are planning to work in a team environment. First, let’s make it clear one more time that a branch is nothing more that a reference. A pointer to a commit. Real commits exist only in two places. Locally and remotely. A local branch is a pointer pointing on a specific local commit aka on a commit in the local git repository. The branch pointer represents two and only things: (a) the commit which the initial files of the working directory came from, before you started making changes and (b) the commit that will contain whichever changes from your working directory you decide to “save” just after you save (commit) them.

A remote-tracking branch is just a relation of a local branch to a remote branch. This relation includes mainly information about the status of the remote branch. This information is stored locally. Which means, the remote-tracking branch exists locally. It works like an image of the remote branch that helps us to assess the status of the local branch comparing to the remote. Because it works like an image, the remote-tracking branch cannot be edited locally. It just reflects the status of the remote branch. There is nothing we can do about it, locally. Git automatically updates them when you communicate with the remote branch (e.g when you execute git fetch or git pull and so on). As the Pro Git book suggests, “think of them as bookmarks, to remind you where the branches in your remote repositories were the last time you connected to them”.

When a remote-tracking branch is used ?

(a) When we execute “git status”, is used to compare the local to the remote branch, based on the information that is containen in the remote-tracking branch. Keep in mind that this information may not be updated and so it may not reflect the current situation of the remote branch.

$ git status
# On branch branch1
# Your branch is ahead of 'origin/branch1' by 1 commit.

(b) When we do “git push” or “git pull” without specifying remote or branch, it will use the relation defined by the remote-tracking branch to select the appropriate remote and branch.

Defining a remote-tracking branch can be done by:

(a) git clone – it fetches all remote branches, creating remote-tracking branches as well, but only creates one local branch, master, for you. So when you run git branch -a, you’ll see something like this:

$ git branch -a
* master
remotes/origin/HEAD
remotes/origin/develop
remotes/origin/master

However, when we try to checkout one of these remote branches, git will create the necessery local branch.

(b) git push -u <remote> <branch> If we try to push a local branch to a remote repository without having a remote-tracking branch then we have to specify the remote name and the branch name it will be pushed. If the branch name does not exist in the remote repository, it will be created. But a remote-tracking branch will not be created locally. And that’s because a temporary relation between the local and remote is assumed. To create a remote-tracking branch during the pushing we need to add the “-u” option. This option is a shorthand for “–set-upstream”.

Updating the remote-tracking branch can be done by:

(a) git fetch – it updates the remote-tracking branches by fetching branches and/or tags (collectively, “refs”) from one or more other repositories, along with the objects necessary to complete their histories. (yes, it may be by more than one remotes, but, if not specified, only the default remote is used. You can see the default remote by using “git branch -vv”

(b) git pull – it’s in fact a git fetch followed by a git merge. So, it will merge any pulled commits into the branch you are currently working.

(c) git push – of course, an action that changes the remote repository could not leave untouched the remote-tracking branch

Remove a tracking relationship

git branch –unset-upstream