Some time ago I helped my brother with a couple of assignments for his Object Oriented programming course in the university. I took this chance to also introduce him to the benefits of using a version control system (VCS) for his projects and specifically my system of choice, git.

For his first project we started off simple: one local repository and only commiting to master, just to get the hang of it.

Remotes, branching and merging came later, along with some confusion and questions, both around the concepts themselves and around practical things like pushing commits to a branch etc.

Contents

Why should I use git?

Before I start my attempt to explain commiting and pushing, branches and merging, I will first take a step back and talk briefly about the 2 important benefits you will get by spending investing some time to learn git.

One thing to keep in mind is that although I will be talking about git, everything applies to all VCSs in one way or another.

No more folder-based version control

I still remember when I didn’t know about it.

I would get my project to a state that I was happy with and then I would get an idea to try something new. To avoid messing up what I already had, I would copy my files, put them in a folder with a very descriptive name, such as “backup” and I would start experimenting with my new idea.

This approach is fine (it really isn’t) as long as you don’t get too many new ideas. In my case I’d end up having a bunch of folders with the said descriptive names like “new idea”, “backup”, “backup idea2”, “working”, “working idea” etc. and soon enough the only two things in my mind were:

  1. Why the hell did I use such stupid names
  2. There must be a better way to do this

And there is.

With git you just store your current state and then you are free to experiment with any new ideas you have knowing that you can always revert to a previous state if things don’t work out. Or if you want, you can store these changes in a different branch. And you can always jump back and forth between the different branches. And you can merge together the changes in these branches.

It makes collaboration easy

If having a bunch of folders called “backup X” wasn’t bad enough, imagine using this system in a team project and having 2 times the same folders but with the extra joy of having to merge each other’s changes and keep them in sync.

Of course you can always copy that folder in a usb stick and take it to a teammate, sit down together and waste your time trying to do that and get something that works. (Or you can always zip that folder and email it to them so that it’s only them that waste their time)

Using git, this process becomes as simple as pushing local changes, to a service like gitlab or github have your teammate pull these changes to their PC and merge them with their work taking advantage of git’s merging capabilities or, if that fails, use its built-in conflict resolution mechanism.

Hello world

Your first commit

With that out of the way let’s honor the tradition of starting with a hello world:

mkdir hello_world_git
cd hello_world_git
echo "Hello world!" > hello.txt
git init
git add hello.txt
git commit -m "Add hello world file"

Let’s break it down

  • The first 3 commands are just setting up a directory and creating a file called ‘hello.txt’ with the content “Hello world!”

  • git init Initializes a new git repository in this directory.
    git tracks changes recursively, so this should be on the top level directory of your project.

  • git add hello.txt tells git that this file is ready to be commited to the repository.
    This puts the file and any changes it has up until this point in something called “staging area”.

  • git commit -m "Add hello world file" creates a commit (snapshot) of everything in the staging area with the commit message “Add hello world file”. All commits must have a commit message and you should try to make it meaningful. Your future self or co-workers will thank you for it.

At this point git knows that you have a file called “hello.txt” and will be keeping track of how it changes.

Let’s see this in action:

echo "Hello world from git!" > hello.txt

This command replaced the contents of the “hello.txt” file with “Hello world from git!”. git already realised that something changed and if you run git status you will something like this:

$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   hello.txt

no changes added to commit (use "git add" and/or "git commit -a")

You can see what changed by running git diff:

$ git diff
diff --git a/hello.txt b/hello.txt
index cd08755..3cbc2fe 100644
--- a/hello.txt
+++ b/hello.txt
@@ -1 +1 @@
-Hello world!
+Hello world from git!

To commit your changes you follow the same steps as earlier, i.e: Add to staging aread and then create a commit with a descriptive message:

git add hello.txt
git commit -m "Change hello world message"

Looking back in history

Now that we have 2 commits we can take a look at our history so far. To do that simply run git log and you should see something like this:

$ git log
commit 010d81ee4fa3a8e04de8762516d7061e47a10181 (HEAD -> master)
Author: sakis <[email protected]>
Date:   Sun Nov 18 12:59:34 2018 +0000

    Change hello world message

commit 7c7de2676f819d84f0359de6a2fa851f4a3045c2
Author: sakis <[email protected]>
Date:   Sun Nov 18 12:52:00 2018 +0000

    Add hello world file

Now, if you don’t find this particularly helpful yet and you would prefer to see the actual content changes, you can try running git log -p which will include the output of the git diff for each commit.

Moving on

These commands should be enough to get you started with git and keeping track of your projects.

The next post will be about branches. What they are, how you create and commit to them, how you merge changes there and how you can push your changes to something like gitlab for other people to see.

Below you will find a cheatsheet with the basic commands that were used in this post which I hope will grow in the future.

Cheatsheet

  • git init Initialize a repo
  • git add <filename/path> Add the file or the files in the staging area, ready to be commited.
  • git commit Commit anything that is in the staging area. If you omit -m <message> your default editor will open for you to type your commit message.
  • git log Will show your repo’s history. Add -p to view the diffs.