History and differences: git log and git diff
25 min · Beginner
Need help? Ask a tutor on WhatsApp (opens in a new tab)Every commit can be read again later. git log lists the commits, git show opens one of them, and git diff shows changes you have not committed yet. Clear messages make that history easy to read.
Read the history: git log
Commit log is the list of a repository's commits, newest first. git log shows each commit's hash, author, date and message.
Priya's marks-report has four commits. git log lists them, newest first.
git logcommit 5fb99f84d4b1cefe5a2771da2b692fcec097c679 (HEAD -> main)
Author: Priya Sharma <priya@example.com>
Date: Mon Oct 19 10:16:00 2026 +0530
Correct physics marks after re-evaluation
commit 4c28a72b35c4a38ac7de78205f0986704e618691
Author: Priya Sharma <priya@example.com>
Date: Mon Oct 19 10:12:00 2026 +0530
Add English marks
commit 49faf476b1137b27c07c1fd41cdb5dc299aa4a20
Author: Priya Sharma <priya@example.com>
Date: Mon Oct 19 10:08:00 2026 +0530
Add pass mark and README
commit b5bdd9f1f7ebb3d92f3781e8d74d37f2387b5afb
Author: Priya Sharma <priya@example.com>
Date: Mon Oct 19 10:04:00 2026 +0530
Add marks for three subjectsThe author line comes from your user.name and user.email; your ids and dates will differ. A long log opens one page at a time: press Space for the next page and q to leave.
Commit hash: the id of a commit
Commit hash is the unique id of a commit: 40 letters and digits that Git calculates from the commit's content. The first 7 characters, such as 49faf47, are enough to name it.
Long ids are hard to read. git log --oneline shows one line per commit: the short hash and the message. You copy a short hash from here whenever a command needs a commit.
git log --oneline5fb99f8 (HEAD -> main) Correct physics marks after re-evaluation 4c28a72 Add English marks 49faf47 Add pass mark and README b5bdd9f Add marks for three subjects
Add a number to see fewer commits: git log --oneline -2 shows the last two. Add a file name to see only the commits that changed it: git log --oneline -- README.md prints 49faf47 Add pass mark and README.
HEAD: where you are now
HEAD is Git's name for the commit you are on now, usually the newest commit of your branch. HEAD~1 is the commit before it, HEAD~2 the one before that.
In the log, (HEAD -> main) marks the newest commit, 5fb99f8. Counting back from it gives older commits a second name. git show --stat opens one commit and lists only its files.
git show --stat HEAD~1commit 4c28a72b35c4a38ac7de78205f0986704e618691
Author: Priya Sharma <priya@example.com>
Date: Mon Oct 19 10:12:00 2026 +0530
Add English marks
marks.txt | 1 +
1 file changed, 1 insertion(+)git show HEAD~1 opened 4c28a72, one step before HEAD; git show 4c28a72 gives the same result. Without --stat, git show also prints the full diff.
Compare versions: git diff
Diff is the exact list of changes between two versions of a file: lines that start with - were removed and lines that start with + were added.
The college re-checks Priya's chemistry paper: 69 becomes 72. Before committing, she reads her change. git diff and git diff --staged compare different areas.
Example 1 · git diff: a change that is not staged
Runs in: Your terminal
git diffdiff --git a/marks.txt b/marks.txt index c6741c8..fddfc73 100644 --- a/marks.txt +++ b/marks.txt @@ -1,5 +1,5 @@ Maths: 78 Physics: 91 -Chemistry: 69 +Chemistry: 72 English: 88 Pass mark: 35
What this code does
- The
-line is the old version and the+line is the new one; the plain lines around them are unchanged context. a/is the file as staged (here the same as the last commit) andb/is the file in your folder now.@@ -2,7 +2,7 @@gives the line numbers.
Example 2 · After git add: git diff --staged
Runs in: Your terminal
git add marks.txtgit diffgit diff --stageddiff --git a/marks.txt b/marks.txt index c6741c8..fddfc73 100644 --- a/marks.txt +++ b/marks.txt @@ -1,5 +1,5 @@ Maths: 78 Physics: 91 -Chemistry: 69 +Chemistry: 72 English: 88 Pass mark: 35
What this code does
- After
git add, plaingit diffprints nothing: there are no unstaged changes left. The change is not lost. git diff --stagedprints the staged change, so all the output above comes from it.
Example 3 · Commit with a clear message
Runs in: Your terminal
git commit -m "Correct chemistry marks after re-evaluation"git log --oneline -3[main 44c7531] Correct chemistry marks after re-evaluation 1 file changed, 1 insertion(+), 1 deletion(-) 44c7531 (HEAD -> main) Correct chemistry marks after re-evaluation 5fb99f8 Correct physics marks after re-evaluation 4c28a72 Add English marks
What this code does
1 insertion(+), 1 deletion(-)is the changed chemistry line: one line out, one line in.- HEAD moved to the new commit
44c7531; the old HEAD,5fb99f8, is now HEAD~1.
Before every commit, read git diff --staged: it is exactly what you are about to save. git diff HEAD shows staged and unstaged changes together.
Write good commit messages
A message is a note to your future self. Write a short summary of about 50 characters that starts with a verb (Add, Fix, Correct, Remove) and completes "This commit will…". If the reason is not obvious, add a second -m for a body.
- Bad:
update,changes,asdf,final 2 really final - Good:
Add English marks,Correct physics marks after re-evaluation - One change per commit: a fix and a new feature go in two commits
Atomic commits
An atomic commit holds one complete logical change, such as one bug fix or one new feature, and nothing unrelated. Staging lets you split a messy day of edits into several atomic commits.
Priya corrected a mark and also reworded the README in the same sitting. She stages and commits the two changes one after the other, so each commit tells one story. git add <file> picks the files of the first change; the second change waits in the working folder.
- Easy to review: a teammate reads a small, focused diff quickly.
- Safe to undo: if one change turns out wrong, you revert that single commit and keep the rest.
- Easy to search:
git log --onelinereads like a list of what happened.
Conventional Commits: a message format
Conventional Commits is a common format for commit messages: type(scope): short description. The type says what kind of change it is, and the optional scope says which part of the project it touches.
Many teams and open-source projects write messages in this format, so tools and people can scan the history at a glance. Keep the description short, in the imperative ("add", "fix"), and without a full stop.
feat(marks): add English marksfix(marks): correct chemistry after re-evaluationdocs(readme): explain the pass markrefactor(report): simplify the total calculationtest(marks): add tests for the pass markExample 4 · A Conventional Commits message
Runs in: Your terminal
git add README.mdgit commit -m "docs(readme): explain the pass mark"git log --oneline -2[main 8d1f3a2] docs(readme): explain the pass mark 1 file changed, 1 insertion(+) 8d1f3a2 (HEAD -> main) docs(readme): explain the pass mark 44c7531 Correct chemistry marks after re-evaluation
What this code does
docssays the commit changes documentation only, and(readme)names the part of the project.- Only
README.mdwas staged, so the commit is atomic: it holds the README change and nothing else.
Common types: feat (new feature), fix (bug fix), docs (documentation only), refactor (restructure without changing behaviour) and test (add or change tests). Your team's own rule always wins, so read the project's CONTRIBUTING file first.
Next step
Check your understanding
12 quick questions