Get AI summaries of any video or article — Sign up free
Git Tutorial: Fixing Common Mistakes and Undoing Bad Commits thumbnail

Git Tutorial: Fixing Common Mistakes and Undoing Bad Commits

Corey Schafer·
5 min read

Based on Corey Schafer's video on YouTube. If you like this content, support the original creators by watching, liking and subscribing to their content.

TL;DR

Use git checkout <file> to discard local, uncommitted edits and restore the file to the last committed version.

Briefing

Undoing mistakes in Git comes down to choosing the right tool for the kind of error—and whether anyone else has already pulled the changes. The most important distinction is between commands that rewrite history (like changing a commit message or moving commits around) and commands that preserve history by adding new “undo” commits. When history rewrite is safe, it keeps the commit graph clean; when it isn’t, Git’s revert workflow avoids breaking other people’s repositories.

The tutorial starts with a simple case: making unwanted edits to a tracked file. After modifying calc.py and confirming the changes with git status and git diff, the fix is to discard local edits using git checkout calc.py. That restores the file to the state from the last commit, returning the working directory to “clean.” From there, the walkthrough moves to commit-level mistakes.

A wrong commit message is corrected immediately with git commit --amend. After creating a commit with an incorrect message (“completed the multiply function” instead of “completed the subtract function”), the amend option opens the commit editor so the message can be replaced without creating a new commit. The tradeoff is explicit: the commit hash changes because the commit content changes, which means Git history is rewritten. The same amend mechanism also works for missing files—creating a .gitignore file, staging it, and then running git commit --amend (without changing the message) folds the new file into the existing last commit. Again, the hash changes, so this approach is only appropriate when the commit hasn’t been pushed or shared.

Next comes the common “wrong branch” problem. Commits accidentally made on master instead of subtract feature are moved by cherry-picking the intended commit onto the correct branch, then resetting master back to the initial commit. cherry-pick creates a new commit on the target branch but leaves the original commit intact on master, so cleanup requires git reset. The tutorial breaks down git reset’s three modes: --soft keeps changes staged, the default mixed reset keeps changes in the working directory, and --hard discards tracked changes entirely. Because --hard leaves untracked files behind, git clean -d -f is used to remove untracked files and directories.

If a hard reset deletes something important, recovery is still possible via git reflog, which records recent references to commits. By checking out the commit hash from before the reset and creating a new branch (e.g., backup), the “lost” work can be preserved before Git garbage-collects unreachable commits.

Finally, when other people already pulled the commits, the safe undo path is git revert. revert creates a new commit that reverses the changes of a specified earlier commit without altering the original commit hashes. The result is an intact history that won’t corrupt collaborators’ checkouts, and git diff between the original and reverted commits shows the changes being undone in the opposite direction.

Cornell Notes

Git undo workflows depend on whether history can be rewritten and whether others have already pulled the changes. For local, uncommitted mistakes, discarding edits with git checkout <file> restores the last committed version. For the last commit, git commit --amend fixes wrong messages or adds missed staged files, but it changes the commit hash and rewrites history—safe only before pushing. For commits on the wrong branch, cherry-pick moves the desired commit to the correct branch, while git reset (soft/mixed/hard) and git clean remove the unintended commit and any leftover files. If history rewrite is unsafe because others pulled, git revert adds new “undo” commits that preserve existing hashes; git reflog helps recover from accidental resets.

What’s the fastest way to undo changes to a file that hasn’t been committed yet?

After editing a tracked file (verified via git status and git diff), run git checkout <file>. In the example, calc.py is modified with gibberish; git checkout calc.py restores calc.py to the exact state from the last commit, and git status returns to clean with no diffs.

How does git commit --amend fix a bad commit message, and why does it change history?

Create the commit with the incorrect message, then run git commit --amend to edit the message without adding a new commit. The commit hash changes because the commit content includes the message; that hash change rewrites history. The tutorial warns this is only appropriate when the commit hasn’t been pushed/shared with others.

How can a missing file be added to the previous commit without creating a new commit?

Stage the missing file (e.g., create .gitignore, then git add .gitignore) and run git commit --amend. The editor opens with the previous commit message; saving and closing without changing the message keeps the message intact while the staged file becomes part of that last commit. The commit hash changes again due to history rewrite.

What’s the workflow for moving a commit from master to another branch after committing to the wrong branch?

Use git cherry-pick <hash> to copy the intended commit onto the correct branch (it creates a new commit there but doesn’t delete the original). Then switch back to master and use git reset to return master to the desired earlier commit (typically the initial commit). The tutorial demonstrates soft/mixed/hard reset and then uses git clean -d -f to remove untracked leftovers after a hard reset.

What do soft, mixed (default), and hard resets do differently?

git reset --soft <hash> moves HEAD back but keeps changes staged in the index. git reset <hash> (mixed default) also moves HEAD back but leaves changes in the working directory (not staged). git reset --hard <hash> makes tracked files match the target commit and discards local tracked changes; untracked files remain, so git clean -d -f is needed to fully clean the workspace.

How can you recover if you ran git reset --hard and deleted something you needed?

Use git reflog to find the commit hash from before the reset. Then git checkout <hash> to inspect the state, and create a new branch (e.g., git branch backup) so the recovered commits aren’t lost. The tutorial notes that detached HEAD work can be garbage-collected later, so branching preserves it.

When other people already pulled the commits, what’s the safest way to undo changes?

Use git revert <hash>. revert creates a new commit that reverses the changes introduced by the earlier commit while leaving the original commits (and their hashes) untouched. This preserves history so collaborators won’t have their repositories corrupted by rewritten hashes.

Review Questions

  1. You made a commit with the wrong message and it hasn’t been pushed yet. Which command fixes it without creating a new commit, and what happens to the commit hash?
  2. You accidentally committed to master instead of subtract feature. What two commands move the work to the correct branch and restore master, and why does cherry-pick require a follow-up reset?
  3. If you already pushed and others pulled, which command undoes the changes without rewriting history, and how does it differ from git reset?

Key Points

  1. 1

    Use git checkout <file> to discard local, uncommitted edits and restore the file to the last committed version.

  2. 2

    Fix the most recent commit message or staged omissions with git commit --amend, but expect the commit hash to change because history is rewritten.

  3. 3

    Only rewrite history (via amend/reset/cherry-pick workflows that alter commit placement) when the commits haven’t been pushed or shared with others.

  4. 4

    Move an accidentally committed change to the correct branch with git cherry-pick <hash>, then clean up the original branch using git reset to the intended commit.

  5. 5

    Choose the right git reset mode: --soft keeps changes staged, mixed keeps them in the working directory, and --hard discards tracked changes; pair --hard with git clean -d -f to remove untracked files.

  6. 6

    Recover from destructive resets using git reflog to locate prior commit references, then check out the hash and create a branch to preserve the recovered state.

  7. 7

    When collaborators already pulled the commits, undo with git revert <hash> to add new “undo” commits without changing existing commit hashes.

Highlights

git commit --amend fixes a wrong commit message without adding a new commit, but it changes the commit hash and rewrites history.
git reset has three behaviors—--soft, mixed (default), and --hard—differing in whether changes remain staged, remain in the working directory, or get discarded.
git clean -d -f is necessary after git reset --hard to remove untracked files and directories that reset doesn’t touch.
git reflog can resurrect work after an accidental hard reset by revealing commit references from before the damage.
git revert undoes earlier commits by creating new reversal commits, preserving original hashes so collaborators aren’t harmed.

Topics

  • Undoing Local Changes
  • Amending Commits
  • Reset Modes
  • Cherry-Picking Between Branches
  • Reverting Shared History

Mentioned