The Three States and Areas of Git
In order to fully understand Git, we have view our files how Git does. Envisioning what states your files are in will allow you to quickly pick up on the Git commands. Git views all files in three ways:
- committed
- modified/untracked
- staged
In addition to these three states, Git files live in one of three areas: the working directory, staging area, and the git directory (aka your local repository). Note that a repository is just a fancy name for a folder under version control.
The manipulation among all the above states occur locally, meaning that the changes affect no one else's current repository but yours (we'll discuss remote repositories - or those that are located on a server - soon).
Git views untracked and modified files similarly. Untracked means that the file is new to your Git project. Modified means that the file has been seen before, but has been changed, so is not ready to be snapshotted by Git. Modification of a file occurs in your working directory.
2) Staged and Staging Area
When a file becomes staged, it's taken into the staging area. This is where Git is able to take a snapshot of it and store its current state to your local repository. This area is also known as the Index.
3) Committed and the Git Directory
Committed means that Git has officially taken a snapshot of the files in the staging area, and stored a unique index in the Git directory. The terms snapshotted and committed are very similar. The significance of being committed is that you can now revert back to this project's current state at any time in the future.
The term for the very last snapshot you've made for commitment is known as the HEAD.
It's very important to understand the three states of a file, and the three areas they live in! If you have a good handle on these concepts, the rest of Git fundamentals should be a cinch!
Initializing and Cloning a Git Repository
We must first learn how to initialize a Git repository before learning any Git subcommands.
Initializing your first Git directory
Let's create one a project called fun-project, and move into it by typing the following:
$ mkdir fun-project
$ cd fun-project
Once we're in our directory, we can initialize Git with the init
subcommand.
$ git init
Initialized empty Git repository in /Users/johndoe/test/fun-project/.git/
Great! You just created your first Git repository! By running the init
subcommand, you have created a hidden folder in the current directory called .git. This folder, along with any of its contents, should not be edited or removed.
Cloning an Existing Repository
If you're more interested in someone else's work and want to look at their source code, or just want to download a cool application off of Github, we can use the clone
subcommand.
Here, we're obtaining source code from Heng Li, a renowned bioinformaticist who has contributed heavily on Next Generation Sequence data analysis. We'll pull in wgsim
, an artificial reads generator. Although this project has been retired and is no longer maintained, it's good enough for demonstration purposes. Simply copy the URL on the side (click the clipboard button) and paste it after the clone
subcommand.

This command will download all the project contents into your local hard drive. You may now go ahead and tweak the files or use the program without affecting the main repository online.
Checking the status
One of the most frequent and informative subcommands you'll use is status
. With this, you can check which files are in the staging area (ready to be placed in the next commit), and what is and is not being tracked.
$ git status
On branch master Initial commit nothing to commit (create/copy files and use "git add" to track)
We can see that we're on the branch master, which is the default git branch. We also see that we have nothing to commit (yet). Considering we have not created any files yet, this is true and expected. Let's now create some files and add it to our repository!
Adding and Commiting Files
Let's now talk about adding and committing files. Since this can get wildly abstract and confusing, refer to the figure below!
As any other well-mannered developer would, let's start by creating a README file. This will be to keep track of any notes that you make along the way that we want any users to know.
$ touch README $ git status
On branch master Initial commit Untracked files: (use "git add <file>..." to include in what will be committed) README nothing added to commit but untracked files present (use "git add" to track)
Upon checking the status, you'll see that your README file is untracked. This means that any modifications made to this file won't be noticed by Git. Additionally, untracked files are not in the staging area, so are not ready to be snapshotted by Git. To move the file to the staging area, simply use the add
subcommand.
$ git add README $ git status
On branch master Initial commit Changes to be committed: (use "git rm --cached <file>..." to unstage) new file: README
The README file has now gone from its untracked state to the staging area, ready to be snapshotted. Remember that the fancy word for Git taking a snapshot is committed. We'll use this term henceforth.
Editing tracked files
Note that if we edit our files in the staging area, its edited version will move out of the staging area; the original version that was placed when running add
will still be in the staging area, but the newly updated copy will not. To place the most updated copy, we have to run the add
subcommand again. For example, let's try adding some text in our README.
$ echo 'Hello world! This is my fun project!' > README $ git status
On branch master Initial commit Changes to be committed: (use "git rm --cached <file>..." to unstage) new file: README 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: README
Notice that the new edits made to the README file are not staged for the commit. We see that we must re-add the README file to place the most recent copy into the staging area. So if you have run add
on your files, but decided to make some more edits, make sure to run add
(if you'd like to stage the most recent copy)!
$ git add README $ git status
On branch master Initial commit Changes to be committed: (use "git rm --cached <file>..." to unstage) new file: README
Committing files
The next step is to commit
our file to our Git repository. By committing, Git will take a snapshot of the files in our staging area.
When committing, it's mandatory to add the -m
option, followed by a comment. This comment serves as a brief summary the updates you made to the code. Although you may see it as an inconvenience, a good commit message will pay off when you're trying to rollback changes in the future.
$ git commit -m 'First commit. Including a README file.'
[master (root-commit) df292d0] First commit. Including a README file. 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 README
Great! Now you've committed for the first time. You may now access this specific point in time with the checksum df292d0.
Shortcut to add and commit
One more thing - we can use the -a
option with the commit
subcommand to automatically stage all the files that were modified and deleted. However, new files that are added that you have not told Git about with not be affected.
$ git commit -a -m "Commit message here."
Practice Makes Perfect
Try making your own edits, and use the status
subcommand to continually check up on your files. Ask yourself where they are in the diagram above and try modifying the states for practice.