May. 3, 2020

Git Basics


Git was originally created by Linus Torvalds (also the creator of Linux) in 2005 to replace the BitKeeper software and help with development of the Linux kernel. It was obviously designed with this in mind, and works best with source code and text files. Git is maintained independent from the Linux kernel, and is not managed by private companies like GitHub or Gitlab.

Benefits of Using a Version Control System (VCS)

With a VCS, we can easily do the following things:

Decentralization

It’s important to note that git is fundamentally decentralized. There are no requirements for a central server (e.g. GitHub). In fact, patches can be emailed around for collaboration if necessary! This reduces the chances of a server failure causing work to be lost and allows people to work without having to interact with a central server. It also means that you can use it for private projects, even if you never plan to upload them anywhere!

It’s important to note that you still can use centralized services if they are helpful. The decentralized nature of git allows the best of both worlds!

Installation

On MacOS

I would recommend using Homebrew to install the latest version of git.

brew install git

If you already have Xcode or the Xcode tools installed, git will already be installed on your machine. Note that the version Xcode/Xcode tools installs may be out of date!

On Windows

Personally, I’m not a big fan of the git CLI tools available for Windows (though this is more of a personal preference). I usually use the Windows Subsystem for Linux to install git and other helpful command-line software.

If you prefer to use Windows without WSL, (or just don’t want to install a VM for the sole purpose of using git) the following software packages are available:

On Linux/BSDs

How to install on your particular distribution or version depends largely on which package manager (if any) you’re using.

On Ubuntu/Debian:

sudo apt update
sudo apt install -y git

On Fedora/CentOS/RHEL:

sudo dnf upgrade --refresh
sudo dnf install git-all

Basic Usage

An overview of features that you’ll likely use the most. Unfortunately, Git doesn’t have a very intuitive naming scheme for its commands.

Initialize

We can turn pretty much any directory into a Git repository

cd your_project_directory
git init

Stage Changes

Staging is basically picking which changes we want to include in a snapshot.

git add *
# or
git add my-specific-directory
# or
git add my-specific-file.txt

Commit Changes

A commit is basically a “snapshot” of your project at a certain point in time. Even relatively minor changes should be “committed”. Try not to make commits contain too many changes.

git commit -m "My commit message"

Undo/Revert Changes

What if we mess everything up and want to go back? Luckily, git provides tools to help us do this. Be careful with some of these commands as they can delete things permanently.

# Get rid of all changes since last comit (CAREFUL)
git reset
git clean -f

Say we use the git log command to find the specific commit (“snapshot”) we want to revert to. All we have to do is copy the “hash” (string of numbers and letters) that represents that commit and then paste it into the git revert command. Here’s an example where d04c04c is the shortened commit hash.

# Using a commit hash
git revert d04c04c

We don’t have to go copy the commit hash if we know that the commit we want to revert to is 2 commits /before/ the most recent commit. We can use the following syntax for this:

# Using "number of commits backward" (in this case 2)
git revert HEAD~2

If we don’t want to erase all the progress after that commit but we do want to work with that particular “snapshot” of our project, we can create a new “branch”:

# Start a new branch from a commit hash
git checkout -b my_branch_name d04c04c

Tag Commits

Special commits can be tagged. An example of when you might want to do this is for a major change or specific version.

git tag -a "tag_annotation" -m "Tag message"

View Existing Changes

We will probably want to see all the different changes that have been made (along with their commit messages) at some point. This can be very helpful for writing work summaries or even just figuring out what someone else was thinking when they designed something.

The git log command prints out a nice list of all the most recent commits along with their commit messages, the author (and their email), and the timestamp.

# Get a log of recent changes
git log

If we want to see which changes were made for a specific commit (“snapshot”), we can use the git show command.

# See changes for a specific commit (by hash)
git show d04c04c
# or 1 commit before the most recent commit
git show HEAD~1

This can be very helpful for:

Clone a Remote Repository

Say we want to use some code from a remote git server, maybe from GitHub. The git clone command allows us to do this easily. It will also download the entire “database” of changes.

git clone https://git.example.com/reponame

Push Changes

If we’re working with a remote Git server (such as GitHub), we need a way to push all our snapshots to that server. You can think of it like “take my database and push it to the server”.

git push
# or
git push --tags # If you've added any tags, make sure you push them too
# or
git push -u origin master # Specify a remote and a branch

Fetch Changes

There may be times when you want to get the changes from the server without changing anything in your project. You can do this using the fetch command.

git fetch
# or
git fetch --all # Get changes for all branches
# or
git fetch --tags # Get tag changes as well

Pull Changes

When collaborating with others, there will be times when others have made changes and pushed them to the server. To get all these changes you can use the ~pull~ command.

git pull

Note that if multiple people have made different changes, you’ll have to resolve that in a “merge”. Git provides tools to do this.

A Basic Workflow

  1. Clone or Create repository: git clone
  2. Make changes
  3. Stage changes: git add
  4. Commit changes: git commit
  5. Push changes: git push

Summary

Git can be a fantastically helpful tool for managing and contributing to projects. There will be a bit of a learning curve, but with a little practice, the seemingly strange command names will start to make a little more sense. This page isn’t meant to be anything more than an overview of the basics; there are even more powerful tools available within git that are not covered here. The git docs are great resources for discovering the true power of git, and I highly recommend reading through the pages for at least a couple of the commands you use often.

While it may work amazingly well for code and text files, trying to manage a 500 gigabyte directory of GeoTIFFs with stock git will more than likely be an incredibly frustrating experience. As with any tool, it’s important to take into account git’s strengths and weaknesses before using it.