Lesson 1 of 3 in Investigating

Searching history

Story: The answer is somewhere in the record, Agent. You just have to ask it the right question.

A project that's a few months old can have hundreds of commits. git log lists every one of them, newest first, and somewhere in that list is the one you're looking for: the commit that deleted a file, changed a price, or added a line of code.

This Lesson's options narrow the list down. Like git log itself, they only read: they never change your files or your commits, so they're always free and never count toward Par.

The examples below come from a small café project with six commits by three people:

$ git log --oneline
b8490e6 (HEAD -> main) Stay open until 6
3daf450 Take the pie off the menu
f73f21d Raise the soup price
2632033 Add a pie
28b786f Add the opening hours
b65f139 Add the menu

One file's history: --

Put a path after --, and git log lists only the commits that changed that file:

$ git log --oneline -- hours.txt
b8490e6 (HEAD -> main) Stay open until 6
28b786f Add the opening hours

The -- tells git that what follows is a path, not a branch or a commit. You can often leave it out, but not when the file no longer exists. Say someone deleted specials.txt last week. Git finds no such file, no branch and no commit by that name, so it gives up:

$ git log specials.txt
fatal: ambiguous argument 'specials.txt': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'

git log -- specials.txt searches the history for it anyway. A deleted file's history ends with the commit that deleted it, so that commit comes first in the list, and git show on it prints every line the file had just before it went.

What each commit changed: -p

-p adds each commit's changes to the list, in the same form git show prints them: - before a line that was removed, + before a line that was added.

$ git log -p -- hours.txt
commit b8490e69e457e0dabc4699fca43bf4382e0d022d (HEAD -> main)
Author: You <you@example.com>
Date:   Fri Feb 9 09:15:00 2024 +0000

    Stay open until 6

diff --git a/hours.txt b/hours.txt
index 1bdb726..d0ea741 100644
--- a/hours.txt
+++ b/hours.txt
@@ -1 +1 @@
-Open 9 to 5
+Open 9 to 6

commit 28b786f6dce6822b4a8bb133e49d9a8532c7f0c2
Author: Maya Chen <maya@example.com>
Date:   Mon Feb 5 14:20:00 2024 +0000

    Add the opening hours

diff --git a/hours.txt b/hours.txt
new file mode 100644
index 0000000..1bdb726
--- /dev/null
+++ b/hours.txt
@@ -0,0 +1 @@
+Open 9 to 5

Together with --, that's the whole story of one file, change by change. Read it from the bottom up to see the file grow: Add the opening hours created hours.txt (new file, --- /dev/null) with Open 9 to 5, and Stay open until 6 changed that line.

Who made a commit: --author

--author=<text> keeps only the commits whose author matches. Git looks for the text in the author's name and email, so part of either is enough:

$ git log --oneline --author=Maya
f73f21d Raise the soup price
28b786f Add the opening hours

It's case-sensitive: --author=maya finds Maya only because her email address, maya@example.com, is in lowercase, and --author=MAYA finds nothing. Writing --author Maya, with a space, works too.

When some text appeared or disappeared: -S

-S <text> finds the commits that added or removed a piece of text. Git counts how many times the text appears in each file before and after every commit, and lists the commits where that number changed:

$ git log --oneline -S Pie
3daf450 Take the pie off the menu
2632033 Add a pie

Add a pie added the word, and Take the pie off the menu removed it. Raise the soup price changed the menu in between, but it left the pie alone, so it isn't listed. A commit that only moves the text to another place in the same file, or re-indents its line, doesn't change the count either, so -S skips it too. That makes it good at finding where a piece of text really came from.

When the text has a space in it, put it in quotes: git log -S "Soup 5". -S is often called the pickaxe, because it digs one string out of the whole history.

Putting them together

The options combine, in any order. Paths always go last, after --:

  • git log --oneline -S Pie -- menu.txt: the commits that added or removed Pie in menu.txt.
  • git log -p --author=Leo -- menu.txt: everything Leo changed in the menu.

Marking what you found

Once you've found a commit, you can give it a name with git branch <name> <commit>. That's the git branch you already know, with one more argument: the commit the new branch starts on. Write the commit as its id from the log; the first 7 characters are enough. You stay on the branch you're on, and the Live Graph shows the new label on the commit you found.

A branch on an old commit is a bookmark: easy to come back to, to show a teammate, or to start a fix from.

On your own computer

When the output is longer than your screen, git shows it a page at a time: press Space for the next page and q to stop. You can also limit the list: git log -3 shows only the newest three commits. The Terminal here shows everything at once.

Command What it does
git log -- <path> Lists only the commits that changed that file, even a deleted one.
git log -p Shows what each commit changed, as a diff.
git log --author=<text> Lists only the commits whose author's name or email contains the text.
git log -S <text> Lists only the commits that added or removed the text.
git branch <name> <commit> Creates a branch on that commit. You stay where you are.

New commands

  • git log -p
  • git log -S
  • git log --author
  • git log --

Explainer: Searching the history

project: your repo, you are hereb65f139 Add the menub65f13928b786f Add the opening hours28b786f2632033 Add a pie2632033f73f21d Raise the soup pricef73f21d3daf450 Take the pie off the menu3daf450b8490e6 Stay open until 6b8490e6HEAD → main
The repository at the end of the Explainer.
Graph as text

project: your repo, you are here

  • HEAD → main at b8490e6 "Stay open until 6"

Branches and tags

  • main at b8490e6 "Stay open until 6"

Commits, newest first

  1. b8490e6 "Stay open until 6"; parent 3daf450; refs: HEAD → main
  2. 3daf450 "Take the pie off the menu"; parent f73f21d
  3. f73f21d "Raise the soup price"; parent 2632033
  4. 2632033 "Add a pie"; parent 28b786f
  5. 28b786f "Add the opening hours"; parent b65f139
  6. b65f139 "Add the menu"; no parent

Challenge 1 of 3

Story: A page has gone missing from the timeline, Agent. The record still has every word of it.

The home page links to faq.html, but someone deleted that file. Bring faq.html back exactly as it was just before it was deleted, and commit it.

Unlocks after Branching & Merging.

Terminal

Unlocks after Branching & Merging.

This Lesson can be played once Branching & Merging is complete. Its text and Explainer are open to everyone.