What is Git? Snapshots and your first commit
The interactive lesson needs JavaScript. The text below is the complete lesson.
After this lesson you can
- explain what a commit is, and how parent links connect commits into history understand
- turn a folder into a repository with
git init, make a commit withgit addandgit commit, and see it withgit logapply
Understand: A project with a memory
Have you ever had files called report-final, report-final-2 and report-final-really? Git solves that problem. Git remembers what your project looked like at chosen moments, so you can safely go back, compare and collaborate.
Each such moment is called a commit. A commit is a complete snapshot of every file Git tracks, not just what changed. It also has a message, an author and a time.
When you commit again, the new commit gets a pointer to its parent. That makes history a chain of snapshots.
Notice the direction: arrows point back in time. A commit knows its parents but never its children, because they did not exist when it was made.
The name main is a branch: a label that points to the latest commit on this line of work and moves when you commit on it.
The whole history lives in a hidden folder, .git, inside the project. The project folder with this history is called a repository. Git needs neither the internet nor GitHub to work.
Watch: Your first repository
We are in an empty folder. git init turns it into a repository. The graph is still empty: no commits yet.
$ git init
Now we create a file. It appears in the working tree: the files you see and edit.
$ echo "Hello, Git!" > README.md
Before we continue: what do you think git status says about the file?
$ git status
git add puts a copy of exactly this version in the staging area, also called the index: the draft of the next commit. Notice that the card now also sits in the staging area. The file will be part of the next snapshot.
$ git add README.md
Now we take the snapshot. The message says briefly what the commit does. Look: a commit appears in the graph, and main points to it.
$ git commit -m "Add welcome text"
Finally we read the history. The short code is the start of the commit's ID. Git computes it from the whole commit: content, parent, message, author and time. That is why it is unique in practice.
$ git log --oneline
Tasks
- Turn the folder into a Git repository.
- Create the file
README.mdwith some text in it. - Ask Git for the status of the folder.
- Stage README.md for the next commit.
- Make a commit with a descriptive message.
- Show the history with one line per commit.
Practise: Transfer: two more commits
A new repository with one commit. No demo this time — use what you just saw.
Tasks
- Change
README.mdand save the change in a new commit. - Create a new file
notes.txtand commit it in a commit of its own.
Check yourself: Recall it
What does a commit store?
- Only the lines changed since the previous commit
- A snapshot of the tracked files, plus message, author and parent
- A link to the files in the folder, so later edits are included automatically
Where does Git store the commits you make in a repository?
- On GitHub
- In the
.gitfolder inside the project - In one shared Git database for the whole computer
Why do arrows point from a new commit to its parent, and not the other way?
- A commit cannot change after it is made, and its children did not exist when it was made
- It is just a drawing convention
- Because Git reads history from the oldest commit forwards
Common misconceptions
- “Git and GitHub are the same.” Git is the program that stores history locally. GitHub is one of several services that can host a copy.
- “A commit stores only the changes.” It points to a complete snapshot; changes are computed when you ask for them.
Read more
Git, repositories and hosting
- Git is a program on your own machine. It stores a project's history as a chain of commits.
- A repository is the project folder plus the hidden
.gitfolder, where Git keeps objects (file content, snapshots, commits) and references such asmainandHEAD. - GitHub, GitLab and Codeberg are hosting services. They keep a copy of the repository and add things Git itself does not have: pull requests, issues, access control and web pages. A pull request is a feature of the service, not of Git.
- Everything in this lesson is local.
git init,git add,git commitandgit logwork without a network. Only commands that talk to another repository, such asgit push,git fetchandgit clone, transfer objects and move references somewhere else.
What git init does
$ git init -b main
Initialized empty Git repository in /home/student/project/.git/
- The command creates
.gitin the folder you are in. Your files are not touched. -b mainchooses the name of the first branch.mainis a common convention, not a requirement. Without-b, Git uses theinit.defaultBranchsetting, and older setups givemaster.- A new repository has a branch without commits.
HEADpoints to the namemain, butmaindoes not point to anything yet. That is whygit logfails until you make the first commit:
$ git log
fatal: your current branch 'main' does not have any commits yet
- Do not edit files inside
.gitby hand. Delete.gitand the whole history is gone, while the files in the folder remain.
Be careful where you run
git init. Run it in your home folder by accident and everything below it becomes one big repository.git statusalways tells you whether you are inside a repository or not.
Who is the author?
Every commit stores a name and an email. Git reads them from the settings. If they are missing, Git tries to guess them from your user name and machine name, and refuses to commit if it cannot:
$ git commit -m "Add welcome text"
Author identity unknown
*** Please tell me who you are.
Run
git config --global user.email "you@example.com"
git config --global user.name "Your Name"
to set your account's default identity.
Omit --global to set the identity only in this repository.
A guessed name is rarely right, so set both yourself before your first commit:
git config --global user.name "Kari Nordmann"
git config --global user.email "kari@example.com"
--globalapplies to every repository for your user. Without--global, the setting applies only to the repository you are in.- The name and email are just text in the commit. They are not a login. When you later push to a server, you sign in with an SSH key or a token through a credential helper.
From file to commit, with real output
A new file is untracked until you run git add on it:
$ echo "Hello, Git!" > README.md
$ git status
On branch main
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
README.md
nothing added to commit but untracked files present (use "git add" to track)
After git add, the file is listed under "Changes to be committed":
$ git add README.md
$ git status
On branch main
No commits yet
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: README.md
The commit itself answers with a short receipt:
$ git commit -m "Add welcome text"
[main (root-commit) ae07153] Add welcome text
1 file changed, 1 insertion(+)
create mode 100644 README.md
mainis the branch that moved.root-commitmeans this is the first commit, with no parent.ae07153is the start of the commit's ID. Yours will differ, because the time and the author are part of it.create mode 100644means the file is new and an ordinary, non-executable file.
git log without options shows the full ID, author, date and message:
$ git log
commit ae07153176166626ac1264449d3bf293f131d342
Author: Student <student@example.invalid>
Date: Tue Oct 13 09:10:27 2026 +0200
Add welcome text
In a normal terminal, git log opens a pager when the output is long. Press q to quit.
Snapshots, not lists of changes
- A commit points to a complete snapshot of every tracked file, plus the message, author, time and the ID of its parent.
- Files that did not change are not stored again. The new snapshot points to the same content as before. The history lesson shows this with real objects.
- Diffs are not stored. When you ask for a diff, Git computes it by comparing two snapshots. To save space, Git eventually packs similar objects together in so-called packfiles, where some are stored as differences against others. That is a storage detail you never see. The model you work with is still whole snapshots.
- The ID is a forty-character hash computed from the whole commit. Repositories that use the newer SHA-256 format have 64-character IDs. Change the content, the message or the parent and you get a new ID. That is why a commit cannot be changed afterwards. Commands that "change history" really make new commits.
Common messages and what they mean
| Message | Meaning | Do this |
|---|---|---|
fatal: not a git repository (or any of the parent directories): .git |
You are not inside a repository | Go to the project folder, or run git init |
nothing added to commit but untracked files present |
Nothing is staged | Run git add on the files to include |
nothing to commit, working tree clean |
No changes to tracked files are waiting to be committed | Nothing, every change is committed |
Author identity unknown |
Name or email is missing | Set user.name and user.email with git config |
does not have any commits yet |
You ran git log before the first commit |
Make a commit first |
Further reading
- What is Git? in the Pro Git book
- First-time Git setup
- git init, git commit and git config
Per-Arne's Git Good!