Git Tutorial: Fixing Common Mistakes and Undoing Bad Commits
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.
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?
How does git commit --amend fix a bad commit message, and why does it change history?
How can a missing file be added to the previous commit without creating a new commit?
What’s the workflow for moving a commit from master to another branch after committing to the wrong branch?
What do soft, mixed (default), and hard resets do differently?
How can you recover if you ran git reset --hard and deleted something you needed?
When other people already pulled the commits, what’s the safest way to undo changes?
Review Questions
- 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?
- 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?
- 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
Use git checkout <file> to discard local, uncommitted edits and restore the file to the last committed version.
- 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
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
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
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
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
When collaborators already pulled the commits, undo with git revert <hash> to add new “undo” commits without changing existing commit hashes.