Once you've made a few commits, Git becomes a time machine. You can list every commit ever made, see exactly which lines changed in each one, and compare your current work with the last commit before you save it.
Reading history is just as important as writing it. Before committing, you check what you changed. When something breaks, you look at what changed recently. When you join a project, you read the log to understand how it grew.
In this lesson you'll use git log, git diff and git show, and tell Git which files it should ignore completely with a .gitignore file.
git log
git log lists commits, newest first. Each entry shows the full hash, the author, the date and the message. Press Space to scroll and Q to quit.
Useful options:
git log --onelineshows one short line per commit.git log -3shows only the last three commits.git log --oneline --graph --alldraws branches as a simple diagram.git log -- index.htmlshows only commits that changed that file.
git diff
git diff shows the exact lines you've changed:
git diffcompares your working files with the staging area: changes you haven't staged yet.git diff --stagedcompares the staging area with the last commit: what will go into the next commit.
In the output, lines starting with - were removed and lines starting with + were added. A changed line appears as one removal and one addition. Checking git diff --staged before every commit is a great habit.
git show
git show displays one commit: its details and the full diff of what it changed.
git show # the latest commit
git show 3f9c2ab # a specific commit, by its hashYou only need the first few characters of a hash, as long as they're unique in the project. Seven is usually enough.
Ignoring files with .gitignore
Some files should never be committed: passwords and API keys, huge downloaded folders like node_modules, and files your computer or editor creates automatically. List them in a file named .gitignore in the project's top folder:
# dependencies
node_modules/
# secrets
.env
# system files
.DS_Store
Thumbs.db
*.logEach line is a pattern: a name, a folder ending in /, or a wildcard such as *.log. Ignored files disappear from git status. Commit the .gitignore itself so everyone on the project shares the same rules.
Filtering the log by author, date and message
On a busy project, git log can list thousands of commits. A few options narrow it down, and you can combine them:
| Command | Shows |
|---|---|
git log --author="Sam" | Commits whose author name or email contains "Sam" |
git log --since="2 weeks ago" | Commits from the last two weeks (--until sets an end date) |
git log --grep="login" | Commits whose message contains "login" |
git log --stat | Each commit plus the files it changed and how many lines |
git log -p | Each commit with its full diff |
For example, git log --oneline --author="Sam" --since="1 month ago" lists Sam's commits from the last month, one per line. Message searches are case-sensitive; add -i to make --grep ignore case.
--stat is a good middle ground when you want to know where a commit made changes without reading every line. -p is what you reach for when you need the detail, and it works with a file name too: git log -p -- index.html shows every change ever made to that file.
One more comparison is worth knowing: git diff HEAD compares your working files with the last commit, staged and unstaged changes together. It answers "what have I changed since my last commit?" in one view.
Git History Syntax
History commands
git log
git log --oneline -5
git log --oneline --graph --all
git diff
git diff --staged
git show <hash>
git rm --cached <file>Git History Summary
git loglists commits;--oneline,-nand--graphmake it easier to read.git diffshows unstaged changes;git diff --stagedshows what you're about to commit.git show <hash>displays one commit and its changes..gitignorelists files and folders Git should never track.- Use
git rm --cachedto stop tracking a file that was committed by mistake.
Git History Examples
Each example shows the code, the output it produces and what each part does.
A short history
git log --oneline9d41e07 (HEAD -> main) Add contact form
6b2a1f3 Style the navigation bar
3f9c2ab Add home pageLine-by-line explanation
- Line 1One line per commit, newest first. HEAD -> main marks where you are now.
What did I change?
After editing a heading in index.html:
git diffdiff --git a/index.html b/index.html
index 4e1c2d0..a7f93b1 100644
--- a/index.html
+++ b/index.html
@@ -5,7 +5,7 @@
<body>
- <h1>My site</h1>
+ <h1>Sam's portfolio</h1>
<p>Welcome!</p>Line-by-line explanation
- Line 1Shows unstaged changes compared with the last commit. In the output, the line starting with - is the old heading and the line starting with + is the new one. Lines with neither are unchanged context.
Ignore a secrets file
echo ".env" >> .gitignore
git status --short
git add .gitignore
git commit -m "Ignore local environment file"?? .gitignore
[main 1c8e5a2] Ignore local environment file
1 file changed, 1 insertion(+)
create mode 100644 .gitignoreLine-by-line explanation
- Line 1Adds the line .env to the .gitignore file.
- Line 2The short status shows .gitignore as new (??). The .env file no longer appears at all.
- Lines 3 to 4Commit the ignore rules so the whole team uses them.
Common Git History Mistakes
Forgetting git diff --staged
git add .
git commit -m "Small fix" # also committed a debug filegit add .
git diff --staged
git commit -m "Small fix"Committing secrets
git add .env
git commit -m "Add config"echo ".env" >> .gitignore
git add .gitignore
git commit -m "Ignore .env"Never commit passwords or API keys. Anyone who can see the repository can see the whole history.
Git History in Real Projects
History in practice
When a website suddenly breaks, a developer's first move is often git log --oneline -10 to see what changed recently, followed by git show on the suspicious commit. Project templates for frameworks like React or Laravel come with a ready-made .gitignore, and GitHub offers templates for every common language when you create a repository.
Git History FAQ
How do I see the history of one file, including when it was renamed?
Run git log --follow -- path/to/file. The --follow option tells Git to keep tracking the file back through renames, so you see commits from before it had its current name. Add -p to see the actual changes in each commit.
How do I quit git log?
git log opens its output in a pager, a scrollable viewer. Press Q to quit and return to the prompt. If you'd rather print everything straight to the terminal, use git --no-pager log -5 or limit the output with -n.
How do I compare two commits or two branches?
Give git diff both names: git diff 3f9c2ab 8e1d4a0 or git diff main feature. Add --stat for a summary of which files changed, or put -- filename at the end to compare a single file. The order matters: the diff shows how to get from the first to the second.
Why is my .gitignore not working?
The most common reason is that the file was already committed: .gitignore only affects untracked files, so run git rm --cached on it first. Other causes are a typo in the pattern or a .gitignore saved in the wrong folder. git check-ignore -v filename shows which rule, if any, matches a file.
What does HEAD~1 mean?
HEAD is the commit you're currently on, and ~1 means "one commit before it". So git show HEAD~1 shows the previous commit and git diff HEAD~2 compares your files with the commit two steps back. It saves you looking up hashes for recent commits.
Git History Exercises
Answer each one and check it instantly. If you get stuck, open the hint before the answer.
Complete the command to show the history with one line per commit.
git
Which command shows the changes that will go into your next commit?
Which line in a .gitignore file ignores every file ending in .log?
In git diff output, what does a line starting with + mean?
Which command shows the exact changes made in one commit?
Git History Quiz
5 questions to check what you learned.
Which key quits the
git logview?- Q
- Esc
- Enter
- X
What does
git show 3f9c2abdisplay?- The files in the folder
- The details and changes of that one commit
- Every commit after it
- The branch it's on
Why commit the .gitignore file itself?
- So everyone working on the project ignores the same files
- Git requires it
- So the ignored files are backed up
- It makes the repository smaller
You committed
secret.txtand then added it to .gitignore. What else must you do?- Nothing, Git will forget it
- Delete the .git folder
- Run git rm --cached secret.txt and commit, and change the secret
- Run git ignore secret.txt
What does a .gitignore line like
*.logdo?- Deletes log files
- Tells Git not to track any file ending in .log
- Commits log files automatically
- Hides logs from your editor