Arc 1 Quest 05

The Lines of Time

git log, diff, show, .gitignore

Introduction

The doors of the Grand Hall of Archives swing open with a solemn creak. Immense shelves, laden with yellowed scrolls and leather-bound registers, rise up to the vaulted ceiling. The air smells of dust and ancient ink. The Master Archivist awaits you, lantern in hand.

"Apprentice, you've proven your worth. You know how to create archives and record entries. But a true Archivist doesn't just write - they also know how to read the past. Today, I'm entrusting you with an ancient archive. Generations of archivists have recorded the kingdom's history within it. Your mission: explore these lines of time and uncover their secrets."

Retrieve the archive

The Master Archivist hands you an old sealed chest - a complete archive of the kingdom. To open it:

git clone archive.bundle les-lignes-du-temps
cd les-lignes-du-temps

You now have a local copy of the entire archive. Let's see what it contains.

Exploring the history

Git stores every modification as commits - like the pages of a history book. Here are the commands to navigate through time.

View the complete list of commits

git log

Displays all commits, from newest to oldest, with the author, date, and message. The display is paginated - use the arrow keys to navigate and press q to quit.

Compact version (one line per commit)

git log --oneline

Each commit fits on a single line: its hash (unique identifier, abbreviated) and its message. This is the most practical view for getting an overview.

With a graph (branch preview)

git log --oneline --graph

Adds a small ASCII drawing that shows the history's structure. We'll cover branches in detail in a future quest, but it's nice to look at.

Details of a specific commit

git show <hash>

Replace <hash> with the hash (short or long) of a commit. You'll see exactly which files were modified and which lines changed.

Compare two moments in time

git diff <hash1> <hash2>

Shows the differences between two commits. Added lines appear in green (preceded by +), deleted lines in red (preceded by -).

Filter by author

git log --author="Aldric"

Shows only commits made by a given author. The search is partial: "Aldric" will find "Aldric the Scribe".

Search in messages

git log --grep="dragon"

Shows only commits whose message contains the searched word.

Exploration mission

Time to put your new skills into practice. Using the commands above, answer these questions:

  1. How many commits does the archive contain?
    (hint: git log --oneline and count, or use git rev-list --count HEAD)
  2. Which author made the most commits?
  3. Find the commit that mentions "dragon" in its message. What is its hash?
  4. Which file was modified in the 3rd commit?
    (hint: git log --oneline to find the hash, then git show <hash>)
  5. Find the commits with bad messages - "fix", "trucs", "modif", "wip", "oups". Use git show on each one: what should they have said instead?

Take the time to really explore. Use git show on several commits to understand what each one modified. You learn by digging.

.gitignore - Files that should never be archived

While exploring the archive, you may have noticed suspicious files: debug.log, .DS_Store, Thumbs.db, a __pycache__/ folder... These files should never have been archived. They are parasitic files - automatically generated by the system or tools, they pollute the archive without adding any value.

And it gets worse: secret-du-royaume.txt contains confidential information. A secret committed by mistake stays in the history forever (or nearly). That's an important lesson.

The .gitignore file

To avoid these mistakes, Git offers a simple mechanism: a file named .gitignore at the project's root. Each line contains a pattern of files to ignore.

Syntax

# This is a comment

# Ignore a specific file
debug.log
kingdom-secret.txt

# Ignore all files with a given extension
*.log
*.tmp

# Ignore an entire folder (and all its contents)
__pycache__/
node_modules/

# Ignore system files
.DS_Store
Thumbs.db

# Ignore environment files (secrets, passwords)
.env
.env.local

Common patterns to know

Pattern What it ignores
*.logAll .log files
*.tmpAll temporary files
.DS_StoremacOS file (folder metadata)
Thumbs.dbWindows file (image thumbnails)
__pycache__/Python cache
node_modules/Node.js dependencies
.envEnvironment variables (often secrets!)

The website gitignore.io generates .gitignore files tailored to your language and tools. Very handy!

Warning: .gitignore doesn't remove what's already tracked

If a file is already in the history (it has been committed), adding it to .gitignore is not enough. You need to remove it from tracking first:

git rm --cached debug.log

The --cached option means: "remove this file from Git tracking, but don't delete it from disk". The file stays on your machine, but Git will no longer track it.

Commit message best practices

While exploring the archive, you saw two types of messages:

Good messages

"Add the northern creatures registry"

"Fix the swamp dragon entry"

"Update the border map"

"Add journal notes for days 15 to 25"

Bad messages

"fix" - Fix what? Nobody knows.

"stuff" - What stuff? Mystery.

"changes" - Thanks, we figured it was a change.

"wip" - "Work In Progress"... but on what?

"oops" - There was a mistake, but which one?

The golden rules

  1. Start with a verb in the imperative: "Add", "Fix", "Update", "Remove", "Refactor"...
  2. Keep it short: the title should be 50 characters maximum.
  3. Be descriptive: explain the why, not just the what. "Fix tax calculation that rounded to integer" is better than "fix bug".
  4. Write for others (and for your future self): in 6 months, you'll be glad to understand what you did.

Going further: Conventional Commits

There's a popular convention called Conventional Commits that prefixes messages:

feat: Add the search system
fix: Fix the score calculation
docs: Update the installation guide
refactor: Simplify the validation logic

It's not mandatory, but it's increasingly common in professional projects.

Final exercise - Clean up the archive

The Master Archivist entrusts you with one last mission: clean the archives of parasitic files and protect them for the future.

Step 1 - Create a .gitignore

In the les-lignes-du-temps/ folder, create a .gitignore file with at least these patterns:

# Log files
*.log

# System files
.DS_Store
Thumbs.db

# Python cache
__pycache__/

# Secrets (never archive!)
kingdom-secret.txt

Step 2 - Remove parasitic files from tracking

These files are already tracked by Git. The .gitignore alone is not enough - you need to remove them from tracking:

git rm --cached debug.log
git rm --cached .DS_Store
git rm --cached Thumbs.db
git rm --cached -r __pycache__/
git rm --cached kingdom-secret.txt

Step 3 - Commit the cleanup

git add .gitignore
git commit -m "Add .gitignore and remove unwanted files from tracking"

Notice the message: it's clear, descriptive, and starts with a verb.

Step 4 - Verify

Run the verification script to validate your quest:

Bash (Linux / macOS / Git Bash on Windows):

bash verifier.sh

PowerShell (Windows):

.\verifier.ps1

The script checks:

  1. You are inside a Git repository
  2. A .gitignore file exists
  3. The .gitignore contains a pattern for .log files
  4. debug.log is no longer tracked by Git
  5. Your last commit has a descriptive message (at least 10 characters)

The Master Archivist reviews the cleaned archives, nodding with approval.

"Excellent work, apprentice. You now know how to read the lines of time, spot the mistakes of the past, and protect the archives for the future. A good Archivist doesn't just write history - they take care of it. You're ready for what comes next."