Git

Quick overview

Git is a distributed source control management tool. You can use it to track, review, revert changes (and much more) inside a directory.

Cloning

With Git, repositories are distributed. You can have a complete copy on your computer. There can be another copy in GitHub under the mnubo organization, there can also be another copy inside of GitLab under smartobjects if you want. None of them is truly the offcial repository. It’s up to you & your team to make a repository official.

Configuration

Git is configurable in a lot of ways. You will almost never need to configure it but there are some very useful things in there. As soon as you start to use it extensively, you’ll want to configure it so that it follows your workflow.

If you just installed git and you want to commit, you might get this error:

This is your first encounter with the configuration. When you commit, you need to give your name and an email address because every commit will contain that information. Git has both a global configuration and a local configuration. This means you can set defaults in your global configuration but you can have specific configuration on a per-repo basis. For example, my global configuration states that my name is: David Francoeur and that my email is dfrancoeur04@gmail.com but when I work on mnubo’s project, I use my mnubo email address. Here’s how:

git config --global user.email "dfrancoeur04@gmail.com"
git config --global user.name "David Francoeur"
git commit -m "example of global configuration"
git show HEAD # you can see the values of the config in the commit itself

To set a local configuration value, remove the --global from the command line:

git reset HEAD^ # remove the last commit
git config user.email "dfrancoeur@mnubo.com"
git add test
git commit -m "example of local configuration"
git show HEAD # you can see the values of global config being overwritten

There is so much more to the configuration, you probably want to look into it. Here’s my global configuration:

Making and sharing changes

Git uses a two phases commit system. You use git add to put changes on the stage and you use git commit to actually save your file in the repo. This allows for plenty of things and I will explain it further in the rest of the post.

Remotes

In the configuration section, we’ve introduced a commit. This commit exists in out local copy of the code, but nobody else can see it. How do we share it with the rest of the world. You can push it directly to the repository we cloned earlier, but it’s not recommended because you would not allow your peers to review your work (in theory, you should not be able to push directly into the official repository). Here’s how:

git status
git push origin master

What’s in the command above? We tell git to push our changes to origin on a branch master. What’s origin and what’s that branch master?

By default, when we cloned the repository initally, git added a remote called origin, this remote point to the repository we cloned. Remember when I said that git was distributed? Well, git deals with that with remote. Remotes are different places where the code base you are working with is located. You can fetch and push changes to these remotes. You can see the remotes with this command:

Merge Requests

So we know how to push to the repository we cloned. But if we do so, we do not allow out colleagues to review our changes. How do we that? There are different ways to do code review, but at mnubo, we use the GitLab interface to do our reviews. Usually, the whole process is called a Merge Request (MR, it can also be called a Pull Request, PR, in other systems). To do a merge request with GitLab, you fork the official repository and make changes to this copy. Afterward, you open a merge request on GitLab.

When you have forked the repository, you get a clone of it. The url is slightly different the official repository:
gitlab@git-lab1.mtl.mnubo.com:dataviz/git-repo.git vs gitlab@git-lab1.mtl.mnubo.com:dfrancoeur/git-repo.git

We can add this fork to our local repository with git remote but before we do that. Let’s give another name to our origin remote so we make it more official:

git remote rename origin upstream # I use upstream here, but you can use anything

Now let’s add a new remote to point to our fork and push the commit in our fork:

Scenarios

Scenario #1

You open your merge request, and after review, the only thing that stands out is a coworker that asks you to rebase your work. What does that mean?

This happens because as you were working with a copy of your local repository, the official repository was being updated by your peers. New commits were introduced and your version do not contain them. Gitlab will allow you to merge the changes if there are no conflicts but doing so will ruin the history.

You can rebase your changes on top of the changes that happenned in the official repository so you get to keep a clean history.

Show: git rebase upstream/master

Scenario #2

You are working on a feature and the amount of changes is getting quite big, it might be relevant to break the upcoming MR into pieces so your reviewers can understand it. For example, you decided to refactor some piece of code that is used throughout the project. You can open a MR with this small subset of changes, continue working.

Show: git add -p, git rebase -i

Scenario #3

You commit multiple times with different changes. After a while, you realize that you forgot to do something and that some new changes should go inside a commit you’ve already done. You can update the existing commit with a rebase.