Monday, 6 April, 2020 UTC


Summary

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.
 
xkcd.com
 
Git origin
You might have already used the origin keyword when performing various operations on your repository, for example, 
git push origin master
.
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:
git clone [email protected]:mwanago/express-typescript.git
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 
push
 and 
pull
, we synchronize our local version of the repository with the remote.
After running 
git clone
 and going into our new directory, we can verify that we have a remote defined.
git remote
origin
git remote get-url origin
[email protected]: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.
git pull [email protected]:mwanago/express-typescript.git master
Do we need to use the remote alias?
When running 
git push
, we have a few options.
The first one is to be very explicit. Running 
git push origin master
 synchronizes specifically the master branch.
The second one is to be a little less explicit. We can run 
git push origin
 without the name of the branch. To complicate things a bit, the behavior of this command is configurable.
By default, 
git push origin
 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.
git checkout postgres
Branch ‘postgres’ set up to track remote branch ‘postgres’ from ‘origin’.
Switched to a new branch ‘postgres’
git branch -vv
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.
The interesting part is 
git push -u origin master
. 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.
git push origin master
Doing only the above creates the master branch in our remote repository. Unfortunately, it doesn’t connect our local master with it.
git branch -vv
* master d55e411 first commit
This might be troublesome! Let’s try to make some changes to README.md and push the changes.
git push origin
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, 
git push origin
 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:
git push origin master
The most straightforward approach to the above issue is to run 
git push -u origin master
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 
git push
 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 
git pull
.
How setting an upstream branch affects git pull
When we run 
git pull,
 we fetch the current state of the remote and merge it to our local repository.
When we run 
git pull
, there are a few things Git needs to know.
  1. From where should it fetch
    When running 
    git pull origin
    , we indicate that we want to fetch from the origin. If we don’t specify it by running just
    git pull
    , 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 
    git pull origin master
     we explicitly say that we want to merge the remote branch master into our current branch. Not specifying the branch by running just 
    git pull origin
    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 
git pull
 we need to set up an upstream branch. Doing so without one causes an error.
git pull
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.
The post Getting geeky with Git #1. Remotes and upstream branches appeared first on Marcin Wanago Blog - JavaScript, both frontend and backend.