SovranCode
HomeCourses Git & GitHub Git Project: Messy Repository
This device
Course contentsGit Project: Messy Repository · 41 topics

1. Git Fundamentals

Git IntroductionGit Version ControlGit vs GitHubGit InstallationGit Working TreeGit RepositoryGit CommitGit .gitignoreGit Project: Learning Journal

2. Git History

Git LogGit DiffGit ResetGit RevertGit StashGit Project: Messy Repository

3. Branches & History

Git BranchGit MergeGit Merge ConflictsGit RebaseGit Cherry-PickGit TagsGit Project: Feature Branch

4. Remotes and GitHub

Git RemoteGitHub AuthenticationGitHub RepositoryGitHub ForkGitHub IssuesGitHub PagesGit Project: Two Clone Sync

5. GitHub Collaboration

GitHub Pull RequestsGitHub Code ReviewGit Branching WorkflowGitHub Branch ProtectionGitHub CollaborationGitHub ContributingGit Project: Reviewed Pull Request

6. Automation and Professional Git

GitHub ActionsGit InternalsGit RecoveryGitHub SecurityGit Project: Team Repository CIProject
Learn Git & GitHub40 complete · 1 planned

1. Git Fundamentals

Git IntroductionGit Version ControlGit vs GitHubGit InstallationGit Working TreeGit RepositoryGit CommitGit .gitignoreGit Project: Learning Journal

2. Git History

Git LogGit DiffGit ResetGit RevertGit StashGit Project: Messy Repository

3. Branches & History

Git BranchGit MergeGit Merge ConflictsGit RebaseGit Cherry-PickGit TagsGit Project: Feature Branch

4. Remotes and GitHub

Git RemoteGitHub AuthenticationGitHub RepositoryGitHub ForkGitHub IssuesGitHub PagesGit Project: Two Clone Sync

5. GitHub Collaboration

GitHub Pull RequestsGitHub Code ReviewGit Branching WorkflowGitHub Branch ProtectionGitHub CollaborationGitHub ContributingGit Project: Reviewed Pull Request

6. Automation and Professional Git

GitHub ActionsGit InternalsGit RecoveryGitHub SecurityGit Project: Team Repository CIProject
PREVIOUS LESSONGit Stash
NEXT LESSONGit Branch
2. Git History 110 min

Git Project: Messy Repository

Diagnose a cluttered working tree, recover the intended files, and leave a clean status with an explained history.

UNIT 02 · RECOVER110 MINLOCAL REPOSITORY

Turn mixed staged, unstaged, ignored, untracked, stashed, and badly committed work into a clean repository whose final snapshots and recovery evidence you can defend.

MISSION PARAMETERS
Starting commitsExactly 3
Final main commitsExactly 6
Recovery refRequired
Remote requiredNo
THE INCIDENT

Correct work in the wrong shape

The tip mixes two intentions, the index and working tree disagree, an ignored environment file must remain local, and a debug artifact must disappear.

THE OUTCOME

A six-commit history with proof

You will preserve every wanted line, split the mixed tip, recover unfinished edits, remove noise, and explain each pointer and state transition.

Project brief

You are taking over a small local “response tool” repository after an interrupted work session. Nothing has been pushed, but the repository contains several kinds of state. Your job is not to make status quiet as quickly as possible. Your job is to determine what each state means, preserve the wanted work, and leave an auditable history.

DiagnoseInventory commits, index, working tree, ignored files, stashes, worktrees, and reflog.
PreserveCreate a recovery ref and a named stash before moving history.
RebuildSplit one unpublished mixed commit into two coherent snapshots.
ProveShow clean status, six main commits, no stashes, and a reachable original tip.
PROJECT WORKSPACE

Evidence tracker

Mark a gate complete only after the named command or review proves it. Progress is saved in this browser.

0%0/7 verified
  1. Open gate
  2. Open gate
  3. Open gate
  4. Open gate
  5. Open gate
  6. Open gate
  7. Open gate
Next evidence gate: State inventory

Safety boundary

Disposable repository only

Create a new practice directory. Never run the project’s reset or cleanup steps in SovranCode, your home directory, or valuable work.

No remote

The scenario is explicitly unpublished. Do not add a remote, push, or simulate shared history during this project.

No hard reset

The required recovery uses preservation, stash, restore, and mixed reset. A hard reset fails the safety contract.

Fake local values only

The environment file must contain obvious placeholders. Never use a real token, password, customer record, or private URL.

Stop if the repository root is unexpected

Before every history-changing milestone, run git rev-parse --show-toplevel. If it is not the disposable project you created for this exercise, do not continue.

Required starting scenario

Build or ask an instructor to provide a repository named response-tool-recovery. The exact short IDs will differ, but its history, status, and files must match this contract.

STARTING HISTORY

Three commits on main

