Learning The Essential Git Commands

What is actually happening with Git?

Image for post
Image for post

Version control can be quite tricky to understand. A few diagrams and a bit of explanation can help us all!

The step-by-step instructions below refer to using a Mac terminal to use Git.

Prerequisites:

  • Some basic understanding of Git

Terminology

Git: Git is a distributed version-control system for tracking changes in source code during software development

Image for post
Image for post
Moving from the working directory to the repository
Image for post
Image for post
Moving from the repository to the working directory

A walk through some git commands

Create a local repository in your documents

The following commands are written using Terminal on a Mac, and are accessible by a Command⌘-Space key combination and typing “Terminal” into the spotlight window.

Once opened, the following commands can be typed into the black Terminal window:

$ cd ~/documents

$ mkdir git

$ cd git

$ git init

This creates a git repository in a git folder, inside your documents folder.

Getting the status

$ git status

This tells us that there are no commits yet. This makes sense, that our working directory is empty

Image for post
Image for post
The working directory is empty before we have added any files to it!

Adding a README.md

$ touch README.md

This tells terminal we want to add README.md, and then we can use any editor to add the following “This is my README” as the top line (I used vim through vim README.md, but you can of course use your preferred editor).

Image for post
Image for post
My README.md file in Vim

We now add this file to the staging area through the following command:

$ git add README.md

Essentially we are moving README.md to the staging area.

Image for post
Image for post

and by performing a git status we can see that the change is waiting to be committed:

Image for post
Image for post
The output of $ git status

Commit README.md to the local repository

We can then move it to the local repository by comitting.

$ git commit -m “add readme.md”

then a git status tells us we are up to date:

Image for post
Image for post

Making a change to your readme

Use your favourite editor to add the following two lines to your README.md

Image for post
Image for post

And, perhaps as expected, a git status will understand that you have modified the file.

However, it gives you options here:

Image for post
Image for post
The options after changing a file in your repository

You have the choice whether to discard the changes (git checkout), or update the staged files to include this changed to update what will be committed in your next commit (git add).

Discard our changes (git checkout)

We can find the commits by using the command

$ git log

and then we can move to this particular commit through the following (although you will need to use your own hash from the previous step.

$ git checkout — README.md

This (permanently) discards the local changes to README.md

Keep our changes

$ git add README.md

$git commit -m “update readme”

We can now make further changes to our readme, which we then add to the staging area.

Image for post
Image for post
The changes to be made by README.md

$ git add README.md

A git log will display either one or two commits (depending on whether you kept the changes previously. The diagrams and details below will assume that you have kept the changes.

Image for post
Image for post

Move back to the previous commit

We have two commits in the repository.

$ git reset — — soft HEAD~1

This moves the head backwards to a previous commit (you can use the previous commit checksum here as well).

Image for post
Image for post
A visualisation of a soft reset

Doing this it keeps our same changes in our working directory and staging area.

Image for post
Image for post

A git log will only display a single commit.

Image for post
Image for post

It appears that we have “lost” the other commits. However this is NOT true.

Reference logs — git reflog

Git keeps records of where references are updated in a local repository. This has been done above.

If you want to reset to the last commit

$ git reset head@{1}

or you can do a git reset to a particular commit (you will need your own head number to use this, rather than mine)

$ git reset c94f878

A git log now returns the two commits again, and the working directory is unchanged.

Changes to the head with git reset

You can use the following options to get different results according to your intended outcome

  • soft: Does not change the working directory, and resets the head to a specified commit
  • mixed (default): resets the staging area but not the working directory, and resets the head to a specified commit
  • hard: resets the index and the working tree to discard any changes you have made after the commit that you want to move to

Getting information about differences

$ git diff

diff shows changes between the the current working directory and the staging area.

It is also possible to give it two commits and see the differences between the two.

Detached heads

Usually you checkout a branch. But what happens when you checkout a particular commit?

$ git checkout c94f878

By checking out a specific commit, you are not on a branch (partly because your commit could be on multiple branches), and you are at a detached heard.

To commit or make changes then you need to make sure that you do not use this anonymous branch, and instead associate this commit with a new branch.

$ git checkout -b mynewbranch

Merge

Trivially this is easy. However, in the more complex case this deserves a separate blog post.

In any case if the other commit is an ancestor of the current commit nothing is done.

$ git merge master

Cherry-pick

A copy of a commit is made, and is applied to another branch. Sometimes you don’t want to merge a whole branch into another, and only need to pick one or two commits.

So if you are on the branch you want to apply the commit to (from master) you can:

$ git checkout master

then we execute the following (were commit is your target commit):

$ git cherry-pick commit

Rebase

An alternative to a merge is a rebase which combines multiple branches. However, a rebase replays the commits from the current branch onto another, leaving a full linear history. This can be thought of as an automated way of performing several cherry-picks in a row. It is also a good way to rewrite history rather than merging.

Rounding up

git add

stages files that you may have changed in your local directory

$ git add .

git commit

allows you to name (if -m is used) a “commit” as a snapshot in time. This is useful as you can move forwards and backwards through these commits using the hash values that are produced. The head of the current branch is set to the new commit. Changes can be made through changes through amend.

$ git commit -m ‘nameofcommit’

git reset

git reset unstages all files, and is often used to undo changes in your working directory that are yet to be staged.

$ git reset

Want to get in contact? Use Twitter:

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store