Skip to main content

What is a Git commit?

A commit is a snapshot of files from a repository1.

A commit doesn't have to include all of the files in a repository. It can include just a few files, while leaving some others outside of the commit.

At any point, you can see which files you have in your Working Area and your Staging Area by running this command in the command line:

git status

How to add files to the Staging area

Before using git, you'll have to install it: https://git-scm.com/download. On Mac, it should already be installed and you can "activate" it by running the command xcode-select --install.

When you have files that you'd like to include in the next commit, you can add them to the Staging area.

To add app.py, run this command in the command line:

git add app.py

You can use relative paths to add files as well. Imagine your project file and folder structure looks like this:

project/
| - app.py
| - file.py
| - models/
| - user.py

If you are currently located in the project folder, you could add the user.py file with this command:

git add models/user.py

You can also add whole folders if you'd like to include all their files in the next commit:

git add models

To stage all files in the working tree we can use the following command:

git add --all

Or we can use this shorter version:

git add -A

::: tip In modern Git we can also use git add . instead of git add --all or git add -A.

In older versions of Git, this command had a slightly different meaning, as it wouldn't stage deleted files: only new and modified files. :::

How to remove files from the Staging area

Let's say you have added the app.py and models/user.py file to your commit:

git status

On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)

modified: app.py
modified: models/user.py

Amongst other things, you can see that app.py and models/user.py are in your Staging Area, under "Changes to be committed".

git status also tells you what command you must run to remove a file from the Staging Area:

git reset HEAD models/user.py

That would remove models/user.py from the Staging Area, but it would leave it in the Working Area. That means that you would not lose any changes you've made.

::: warning Note that for any files in your Working Area, Git tells you how to "discard changes in the working directory". This would make you lose changes. Sometimes this is what you want, but be careful.

To discard changes in the working directory, first make sure a file is not in the Staging Area. Then, run this command:

git checkout -- models/user.py

:::

How to make commits

Once you've got all the file changes you'd like to commit in your Staging Area, you can make a commit out of them.

That would store them separately, and clear your Staging Area.

To do so, just type:

git commit

When you do this, a text editor opens up. You can type a message here describing what the commit is, and why this commit was made (i.e. the purpose of the changes).

When you're done writing, just save and quit the text editor. Git will then use what you typed as the commit message.

Good, complete commit messages allow you to easily search through the commits later on, as well as identify which commit did what (in case you want to undo any of them).

Remember that in addition to helping you, it can also help other contributors to your repository. Although at this point you may not have any, in the future you will, and good commit messages will be really important!

::: tip Tracked files When you include a file in your repository, Git starts "tracking" it. It will automatically detect changes in that file. It won't automatically add it to the Staging Area, but it will let you know that you have "modified" files in your Working Area.

When you make a commit and leave "tracked" files uncommitted, internally Git commits will include a reference to the file as it was in the previous commit--unchanged2. This takes up virtually no space (since it's just a reference).

That means that every Git commit is an entire snapshot of all modified and tracked files since the previous commit, even unchanged files. :::

Git Shortcut: commit all tracked files

As we've learned, a file becomes "tracked" when we've added it to a previous commit (and not deleted it from the repository).

In the command line, we can run:

git commit -a

That commits all tracked files, and that means we don't have to git add each of them individually.

Git Shortcut: commit with a short message

When you've added your files to the Staging area, you can do:

git commit -m "Your message here."

This creates a commit with those files and the message "Your message here.".

Oftentimes it's a good idea to write longer, more descriptive commit messages. However some smaller commits, or some commits that lead to a bigger set of changes, can do with a smaller message. This is good for that!

Note that you can chain this with the previous tip, and do:

git commit -am "Your message here."

This adds all tracked files to the Staging area and commits them with a short message, in one single command.

A technicality about commits

In addition to the changes a commit also stores some metadata, such as the author and date of the commit.

An important thing that is stored is the parent commit: each commit knows what the previous commit was, and that is how we can construct a sequence of commits.

Three commits with their parents

Footnotes

  1. How does git store files? (StackOverflow)

  2. Snapshots, Not Differences (git-scm.com)