* d31f8a2 (HEAD -> main) Mix formatter behavior and release notes
* a82c517 Add text formatter
* 19f0e44 Initialize response tool
STARTING STATUS

Three visible paths

M  src/format.js
 M README.md
?? debug.log

The repository also contains an ignored .env.local with fake values. Normal status omits it; git status --short --ignored shows it with !!. There are no existing stashes, linked worktrees, remotes, or unmerged paths.

File and change contract

Mixed tip commit

d31f8a2 modifies src/format.js to normalize output and adds docs/release-notes.md. Both changes are wanted, but they belong in separate commits.

Staged formatter edit

The index adds explicit handling for blank input in src/format.js. This is wanted and must become its own commit after the tip is split.

Unstaged README edit

The working tree documents formatter usage. This is wanted, but it must remain separate from behavior changes.

Untracked debug log

debug.log is disposable runtime output. It must not appear in a commit or in the final working tree.

Ignored environment file

.env.local contains only fake local values, remains present and ignored, and must never become tracked or stashed with -a.

Recovery evidence

A branch named recovery/original-tip must preserve the original mixed commit for audit after main is rebuilt.

Target repository state

* <new> (HEAD -> main) Document formatter usage
* <new> Handle blank formatter input
* <new> Add release notes
* <new> Normalize formatter output
* a82c517 Add text formatter
* 19f0e44 Initialize response tool

The exact new IDs will differ. The final main branch contains six commits: two original commits followed by four single-purpose commits in the order shown. The recovery branch still points to the original three-commit line.

PRESERVATION GATE

Original tip reachable

The recovery branch still resolves to the original mixed commit and its tree remains inspectable.

git show --stat recovery/original-tip
STATE GATE

No hidden unfinished work

Normal status is clean, only the expected environment path is ignored, and the stash list is empty.

git status --short --ignored
HISTORY GATE

Six coherent snapshots

Main has exactly six commits with four distinct recovery outcomes after the original baseline.

git rev-list --count main

Milestone 1: inventory without changing state

git status --short --ignored
git diff
git diff --cached
git log --oneline --decorate --graph --all
git stash list
git worktree list
git reflog --date=iso -12

Write a state ledger before running any mutating command. For every path, record whether it exists in HEAD, the index, the working tree, or only as ignored/untracked content. For each commit, record its parent, purpose, and whether another ref contains it.

Empty output is evidence only for that command

An empty stash list says nothing about staged files. A clean plain diff says nothing about cached changes. Keep each observation tied to the state it actually compares.

Milestone 2: inspect every change

Use path-limited and full comparisons to prove the scenario contract:

git show --stat HEAD
git show HEAD -- src/format.js
git show HEAD -- docs/release-notes.md
git diff
git diff --cached
git diff HEAD
git check-ignore -v .env.local
git ls-files --error-unmatch .env.local

The final ls-files command should fail because the environment file is not tracked. Record that as expected evidence. Open debug.log only long enough to confirm it is disposable and contains no sensitive information.

Milestone 3: create two preservation points

First preserve the committed tip with a branch. Then package the staged, unstaged, and untracked visible state in a named stash. Do not include ignored files.

git branch recovery/original-tip HEAD
git show --stat recovery/original-tip

git stash push -u -m "recovery: preserve mixed working state"
git stash list
git stash show --patch stash@{0}
git status --short --ignored

After stashing, normal status should be clean and .env.local should remain in place as ignored content. The stash patch should contain the staged formatter edit, README edit, and untracked debug log—never the ignored environment file.

Milestone 4: split the accidental tip

The mixed commit is unpublished and protected by recovery/original-tip. Move main back one commit with mixed reset, leaving the mixed tip’s content in the working tree.

git rev-parse --show-toplevel
git reset --mixed HEAD~1
git status --short
git diff -- src/format.js
git diff -- docs/release-notes.md

Stage and commit the formatter change first, then the release notes. Review the complete cached patch before each commit.

git add src/format.js
git diff --cached
git commit -m "Normalize formatter output"

git add docs/release-notes.md
git diff --cached
git commit -m "Add release notes"
Do not delete the recovery branch yet

It is required evidence that the original commit remains recoverable. Keep it until after the final assessment and any instructor review.

Milestone 5: restore the unfinished work

Apply the named stash without dropping it. The formatter file changed during the history rebuild, so inspect carefully even if Git applies without conflict.

git stash apply stash@{0}
git status --short
git diff
git diff --cached
git diff HEAD

If a conflict occurs, resolve the file to preserve both normalization and blank-input handling. Stage only the resolved formatter behavior. Do not use ours/theirs mechanically, and do not drop the stash while recovery remains unproven.

