Getting geeky with Git #1. Remotes and upstream branches

Git JavaScript

This entry is part 1 of 11 in the Getting geeky with Git

Version control systems (VCS) are one of the essential tools of every programmer. The most popular one is Git, and therefore it is worth looking into it a bit more. In this article, we look into what is a remote and what the origin keyword means. We also check out what is an upstream branch and how we can benefit from defining it.

 

git xkcd

xkcd.com

 

Git origin

You might have already used the origin keyword when performing various operations on your repository, for example,  .

In some of my examples below I use a repository from the TypeScript Express series

The best way would be to learn by example. Let’s start by pulling a repository:

The above command clones a repository into a directory on our drive. Doing so defines a remote.

Git is a distributed version control system. Although we do most of the operations on a local copy of a repository, Git can also communicate with remotes.

Remotes are repositories other than our local versions. When we   and  , we synchronize our local version of the repository with the remote.

After running   and going into our new directory, we can verify that we have a remote defined.

origin

git@github.com:mwanago/express-typescript.git

So, the origin is an alias to a particular remote repository. Its name is a widely used convention that is set up for us by default.

We could provide a full path to our remote instead of using an alias.

Do we need to use the remote alias?

When running  , we have a few options.

The first one is to be very explicit. Running   synchronizes specifically the master branch.

The second one is to be a little less explicit. We can run   without the name of the branch. To complicate things a bit, the behavior of this command is configurable.

By default,   pushes the current branch to its upstream branch.

What is upstream and how it connects to our local branches

The upstream branch is the branch tracked by our local branch. Putting the above simply, the upstream branch is the remote counterpart of a local branch.

On our repository, there is a branch called postgres. Let’s switch into it.

Branch ‘postgres’ set up to track remote branch ‘postgres’ from ‘origin’.
Switched to a new branch ‘postgres’

master 687ad6e [origin/master] refactor(): use named imports from express
* postgres 4fcd357 [origin/postgres] test(Authentication): test if there is a token in the registration response

In the above output, we see origin/master and origin/postgres. Those two are remote-tracking branches. They act as local references to the state of the remote branches.

Our local branch postgres now tracks a remote branch in the origin remote.

Since our local branch tracks the remote branch, it is referred to as a tracking branch

Creating a brand new repository

To provide a real-world example, let’s create a new repository on GitHub.

GitHub new repository

The interesting part is  . Let’s break down what is happening above.

-u stands for –set-upstream

In a brand new repository, there are no branches at all. Creating our first commit and try to push our local master branch that was created in this process, it might not be enough.

Doing only the above creates the master branch in our remote repository. Unfortunately, it doesn’t connect our local master with it.

* master d55e411 first commit

This might be troublesome! Let’s try to make some changes to README.md and push the changes.

fatal: The current branch master has no upstream branch.
To push the current branch and set the remote as upstream, use git push –set-upstream origin master

As we stated above, by default,   pushes the current branch to its upstream branch. The issue is that we don’t have an upstream branch set up!

It would succeed if we were more explicit because we state where is the branch that we want to push to:

The most straightforward approach to the above issue is to run  instead. It connects our local master through origin/master to the branch in our remote repository, making it an upstream branch.

As you can see, setting up an upstream branch gives us a possibility to be a bit less explicit. We could even run   without the remote, and Git assumes that we want the remote of the current branch. Being as precise as possible when pushing changes might be a good thing, though.

Having upstream branches can be useful when doing other operations such as  .

How setting an upstream branch affects git pull

When we run   we fetch the current state of the remote and merge it to our local repository.

When we run  , there are a few things Git needs to know.

  1. From where should it fetch
    When running  , we indicate that we want to fetch from the origin. If we don’t specify it by running just , the default is the remote associated with the branch we are currently on. To figure out the associated remote, git needs an upstream branch.
  2. What should it fetch
    When we run   we explicitly say that we want to merge the remote branch master into our current branch. Not specifying the branch by running just  means that we want to merge the upstream branch into our current branch.

As you can see above, if we want to omit the arguments of   we need to set up an upstream branch. Doing so without one causes an error.

There is no tracking information for the current branch.
Please specify which branch you want to merge with.
See git-pull(1) for details.

git pull <remote> <branch>

If you wish to set tracking information for this branch you can do so with:

git branch –set-upstream-to=origin/<branch> maste

Summary

The terminology surrounding branches and remotes in Git is vast and can be quite confusing.

Remote is a repository other than our local copy. The origin keyword is an alias to the default remote connected to our local repository.

Since Git is distributed, we maintain local copies of branches. To connect to their remote counterparts, we locally have remote-tracking branches, for example, origin/master. They act as pointers to where the remote master is.

If our local branch tracks a remote branch through a remote-tracking branch, we call it a tracking branch. Its remote equivalent now acts as an upstream to our local branch.

While knowing all of the above might not be crucial to using Git in your everyday work, it gives you a broader perspective. It might also help when dealing with some issues.

Series NavigationGetting geeky with Git #2. Building blocks of a commit >>
Subscribe
Notify of
guest
1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Rail
2 years ago

Thank you!