Undoing changes and fixing history
In these slides we’ll cover:
git restoregit amendgit revertgit reset
git add, it moves to the staging area as “staged.”
git commit -m "...", it gets saved to the repository as “committed.”git restoreSometimes you modify a file and realize you want to throw away those changes completely.
Maybe you experimented with code that didn’t work, or you accidentally deleted important lines.
The git restore command is the modern way to discard changes in your working directory.
It reverts the file back to how it looked in the last commit.
git restoreLet’s say you modified a file called eda.ipynb but want to discard all changes. Here’s how you check the status first:
This command replaces eda.ipynb in your working directory with the version from the last commit. All your modifications disappear permanently, so use this carefully.
You can restore several files at once by listing them:
What if you already ran git add but now want to unstage a file?
You’re not trying to discard the changes—you just want to remove the file from the staging area.
This is like removing items from your shopping cart before checkout. The items (your changes) still exist, but they’re no longer queued for the next commit.
git restore --stagedThe --staged flag tells Git to unstage a file:
After running this, eda.ipynb returns to the “modified” state.
Your changes remain intact in the working directory—they’re just no longer staged.
To unstage everything at once:
This is helpful when you accidentally staged too many files and want to be more selective about what goes into your next commit.
git reset MethodBefore Git 2.23, developers used git reset to unstage files:
This command still works perfectly, and you’ll encounter it in many existing projects.
HEAD refers to your current commit, and this command says “unstage this file, but keep my changes.”
Sometimes you want to both unstage a file and discard the changes. You can do this in two steps:
Sometimes you want to both unstage a file and discard the changes. You can do this in two steps:
# Step 1: Unstage the file
git restore --staged eda.ipynb
# Step 2: Discard the changes
git restore eda.ipynb
Think of it like taking an item out of your shopping cart and then deciding whether to put it back on the shelf or keep looking at it.
Before you discard changes, it’s smart to review what you’re about to lose. Git gives you tools to inspect your modifications.
See exactly what changed in your working directory:
This shows line-by-line differences. If you see something important, you might decide not to undo it.
Undoing changes is powerful, but it can be destructive. Here are some guidelines to work safely.
Always run git status before undoing anything. This shows you exactly what state your files are in and helps you choose the right command.
Use git diff to review changes before discarding them. Once you run git restore, those changes are gone forever—they’re not saved anywhere.
Be extra careful with git restore . because it affects all files at once. Consider restoring files one at a time when you’re learning.
If you’re unsure, you can always make a quick backup copy of your file outside Git before running any restore commands.
You edited slides.qmd by mistake and want to undo everything:
You ran git add . but only wanted to stage app.R, not test.R:
You made many changes across multiple files and want to start over completely:
You modify index.html, styles.css, and app.R. Then you stage everything:
After reviewing, you realize app.R has experimental code that isn’t ready. You want to unstage it:
Amending a commit means modifying the most recent commit you made.
You can change the commit message,
You can add forgotten files,
You can remove files you didn’t mean to include.
Note that:
When you amend, Git doesn’t actually edit the existing commit.
The original commit is discarded and replaced with the amended version.
This works perfectly when you’re working alone or haven’t shared your commits yet.
Imagine you just committed with a message that says "Fix bug" but you want something more descriptive like "Fix bug in slider widget".
Imagine you just committed with a message that says "Fix bug" but you want something more descriptive like "Fix bug in slider widget".
Here’s how you do it.
Another common scenario is forgetting to include a file in your commit. Maybe you fixed a bug across two files but only staged one of them.
Another common scenario is forgetting to include a file in your commit. Maybe you fixed a bug across two files but only staged one of them.
# You made a commit but forgot to include functions.py
git commit -m "Update data cleaning script"
# Realize you forgot functions.py
# Stage the forgotten file
git add functions.py
# Amend the previous commit to include it
git commit --amend --no-editThe --no-edit flag tells Git to keep the same commit message. This is perfect when you only want to add files without changing the message.
You can also add files and change the message at the same time. This gives you complete control over fixing your commit.
You can also add files and change the message at the same time. This gives you complete control over fixing your commit.
Sometimes you accidentally include files that shouldn’t be in a commit. Maybe you staged all changes with git add . and included an image file or temporary notes.
Sometimes you accidentally include files that shouldn’t be in a commit. Maybe you staged all changes with git add . and included an image file or temporary notes.
# You committed but included screenshot.png by mistake
git commit -m "Univariate summary statistics"
# Remove screenshot.png from the staging area
git restore --staged screenshot.png
# Amend the commit without that file
git commit --amend --no-editThe file still exists in your working directory—it just won’t be part of this commit anymore. You can decide later whether to delete it or add it to your .gitignore file.
| Situation | Use Amend | Use New Commit |
|---|---|---|
| Typo in commit message | Yes (if not pushed) | No |
| Forgot one file | Yes (if not pushed) | No |
| Found bug after pushing | No | Yes |
| Additional feature work | No | Yes |
| Working on shared branch | No | Yes |
git commit --amend only works on the most recent commit.
To modify older commits, you would need more advanced techniques like interactive rebase, which is beyond basic Git usage.
Sometimes you accidentally commit the wrong code and need to undo it.
Git offers two main ways to undo commits:
git revertgit resetThey both undo changes, but they work in completely different ways.
git revert creates a new commit that undoes previous work.
git reset rewrites your commit history.
Choosing the wrong command can cause problems, especially when working with others.
git revertgit revertgit revert creates a new commit that undoes the changes from a previous commit.
It’s the safe option because it doesn’t delete or modify existing commits.
Instead, it adds a new commit that reverses the changes.
This approach is perfect when you’ve already pushed your commits to a remote repository and other people might be using them.
You’re not rewriting history; you’re adding to it.
git revert worksSuppose you have a file called dashboard.qmd and you’ve made several commits. Your commit history looks like this:
git revert worksNow you realize the "Add new feature to tab 1" commit (abc123) introduced a problem.
You want to undo it, but you’ve already pushed it to GitHub and your teammate has pulled the changes.
Here’s how you use git revert:
git revert worksAfter running git revert HEAD, Git creates a new commit that undoes the changes from abc123.
Your history now looks like this:
Notice that the original commit (abc123) is still there. The new commit (fed987) simply reverses its changes. This is safe and transparent.
You can also revert commits that aren’t at the top of your history. You just need to specify the commit hash:
If the changes conflict with more recent commits, Git will ask you to resolve the conflicts manually.
You can revert multiple commits at once.
For example, say you want to revert the last 2 commits. Here’s how to do it.
You can revert multiple commits at once.
For example, say you want to revert the last 2 commits. Here’s how to do it.
# Revert the last 2 commits
# This creates 2 separate revert commits
git revert HEAD~2..HEAD
# Or revert without creating commits immediately
# (you'll commit manually after)
git revert --no-commit HEAD~2..HEAD
git commit -m "Revert last two changes"The --no-commit option is useful when you want to revert several commits but create only one revert commit instead of multiple ones.
HEAD: Refers to the tip of your current branch (the latest commit).HEAD~2: Refers to the commit two steps back from the top of your branch...: Specifies a range of commits (from HEAD~2 up to HEAD)A..B, A is exclusive and B is inclusive.git revertUse git revert in these situations:
Revert is the professional choice for team environments. It shows accountability and keeps everyone’s work synchronized.
git resetgit resetgit reset moves your branch pointer to a different commit, effectively removing commits from your history.
Unlike git revert, it doesn’t create new commits.
git reset simply pretends certain commits never happened.
This is powerful but dangerous, especially if you’ve already shared your commits with others.
git reset WorksUsing the same example from before, suppose you want to completely remove the "Add new feature to tab 1" commit as if it never existed:
Your commit history now looks like:
The abc123 commit is gone from your history. This approach rewrites history. The commit no longer exists in your branch’s timeline.
git reset moves your current branch pointer backward to a previous commit.
But unlike a simple undo, reset gives you control over what happens to your changes:
Git offers three different reset modes:
--soft--mixed--hardIf you’ve already pushed the commit you’re resetting, you’ll create a mess:
# You reset and try to push
git reset HEAD~1
git push origin main
# Error: Updates were rejected
# Your local branch is behind the remoteGit refuses to push because you’re trying to rewrite history that others might depend on.
This is why reset should only be used for commits that haven’t been shared yet.
git resetUse git reset in these situations:
Reset is perfect for cleaning up your local work before sharing it with others. It’s like being able to edit your draft before publishing.
git revert
git reset
git revertgit revertgit revertgit resetWhen in doubt, git revert is the safer choice. It might create a longer history, but it won’t cause problems for you or your teammates.