Milestone 6: classify and commit recovered paths

  1. 01
    Remove runtime noise

    Delete debug.log after confirming it is disposable. Do not add a broad ignore rule merely to hide an unexplained artifact.

  2. 02
    Commit blank-input behavior

    Stage only src/format.js, run cached diff and --check, test the formatter, then commit Handle blank formatter input.

  3. 03
    Commit usage documentation

    Stage only README.md, inspect the patch, then commit Document formatter usage.

  4. 04
    Verify recovered content

    Inspect both new commits and prove normalization, blank handling, release notes, and usage documentation all remain.

  5. 05
    Drop the preserved stash

    Only after the commits and final files prove recovery, drop the exact stash entry and confirm the list is empty.

Milestone 7: audit history and state

git status
git status --short --ignored
git log --oneline --decorate --graph --all
git rev-list --count main
git diff recovery/original-tip..main
git diff recovery/original-tip main --stat
git stash list
git worktree list
git reflog --date=iso -12

Main count

git rev-list --count main prints 6.

Normal status

The working tree and index are clean; no debug log or unexpected untracked file remains.

Ignored status

Only the expected local environment path appears and verbose ignore tracing names the intended rule.

Recovery branch

The original tip is still reachable and visibly diverges from the rebuilt main branch.

Stash and worktrees

The stash list is empty and only the intended primary worktree remains registered.

Reflog

The reset and subsequent commits are explainable; reflog supports the narrative but is not the only preservation mechanism.

Required failure drills

Complete both drills after saving the required final evidence. Use the recovery branch and disposable paths so the assessed main branch can be restored exactly.

DRILL A

Apply on a divergent branch

Create a temporary branch from a82c517, make a conflicting formatter change, and attempt to apply a recreated practice stash. Resolve or abort deliberately, then delete the temporary branch only when clean.

DRILL B

Recover a moved tip

Create a temporary branch, move it with mixed reset, find its previous tip in reflog, and create a recovery ref there. Never use hard reset in this project.

Submission evidence

  • The initial state ledger with HEAD, index, working-tree, untracked, and ignored classifications.
  • The original graph, status, plain diff, cached diff, and ignored-path proof.
  • The verified recovery/original-tip branch and named stash patch.
  • Cached diffs for all four rebuilt/recovered commits.
  • Test output or repeatable manual assertions for normalization and blank-input behavior.
  • The final six-commit graph, clean status, ignored status, empty stash list, worktree list, and reflog excerpt.
  • A short incident report explaining what was wrong, what was preserved, each state transition, and why no shared history was rewritten.
Sanitize evidence

Review terminal paths, usernames, environment values, notifications, and neighboring windows before sharing screenshots. The environment file itself is never part of the submission.

Self-assessment rubric: 25 points

NEEDS REVISION0–19 points

Wanted work, safety evidence, or final-state proof is missing.

SHIP STANDARD20–23 points

The repository is safely recovered and every required state is auditable.

DISTINCTION24–25 points

The recovery is minimal, precise, reproducible, and explained without unsupported claims.

5 · Diagnosis

Complete state ledger, correct diff interpretation, exact commit inspection, and no mutation before inventory.

5 · Preservation

Verified recovery branch, named inspected stash, ignored environment file excluded, and no hard reset.

5 · History repair

Mixed tip split into two coherent commits with complete cached review and accurate messages.

5 · Work recovery

Wanted staged and unstaged edits become separate tested commits; debug output is removed; no content is lost.

5 · Final audit

Six main commits, clean normal state, expected ignored state, empty stash list, valid recovery ref, and clear incident report.

Automatic stop

Any real credential, operation in a valuable repository, hard reset, or unexplained loss requires rebuilding the exercise safely.

Optional extension: compare with a worktree

Create a linked worktree at recovery/original-tip in a sibling directory. Compare the original mixed checkout with final main side by side, then remove the clean linked worktree through Git. This extension must not alter the required main history or delete the recovery branch.

Project checklist

  • I performed the exercise only in the intended disposable repository.
  • I inventoried every state before changing commits, index entries, or files.
  • The original tip and unfinished work had verified preservation points.
  • Main contains six coherent commits in the required order.
  • Wanted code and documentation remain; debug noise is gone; local environment data stays ignored.
  • Final status, graph, stash list, worktree list, diffs, and reflog support my incident report.

Related lessons

  • Git Stash — Preserve mixed working state before you rewrite.
  • Git Reset — Mixed reset is a recovery tool, not a habit.
PREVIOUS LESSONGit Stash
NEXT LESSONGit Branch
ON THIS PAGEGit Project: Messy RepositoryProject briefSafety boundaryRequired starting scenarioFile and change contractTarget repository stateMilestone 1: inventory without changing stateMilestone 2: inspect every changeMilestone 3: create two preservation pointsMilestone 4: split the accidental tipMilestone 5: restore the unfinished workMilestone 6: classify and commit recovered pathsMilestone 7: audit history and stateRequired failure drillsSubmission evidenceSelf-assessment rubric: 25 pointsOptional extension: compare with a worktreeProject checklistRelated lessons
Course contents