âšď¸ Skipped - page is already crawled
| Filter | Status | Condition | Details |
|---|---|---|---|
| HTTP status | PASS | download_http_code = 200 | HTTP 200 |
| Age cutoff | PASS | download_stamp > now() - 6 MONTH | 0 months ago |
| History drop | PASS | isNull(history_drop_reason) | No drop reason |
| Spam/ban | PASS | fh_dont_index != 1 AND ml_spam_score = 0 | ml_spam_score=0 |
| Canonical | PASS | meta_canonical IS NULL OR = '' OR = src_unparsed | Not set |
| Property | Value |
|---|---|
| URL | https://github.blog/open-source/git/how-to-undo-almost-anything-with-git/ |
| Last Crawled | 2026-04-12 03:54:46 (7 hours ago) |
| First Indexed | 2024-06-04 18:29:31 (1 year ago) |
| HTTP Status Code | 200 |
| Meta Title | How to undo (almost) anything with Git - The GitHub Blog |
| Meta Description | One of the most useful features of any version control system is the ability to "undo" your mistakes. In Git, "undo" can mean many slightly different things. |
| Meta Canonical | null |
| Boilerpipe Text | One of the most useful features of any version control system is the ability to âundoâ your mistakes. In Git, âundoâ can mean many slightly different things.
When you make a new commit, Git stores a snapshot of your repository at that specific moment in time; later, you can use Git to go back to an earlier version of your project.
In this post, Iâm going to take a look at some common scenarios where you might want to âundoâ a change youâve made and the best way to do it using Git.
Undo a âpublicâ change
Scenario:
You just ran
git push
, sending your changes to GitHub, now you realize thereâs a problem with one of those commits. Youâd like to undo that commit.
Undo with:
git revert <SHA>
Whatâs happening:
git revert
will create a new commit thatâs the opposite (or inverse) of the given SHA. If the old commit is âmatterâ, the new commit is âanti-matterââanything removed in the old commit will be added in the new commit and anything added in the old commit will be removed in the new commit.
This is Gitâs safest, most basic âundoâ scenario, because it doesnât
alter
historyâso you can now
git push
the new âinverseâ commit to undo your mistaken commit.
Fix the last commit message
Scenario:
You just typoâd the last commit message, you did
git commit -m "Fxies bug #42"
but before
git push
you realized that really should say âFixes bug #42â.
Undo with:
git commit --amend
or
git commit --amend -m "Fixes bug #42"
Whatâs happening:
git commit --amend
will update and replace the most recent commit with a new commit that combines any staged changes with the contents of the previous commit. With nothing currently staged, this just rewrites the previous commit message.
Undo âlocalâ changes
Scenario:
The cat walked across the keyboard and somehow saved the changes, then crashed the editor. You havenât committed those changes, though. You want to undo everything in that fileâjust go back to the way it looked in the last commit.
Undo with:
git checkout -- <bad filename>
Whatâs happening:
git checkout
alters files in the working directory to a state previously known to Git. You could provide a branch name or specific SHA you want to go back to or, by default, Git will assume you want to checkout
HEAD
, the last commit on the currently-checked-out branch.
Keep in mind: any changes you âundoâ this way are
really
gone. They were never committed, so Git canât help us recover them later. Be sure you know what youâre throwing away here! (Maybe use
git diff
to confirm.)
Reset âlocalâ changes
Scenario:
Youâve made some commits locally (not yet pushed), but everything is terrible, you want to undo the last three commitsâlike they never happened.
Undo with:
git reset <last good SHA>
or
git reset --hard <last good SHA>
Whatâs happening:
git reset
rewinds your repositoryâs history all the way back to the specified SHA. Itâs as if those commits never happened. By default,
git reset
preserves the working directory. The commits are gone, but the
contents
are still on disk. This is the safest option, but often, youâll want to âundoâ the commits
and
the changes in one moveâthatâs what
--hard
does.
Redo after undo âlocalâ
Scenario:
You made some commits, did a
git reset --hard
to âundoâ those changes (see above), and
then
realized: you want those changes back!
Undo with:
git reflog
and
git reset
or
git checkout
Whatâs happening:
git reflog
is an amazing resource for recovering project history. You can recover
almost
anythingâanything youâve committedâvia the reflog.
Youâre probably familiar with the
git log
command, which shows a list of commits.
git reflog
is similar, but instead shows a list of times when
HEAD
changed.
Some caveats:
HEAD
changes
only
.
HEAD
changes when you switch branches, make commits with
git commit
and un-make commits with
git reset
, but
HEAD
does
not
change when you
git checkout -- <bad filename>
(from an earlier scenarioâas mentioned before, those changes were never committed, so the reflog canât help us recover those.
git reflog
doesnât last forever. Git will periodically clean up objects which are âunreachable.â Donât expect to find months-old commits lying around in the reflog forever.
Your
reflog
is yours and yours alone. You canât use
git reflog
to restore another developerâs un-pushed commits.
So⌠how do you use the reflog to âredoâ a previously âundoneâ commit or commits? It depends on what exactly you want to accomplish:
If you want to restore the projectâs history as it was at that moment in time use
git reset --hard <SHA>
If you want to recreate one or more files in your working directory as they were at that moment in time, without altering history use
git checkout <SHA> -- <filename>
If you want to replay
exactly one
of those commits into your repository use
git cherry-pick <SHA>
Once more, with branching
Scenario:
You made some commits, then realized you were checked out on
master
. You wish you could make those commits on a feature branch instead.
Undo with:
git branch feature
,
git reset --hard origin/master
, and
git checkout feature
Whatâs happening:
You may be used to creating new branches with
git checkout -b <name>
âitâs a popular short-cut for creating a new branch and checking it out right awayâbut you donât want to switch branches just yet. Here,
git branch feature
creates a new branch called
feature
pointing at your most recent commit, but leaves you checked out to
master
.
Next,
git reset --hard
rewinds
master
back to
origin/master
, before any of your new commits. Donât worry, though, they are still available on
feature
.
Finally,
git checkout
switches to the new
feature
branch, with all of your recent work intact.
Branch in time saves nine
Scenario:
You started a new branch
feature
based on
master
, but
master
was pretty far behind
origin/master
. Now that
master
branch is in sync with
origin/master
, you wish commits on
feature
were starting
now
, instead of being so far behind.
Undo with:
git checkout feature
and
git rebase master
Whatâs happening:
You could have done this with
git reset
(no
--hard
, intentionally preserving changes on disk) then
git checkout -b <new branch name>
and then re-commit the changes, but that way, youâd lose the commit history. Thereâs a better way.
git rebase master
does a couple of things:
First it locates the common ancestor between your currently-checked-out branch and
master
.
Then it resets the currently-checked-out branch to that ancestor, holding all later commits in a temporary holding area.
Then it advances the currently-checked-out-branch to the end of
master
and replays the commits from the holding area
after
master
âs last commit.
Mass undo/redo
Scenario:
You started this feature in one direction, but mid-way through, you realized another solution was better. Youâve got a dozen or so commits, but you only want some of them. Youâd like the others to just disappear.
Undo with:
git rebase -i <earlier SHA>
Whatâs happening:
-i
puts
rebase
in âinteractive modeâ. It starts off like the rebase discussed above, but before replaying any commits, it pauses and allows you to gently modify each commit as itâs replayed.
rebase -i
will open in your default text editor, with a list of commits being applied, like this:
The first two columns are key: the first is the selected command for the commit identified by the SHA in the second column. By default,
rebase -i
assumes each commit is being applied, via the
pick
command.
To drop a commit, just delete that line in your editor. If you no longer want the bad commits in your project, you can delete lines 1 and 3-4 above.
If you want to preserve the
contents
of the commit but edit the commit
message
, you use the
reword
command. Just replace the word
pick
in the first column with the word
reword
(or just
r
). It can be tempting to rewrite the commit message right now, but that wonât workâ
rebase -i
ignores everything after the SHA column. The text after that is really just to help us remember what
0835fe2
is all about. When youâve finished with
rebase -i
, youâll be prompted for any new commit messages you need to write.
If you want to combine two commits together, you can use the
squash
or
fixup
commands, like this:
squash
and
fixup
combine âupââthe commit with the âcombineâ command will be merged into the commit immediately before it. In this scenario,
0835fe2
and
6943e85
will be combined into one commit, then
38f5e4e
and
af67f82
will be combined together into another.
When you select
squash
, Git will prompt us to give the new, combined commit a new commit message;
fixup
will give the new commit the message from the first commit in the list. Here, you know that
af67f82
is an âooopsâ commit, so youâll just use the commit message from
38f5e4e
as is, but youâll write a new message for the new commit you get from combining
0835fe2
and
6943e85
.
When you save and exit your editor, Git will apply your commits in order from top to bottom. You can alter the order commits apply by changing the order of commits before saving. If youâd wanted, you could have combined
af67f82
with
0835fe2
by arranging things like this:
Fix an earlier commit
Scenario:
You failed to include a file in an earlier commit, itâd be great if that earlier commit could somehow include the stuff you left out. You havenât pushed, yet, but it wasnât the most recent commit, so you canât use
commit --amend
.
Undo with:
git commit --squash <SHA of the earlier commit>
and
git rebase --autosquash -i <even earlier SHA>
Whatâs happening:
git commit --squash
will create a new commit with a commit message like
squash! Earlier commit
. (You could manually create a commit with a message like that, but
commit --squash
saves you some typing.)
You can also use
git commit --fixup
if you donât want to be prompted to write a new commit message for the combined commit. In this scenario, youâd probably use
commit --fixup
, since you just want to use the earlier commitâs commit message during
rebase
.
rebase --autosquash -i
will launch an interactive
rebase
editor, but the editor will open with any
squash!
and
fixup!
commits already paired to the commit target in the list of commits, like so:
When using
--squash
and
--fixup
, you might not remember the SHA of the commit you want to fixâonly that it was one or five commits ago. You might find using Gitâs
^
and
~
operators especially handy.
HEAD^
is one commit before
HEAD
.
HEAD~4
is four commits before
HEAD
â or, altogether, five commits back.
Stop tracking a tracked file
Scenario:
You accidentally added
application.log
to the repository, now every time you run the application, Git reports there are unstaged changes in
application.log
. You put
*.log
in the
.gitignore
file, but itâs still thereâhow do you tell git to to âundoâ tracking changes in this file?
Undo with:
git rm --cached application.log
Whatâs happening:
While
.gitignore
prevents Git from tracking changes to files or even noticing the existence of files itâs never tracked before, once a file has been added and committed, Git will continue noticing changes in that file. Similarly, if youâve used
git add -f
to âforceâ, or override,
.gitignore
, Git will keep tracking changes. You wonât have to use
-f
to add it in the future.
If you want to remove that should-be-ignored file from Gitâs tracking,
git rm --cached
will remove it from tracking but leave the file untouched on disk. Since itâs now being ignored, you wonât see that file in
git status
or accidentally commit changes from that file again.
Thatâs how to undo anything with Git. To learn more about any of the Git commands used here, check out the relevant documentation:
checkout
commit
rebase
reflog
reset
revert
rm
Written by |
| Markdown | [Skip to content](https://github.blog/open-source/git/how-to-undo-almost-anything-with-git/#start-of-content) [Skip to sidebar](https://github.blog/open-source/git/how-to-undo-almost-anything-with-git/#sidebar)
/ [Blog](https://github.blog/)
- [Changelog](https://github.blog/changelog/)
- [Docs](https://docs.github.com/)
- [Customer stories](https://github.com/customer-stories)
[Try GitHub Copilot](https://github.com/features/copilot?utm_source=blog-tap-nav&utm_medium=blog&utm_campaign=universe25) [See what's new](https://github.com/events/universe/recap?utm_source=k2k-blog-tap-nav&utm_medium=blog&utm_campaign=universe25)
- [AI & ML](https://github.blog/ai-and-ml/)
- [AI & ML](https://github.blog/ai-and-ml/)
Learn about artificial intelligence and machine learning across the GitHub ecosystem and the wider industry.
- [Generative AI](https://github.blog/ai-and-ml/generative-ai/)
Learn how to build with generative AI.
- [GitHub Copilot](https://github.blog/ai-and-ml/github-copilot/)
Change how you work with GitHub Copilot.
- [LLMs](https://github.blog/ai-and-ml/llms/)
Everything developers need to know about LLMs.
- [Machine learning](https://github.blog/ai-and-ml/machine-learning/)
Machine learning tips, tricks, and best practices.
- 
[How AI code generation works](https://github.blog/ai-and-ml/generative-ai/how-ai-code-generation-works/)
Explore the capabilities and benefits of AI code generation and how it can improve your developer experience.
Learn more
- [Developer skills](https://github.blog/developer-skills/)
- [Developer skills](https://github.blog/developer-skills/)
Resources for developers to grow in their skills and careers.
- [Application development](https://github.blog/developer-skills/application-development/)
Insights and best practices for building apps.
- [Career growth](https://github.blog/developer-skills/career-growth/)
Tips & tricks to grow as a professional developer.
- [GitHub](https://github.blog/developer-skills/github/)
Improve how you use GitHub at work.
- [GitHub Education](https://github.blog/developer-skills/github-education/)
Learn how to move into your first professional role.
- [Programming languages & frameworks](https://github.blog/developer-skills/programming-languages-and-frameworks/)
Stay current on whatâs new (or new again).
- 
[Get started with GitHub documentation](https://docs.github.com/en/get-started)
Learn how to start building, shipping, and maintaining software with GitHub.
Learn more
- [Engineering](https://github.blog/engineering/)
- [Engineering](https://github.blog/engineering/)
Get an inside look at how weâre building the home for all developers.
- [Architecture & optimization](https://github.blog/engineering/architecture-optimization/)
Discover how we deliver a performant and highly available experience across the GitHub platform.
- [Engineering principles](https://github.blog/engineering/engineering-principles/)
Explore best practices for building software at scale with a majority remote team.
- [Infrastructure](https://github.blog/engineering/infrastructure/)
Get a glimpse at the technology underlying the worldâs leading AI-powered developer platform.
- [Platform security](https://github.blog/engineering/platform-security/)
Learn how we build security into everything we do across the developer lifecycle.
- [User experience](https://github.blog/engineering/user-experience/)
Find out what goes into making GitHub the home for all developers.
- 
[How we use GitHub to be more productive, collaborative, and secure](https://github.blog/engineering/how-we-use-github-to-be-more-productive-collaborative-and-secure/)
Our engineering and security teams do some incredible work. Letâs take a look at how we use GitHub to be more productive, build collaboratively, and shift security left.
Learn more
- [Enterprise software](https://github.blog/enterprise-software/)
- [Enterprise software](https://github.blog/enterprise-software/)
Explore how to write, build, and deploy enterprise software at scale.
- [Automation](https://github.blog/enterprise-software/automation/)
Automating your way to faster and more secure ships.
- [CI/CD](https://github.blog/enterprise-software/ci-cd/)
Guides on continuous integration and delivery.
- [Collaboration](https://github.blog/enterprise-software/collaboration/)
Tips, tools, and tricks to improve developer collaboration.
- [DevOps](https://github.blog/enterprise-software/devops/)
DevOps resources for enterprise engineering teams.
- [DevSecOps](https://github.blog/enterprise-software/devsecops/)
How to integrate security into the SDLC.
- [Governance & compliance](https://github.blog/enterprise-software/governance-and-compliance/)
Ensuring your builds stay clean.
- 
[GitHub recognized as a Leader in the GartnerŽ Magic Quadrant⢠for AI Code Assistants](https://github.com/resources/whitepapers/gartner-magic-quadrant-and-critical-capabilities-for-ai-code-assistants)
Learn why Gartner positioned GitHub as a Leader for the second year in a row.
Learn more
- [News & insights](https://github.blog/news-insights/)
- [News & insights](https://github.blog/news-insights/)
Keep up with whatâs new and notable from inside GitHub.
- [Company news](https://github.blog/news-insights/company-news/)
An inside look at news and product updates from GitHub.
- [Product](https://github.blog/news-insights/product-news/)
The latest on GitHubâs platform, products, and tools.
- [Octoverse](https://github.blog/news-insights/octoverse/)
Insights into the state of open source on GitHub.
- [Policy](https://github.blog/news-insights/policy-news-and-insights/)
The latest policy and regulatory changes in software.
- [Research](https://github.blog/news-insights/research/)
Data-driven insights around the developer ecosystem.
- [The library](https://github.blog/news-insights/the-library/)
Older news and updates from GitHub.
- 
[Unlocking the power of unstructured data with RAG](https://github.blog/ai-and-ml/llms/unlocking-the-power-of-unstructured-data-with-rag/)
Learn how to use retrieval-augmented generation (RAG) to capture more insights.
Learn more
- [Open Source](https://github.blog/open-source/)
- [Open Source](https://github.blog/open-source/)
Everything open source on GitHub.
- [Git](https://github.blog/open-source/git/)
The latest Git updates.
- [Maintainers](https://github.blog/open-source/maintainers/)
Spotlighting open source maintainers.
- [Social impact](https://github.blog/open-source/social-impact/)
How open source is driving positive change.
- [Gaming](https://github.blog/open-source/gaming/)
Explore open source games on GitHub.
- 
[An introduction to innersource](https://resources.github.com/software-development/innersource/)
Organizations worldwide are incorporating open source methodologies into the way they build and ship their own software.
Learn more
- [Security](https://github.blog/security/)
- [Security](https://github.blog/security/)
Stay up to date on everything security.
- [Application security](https://github.blog/security/application-security/)
Application security, explained.
- [Supply chain security](https://github.blog/security/supply-chain-security/)
Demystifying supply chain security.
- [Vulnerability research](https://github.blog/security/vulnerability-research/)
Updates from the GitHub Security Lab.
- [Web application security](https://github.blog/security/web-application-security/)
Helpful tips on securing web applications.
- 
[The enterprise guide to AI-powered DevSecOps](https://resources.github.com/security/the-enterprise-guide-to-ai-powered-devsecops/)
Learn about core challenges in DevSecOps, and how you can start addressing them with AI and automation.
Learn more
## Categories
- [AI & ML](https://github.blog/ai-and-ml/)
- Back
[AI & ML](https://github.blog/ai-and-ml/)
Learn about artificial intelligence and machine learning across the GitHub ecosystem and the wider industry.
- [Generative AI](https://github.blog/ai-and-ml/generative-ai/)
Learn how to build with generative AI.
- [GitHub Copilot](https://github.blog/ai-and-ml/github-copilot/)
Change how you work with GitHub Copilot.
- [LLMs](https://github.blog/ai-and-ml/llms/)
Everything developers need to know about LLMs.
- [Machine learning](https://github.blog/ai-and-ml/machine-learning/)
Machine learning tips, tricks, and best practices.
- [How AI code generation works](https://github.blog/ai-and-ml/generative-ai/how-ai-code-generation-works/)
Explore the capabilities and benefits of AI code generation and how it can improve your developer experience.
[Learn more](https://github.blog/ai-and-ml/generative-ai/how-ai-code-generation-works/)
- [Developer skills](https://github.blog/developer-skills/)
- Back
[Developer skills](https://github.blog/developer-skills/)
Resources for developers to grow in their skills and careers.
- [Application development](https://github.blog/developer-skills/application-development/)
Insights and best practices for building apps.
- [Career growth](https://github.blog/developer-skills/career-growth/)
Tips & tricks to grow as a professional developer.
- [GitHub](https://github.blog/developer-skills/github/)
Improve how you use GitHub at work.
- [GitHub Education](https://github.blog/developer-skills/github-education/)
Learn how to move into your first professional role.
- [Programming languages & frameworks](https://github.blog/developer-skills/programming-languages-and-frameworks/)
Stay current on whatâs new (or new again).
- [Get started with GitHub documentation](https://docs.github.com/en/get-started)
Learn how to start building, shipping, and maintaining software with GitHub.
[Learn more](https://docs.github.com/en/get-started)
- [Engineering](https://github.blog/engineering/)
- Back
[Engineering](https://github.blog/engineering/)
Get an inside look at how weâre building the home for all developers.
- [Architecture & optimization](https://github.blog/engineering/architecture-optimization/)
Discover how we deliver a performant and highly available experience across the GitHub platform.
- [Engineering principles](https://github.blog/engineering/engineering-principles/)
Explore best practices for building software at scale with a majority remote team.
- [Infrastructure](https://github.blog/engineering/infrastructure/)
Get a glimpse at the technology underlying the worldâs leading AI-powered developer platform.
- [Platform security](https://github.blog/engineering/platform-security/)
Learn how we build security into everything we do across the developer lifecycle.
- [User experience](https://github.blog/engineering/user-experience/)
Find out what goes into making GitHub the home for all developers.
- [How we use GitHub to be more productive, collaborative, and secure](https://github.blog/engineering/how-we-use-github-to-be-more-productive-collaborative-and-secure/)
Our engineering and security teams do some incredible work. Letâs take a look at how we use GitHub to be more productive, build collaboratively, and shift security left.
[Learn more](https://github.blog/engineering/how-we-use-github-to-be-more-productive-collaborative-and-secure/)
- [Enterprise software](https://github.blog/enterprise-software/)
- Back
[Enterprise software](https://github.blog/enterprise-software/)
Explore how to write, build, and deploy enterprise software at scale.
- [Automation](https://github.blog/enterprise-software/automation/)
Automating your way to faster and more secure ships.
- [CI/CD](https://github.blog/enterprise-software/ci-cd/)
Guides on continuous integration and delivery.
- [Collaboration](https://github.blog/enterprise-software/collaboration/)
Tips, tools, and tricks to improve developer collaboration.
- [DevOps](https://github.blog/enterprise-software/devops/)
DevOps resources for enterprise engineering teams.
- [DevSecOps](https://github.blog/enterprise-software/devsecops/)
How to integrate security into the SDLC.
- [Governance & compliance](https://github.blog/enterprise-software/governance-and-compliance/)
Ensuring your builds stay clean.
- [GitHub recognized as a Leader in the GartnerŽ Magic Quadrant⢠for AI Code Assistants](https://github.com/resources/whitepapers/gartner-magic-quadrant-and-critical-capabilities-for-ai-code-assistants)
Learn why Gartner positioned GitHub as a Leader for the second year in a row.
[Learn more](https://github.com/resources/whitepapers/gartner-magic-quadrant-and-critical-capabilities-for-ai-code-assistants)
- [News & insights](https://github.blog/news-insights/)
- Back
[News & insights](https://github.blog/news-insights/)
Keep up with whatâs new and notable from inside GitHub.
- [Company news](https://github.blog/news-insights/company-news/)
An inside look at news and product updates from GitHub.
- [Product](https://github.blog/news-insights/product-news/)
The latest on GitHubâs platform, products, and tools.
- [Octoverse](https://github.blog/news-insights/octoverse/)
Insights into the state of open source on GitHub.
- [Policy](https://github.blog/news-insights/policy-news-and-insights/)
The latest policy and regulatory changes in software.
- [Research](https://github.blog/news-insights/research/)
Data-driven insights around the developer ecosystem.
- [The library](https://github.blog/news-insights/the-library/)
Older news and updates from GitHub.
- [Unlocking the power of unstructured data with RAG](https://github.blog/ai-and-ml/llms/unlocking-the-power-of-unstructured-data-with-rag/)
Learn how to use retrieval-augmented generation (RAG) to capture more insights.
[Learn more](https://github.blog/ai-and-ml/llms/unlocking-the-power-of-unstructured-data-with-rag/)
- [Open Source](https://github.blog/open-source/)
- Back
[Open Source](https://github.blog/open-source/)
Everything open source on GitHub.
- [Git](https://github.blog/open-source/git/)
The latest Git updates.
- [Maintainers](https://github.blog/open-source/maintainers/)
Spotlighting open source maintainers.
- [Social impact](https://github.blog/open-source/social-impact/)
How open source is driving positive change.
- [Gaming](https://github.blog/open-source/gaming/)
Explore open source games on GitHub.
- [An introduction to innersource](https://resources.github.com/software-development/innersource/)
Organizations worldwide are incorporating open source methodologies into the way they build and ship their own software.
[Learn more](https://resources.github.com/software-development/innersource/)
- [Security](https://github.blog/security/)
- Back
[Security](https://github.blog/security/)
Stay up to date on everything security.
- [Application security](https://github.blog/security/application-security/)
Application security, explained.
- [Supply chain security](https://github.blog/security/supply-chain-security/)
Demystifying supply chain security.
- [Vulnerability research](https://github.blog/security/vulnerability-research/)
Updates from the GitHub Security Lab.
- [Web application security](https://github.blog/security/web-application-security/)
Helpful tips on securing web applications.
- [The enterprise guide to AI-powered DevSecOps](https://resources.github.com/security/the-enterprise-guide-to-ai-powered-devsecops/)
Learn about core challenges in DevSecOps, and how you can start addressing them with AI and automation.
[Learn more](https://resources.github.com/security/the-enterprise-guide-to-ai-powered-devsecops/)
- [Changelog](https://github.blog/changelog/)
- [Docs](https://docs.github.com/)
- [Customer stories](https://github.com/customer-stories)
[See what's new](https://github.com/events/universe/recap?utm_source=k2k-blog-tap-nav&utm_medium=blog&utm_campaign=universe25) [Try GitHub Copilot](https://github.com/features/copilot?utm_source=blog-tap-nav&utm_medium=blog&utm_campaign=universe25)
[Home](https://github.blog/) / [Open Source](https://github.blog/open-source/) / [Git](https://github.blog/open-source/git/)
# How to undo (almost) anything with Git
One of the most useful features of any version control system is the ability to âundoâ your mistakes. In Git, âundoâ can mean many slightly different things.

[Joshua Wehner](https://github.blog/author/jaw6/ "Posts by Joshua Wehner")¡[@jaw6](https://github.com/jaw6)
June 8, 2015
\|
Updated July 23, 2024
\|
9 minutes
- Share:
One of the most useful features of any version control system is the ability to âundoâ your mistakes. In Git, âundoâ can mean many slightly different things.
When you make a new commit, Git stores a snapshot of your repository at that specific moment in time; later, you can use Git to go back to an earlier version of your project.
In this post, Iâm going to take a look at some common scenarios where you might want to âundoâ a change youâve made and the best way to do it using Git.
## [Undo a âpublicâ change](https://github.blog/open-source/git/how-to-undo-almost-anything-with-git/#undo-a-public-change)
**Scenario:** You just ran `git push`, sending your changes to GitHub, now you realize thereâs a problem with one of those commits. Youâd like to undo that commit.
**Undo with:** `git revert <SHA>`
**Whatâs happening:** `git revert` will create a new commit thatâs the opposite (or inverse) of the given SHA. If the old commit is âmatterâ, the new commit is âanti-matterââanything removed in the old commit will be added in the new commit and anything added in the old commit will be removed in the new commit.
This is Gitâs safest, most basic âundoâ scenario, because it doesnât *alter* historyâso you can now `git push` the new âinverseâ commit to undo your mistaken commit.
## [Fix the last commit message](https://github.blog/open-source/git/how-to-undo-almost-anything-with-git/#fix-the-last-commit-message)
**Scenario:** You just typoâd the last commit message, you did `git commit -m "Fxies bug #42"` but before `git push` you realized that really should say âFixes bug \#42â.
**Undo with:** `git commit --amend` or `git commit --amend -m "Fixes bug #42"`
**Whatâs happening:** `git commit --amend` will update and replace the most recent commit with a new commit that combines any staged changes with the contents of the previous commit. With nothing currently staged, this just rewrites the previous commit message.
## [Undo âlocalâ changes](https://github.blog/open-source/git/how-to-undo-almost-anything-with-git/#undo-local-changes)
**Scenario:** The cat walked across the keyboard and somehow saved the changes, then crashed the editor. You havenât committed those changes, though. You want to undo everything in that fileâjust go back to the way it looked in the last commit.
**Undo with:** `git checkout -- <bad filename>`
**Whatâs happening:** `git checkout` alters files in the working directory to a state previously known to Git. You could provide a branch name or specific SHA you want to go back to or, by default, Git will assume you want to checkout `HEAD`, the last commit on the currently-checked-out branch.
Keep in mind: any changes you âundoâ this way are *really* gone. They were never committed, so Git canât help us recover them later. Be sure you know what youâre throwing away here! (Maybe use `git diff` to confirm.)
## [Reset âlocalâ changes](https://github.blog/open-source/git/how-to-undo-almost-anything-with-git/#reset-local-changes)
**Scenario:** Youâve made some commits locally (not yet pushed), but everything is terrible, you want to undo the last three commitsâlike they never happened.
**Undo with:** `git reset <last good SHA>` or `git reset --hard <last good SHA>`
**Whatâs happening:** `git reset` rewinds your repositoryâs history all the way back to the specified SHA. Itâs as if those commits never happened. By default, `git reset` preserves the working directory. The commits are gone, but the *contents* are still on disk. This is the safest option, but often, youâll want to âundoâ the commits *and* the changes in one moveâthatâs what `--hard` does.
## [Redo after undo âlocalâ](https://github.blog/open-source/git/how-to-undo-almost-anything-with-git/#redo-after-undo-local)
**Scenario:** You made some commits, did a `git reset --hard` to âundoâ those changes (see above), and *then* realized: you want those changes back\!
**Undo with:** `git reflog` and `git reset` or `git checkout`
**Whatâs happening:** `git reflog` is an amazing resource for recovering project history. You can recover *almost* anythingâanything youâve committedâvia the reflog.
Youâre probably familiar with the `git log` command, which shows a list of commits. `git reflog` is similar, but instead shows a list of times when `HEAD` changed.
Some caveats:
- `HEAD` changes *only*.`HEAD` changes when you switch branches, make commits with `git commit` and un-make commits with `git reset`, but `HEAD` does *not* change when you `git checkout -- <bad filename>` (from an earlier scenarioâas mentioned before, those changes were never committed, so the reflog canât help us recover those.
- `git reflog` doesnât last forever. Git will periodically clean up objects which are âunreachable.â Donât expect to find months-old commits lying around in the reflog forever.
- Your `reflog` is yours and yours alone. You canât use `git reflog` to restore another developerâs un-pushed commits.

So⌠how do you use the reflog to âredoâ a previously âundoneâ commit or commits? It depends on what exactly you want to accomplish:
- If you want to restore the projectâs history as it was at that moment in time use `git reset --hard <SHA>`
- If you want to recreate one or more files in your working directory as they were at that moment in time, without altering history use `git checkout <SHA> -- <filename>`
- If you want to replay *exactly one* of those commits into your repository use `git cherry-pick <SHA>`
## [Once more, with branching](https://github.blog/open-source/git/how-to-undo-almost-anything-with-git/#once-more-with-branching)
**Scenario:** You made some commits, then realized you were checked out on `master`. You wish you could make those commits on a feature branch instead.
**Undo with:** `git branch feature`, `git reset --hard origin/master`, and `git checkout feature`
**Whatâs happening:** You may be used to creating new branches with `git checkout -b <name>`âitâs a popular short-cut for creating a new branch and checking it out right awayâbut you donât want to switch branches just yet. Here, `git branch feature` creates a new branch called `feature` pointing at your most recent commit, but leaves you checked out to `master`.
Next, `git reset --hard` rewinds `master` back to `origin/master`, before any of your new commits. Donât worry, though, they are still available on `feature`.
Finally, `git checkout` switches to the new `feature` branch, with all of your recent work intact.
## [Branch in time saves nine](https://github.blog/open-source/git/how-to-undo-almost-anything-with-git/#branch-in-time-saves-nine)
**Scenario:** You started a new branch `feature` based on `master`, but `master` was pretty far behind `origin/master`. Now that `master` branch is in sync with `origin/master`, you wish commits on `feature` were starting *now*, instead of being so far behind.
**Undo with:** `git checkout feature` and `git rebase master`
**Whatâs happening:** You could have done this with `git reset` (no `--hard`, intentionally preserving changes on disk) then `git checkout -b <new branch name>` and then re-commit the changes, but that way, youâd lose the commit history. Thereâs a better way.
`git rebase master` does a couple of things:
- First it locates the common ancestor between your currently-checked-out branch and `master`.
- Then it resets the currently-checked-out branch to that ancestor, holding all later commits in a temporary holding area.
- Then it advances the currently-checked-out-branch to the end of `master` and replays the commits from the holding area *after* `master`âs last commit.
## [Mass undo/redo](https://github.blog/open-source/git/how-to-undo-almost-anything-with-git/#mass-undo-redo)
**Scenario:** You started this feature in one direction, but mid-way through, you realized another solution was better. Youâve got a dozen or so commits, but you only want some of them. Youâd like the others to just disappear.
**Undo with:** `git rebase -i <earlier SHA>`
**Whatâs happening:** `-i` puts `rebase` in âinteractive modeâ. It starts off like the rebase discussed above, but before replaying any commits, it pauses and allows you to gently modify each commit as itâs replayed.
`rebase -i` will open in your default text editor, with a list of commits being applied, like this:

The first two columns are key: the first is the selected command for the commit identified by the SHA in the second column. By default, `rebase -i` assumes each commit is being applied, via the `pick` command.
To drop a commit, just delete that line in your editor. If you no longer want the bad commits in your project, you can delete lines 1 and 3-4 above.
If you want to preserve the *contents* of the commit but edit the commit *message*, you use the `reword` command. Just replace the word `pick` in the first column with the word `reword` (or just `r`). It can be tempting to rewrite the commit message right now, but that wonât workâ`rebase -i` ignores everything after the SHA column. The text after that is really just to help us remember what `0835fe2` is all about. When youâve finished with `rebase -i`, youâll be prompted for any new commit messages you need to write.
If you want to combine two commits together, you can use the `squash` or `fixup` commands, like this:

`squash` and `fixup` combine âupââthe commit with the âcombineâ command will be merged into the commit immediately before it. In this scenario, `0835fe2` and `6943e85` will be combined into one commit, then `38f5e4e` and `af67f82` will be combined together into another.
When you select `squash`, Git will prompt us to give the new, combined commit a new commit message; `fixup` will give the new commit the message from the first commit in the list. Here, you know that `af67f82` is an âooopsâ commit, so youâll just use the commit message from `38f5e4e` as is, but youâll write a new message for the new commit you get from combining `0835fe2` and `6943e85`.
When you save and exit your editor, Git will apply your commits in order from top to bottom. You can alter the order commits apply by changing the order of commits before saving. If youâd wanted, you could have combined `af67f82` with `0835fe2` by arranging things like this:

## [Fix an earlier commit](https://github.blog/open-source/git/how-to-undo-almost-anything-with-git/#fix-an-earlier-commit)
**Scenario:** You failed to include a file in an earlier commit, itâd be great if that earlier commit could somehow include the stuff you left out. You havenât pushed, yet, but it wasnât the most recent commit, so you canât use `commit --amend`.
**Undo with:** `git commit --squash <SHA of the earlier commit>` and `git rebase --autosquash -i <even earlier SHA>`
**Whatâs happening:** `git commit --squash` will create a new commit with a commit message like `squash! Earlier commit`. (You could manually create a commit with a message like that, but `commit --squash` saves you some typing.)
You can also use `git commit --fixup` if you donât want to be prompted to write a new commit message for the combined commit. In this scenario, youâd probably use `commit --fixup`, since you just want to use the earlier commitâs commit message during `rebase`.
`rebase --autosquash -i` will launch an interactive `rebase` editor, but the editor will open with any `squash!` and `fixup!` commits already paired to the commit target in the list of commits, like so:

When using `--squash` and `--fixup`, you might not remember the SHA of the commit you want to fixâonly that it was one or five commits ago. You might find using Gitâs `^` and `~` operators especially handy. `HEAD^` is one commit before `HEAD`. `HEAD~4` is four commits before `HEAD` â or, altogether, five commits back.
## [Stop tracking a tracked file](https://github.blog/open-source/git/how-to-undo-almost-anything-with-git/#stop-tracking-a-tracked-file)
**Scenario:** You accidentally added `application.log` to the repository, now every time you run the application, Git reports there are unstaged changes in `application.log`. You put `*.log` in the `.gitignore` file, but itâs still thereâhow do you tell git to to âundoâ tracking changes in this file?
**Undo with:** `git rm --cached application.log`
**Whatâs happening:** While `.gitignore` prevents Git from tracking changes to files or even noticing the existence of files itâs never tracked before, once a file has been added and committed, Git will continue noticing changes in that file. Similarly, if youâve used `git add -f` to âforceâ, or override, `.gitignore`, Git will keep tracking changes. You wonât have to use `-f` to add it in the future.
If you want to remove that should-be-ignored file from Gitâs tracking, `git rm --cached` will remove it from tracking but leave the file untouched on disk. Since itâs now being ignored, you wonât see that file in `git status` or accidentally commit changes from that file again.
***
Thatâs how to undo anything with Git. To learn more about any of the Git commands used here, check out the relevant documentation:
- [checkout](http://git-scm.com/docs/git-checkout)
- [commit](http://git-scm.com/docs/git-commit)
- [rebase](http://git-scm.com/docs/git-rebase)
- [reflog](http://git-scm.com/docs/git-reflog)
- [reset](http://git-scm.com/docs/git-reset)
- [revert](http://git-scm.com/docs/git-revert)
- [rm](http://git-scm.com/docs/git-rm)
***
## Tags:
- [Git](https://github.blog/tag/git/)
## Written by

### [Joshua Wehner](https://github.blog/author/jaw6/)
[@jaw6](https://github.com/jaw6)
- [Git](https://github.blog/tag/git/)
## More on [Git](https://github.blog/tag/git/)
### [Highlights from Git 2.52](https://github.blog/open-source/git/highlights-from-git-2-52/)
The open source Git project just released Git 2.52. Here is GitHubâs look at some of the most interesting features and changes introduced since last time.
[Taylor Blau](https://github.blog/author/ttaylorr/ "Posts by Taylor Blau")
### [20 Years of Git, 2 days at GitHub HQ: Git Merge 2025 highlights đ](https://github.blog/open-source/git/20-years-of-git-2-days-at-github-hq-git-merge-2025-highlights/)
Git Merge 2025 celebrated 20 years of Git with talks, collaboration, and community. Catch the highlights and recordings.
[Lee Reilly](https://github.blog/author/leereilly/ "Posts by Lee Reilly")
## Related posts

[Maintainers](https://github.blog/open-source/maintainers/)
### [Rethinking open source mentorship in the AI era](https://github.blog/open-source/maintainers/rethinking-open-source-mentorship-in-the-ai-era/)
As contribution volume grows, mentorship signals are harder to read. The 3 Cs framework helps maintainers mentor more strategically⌠without burning out.
[Abigail Cabunoc Mayes](https://github.blog/author/abbycabs/ "Posts by Abigail Cabunoc Mayes")

[Maintainers](https://github.blog/open-source/maintainers/)
### [Investing in the people shaping open source and securing the future together](https://github.blog/security/supply-chain-security/investing-in-the-people-shaping-open-source-and-securing-the-future-together/)
See how GitHub is investing in open source security funding maintainers, partnering with Alpha-Omega, and expanding access to help reduce burden and strengthen software supply chains.
[Kevin Crosby](https://github.blog/author/kevincrosby/ "Posts by Kevin Crosby")

[AI & ML](https://github.blog/ai-and-ml/)
### [How to scan for vulnerabilities with GitHub Security Labâs open source AI-powered framework](https://github.blog/security/how-to-scan-for-vulnerabilities-with-github-security-labs-open-source-ai-powered-framework/)
GitHub Security Lab Taskflow Agent is very effective at finding Auth Bypasses, IDORs, Token Leaks, and other high-impact vulnerabilities.
[Man Yue Mo](https://github.blog/author/mymo/ "Posts by Man Yue Mo") & [Peter StĂśckli](https://github.blog/author/stockli/ "Posts by Peter StĂśckli")
## Explore more from GitHub

### Docs
Everything you need to master GitHub, all in one place.
[Go to Docs](https://docs.github.com/)

### GitHub
Build whatâs next on GitHub, the place for anyone from anywhere to build anything.
[Start building](https://github.com/)

### GitHub Copilot
Donât fly solo. Try 30 days for free.
[Learn more](https://github.blog/ai-and-ml/github-copilot/)

### Enterprise content
Executive insights, curated just for you
[Get started](https://github.com/solutions/executive-insights)
## We do newsletters, too
Discover tips, technical guides, and best practices in our biweekly newsletter just for devs.
Your email address
## Site-wide Links
### Product
- [Features](https://github.com/features)
- [Security](https://github.com/security)
- [Enterprise](https://github.com/enterprise)
- [Customer Stories](https://github.com/customer-stories?type=enterprise)
- [Pricing](https://github.com/pricing)
- [Resources](https://resources.github.com/)
### Platform
- [Developer API](https://developer.github.com/)
- [Partners](https://partner.github.com/)
- [Atom](https://atom.io/)
- [Electron](https://www.electronjs.org/)
- [GitHub Desktop](https://desktop.github.com/)
### Support
- [Docs](https://docs.github.com/)
- [Community Forum](https://github.community/)
- [Training](https://services.github.com/)
- [Status](https://www.githubstatus.com/)
- [Contact](https://support.github.com/)
### Company
- [About](https://github.com/about)
- [Blog](https://github.blog/)
- [Careers](https://github.com/about/careers)
- [Press](https://github.com/about/press)
- [Shop](https://shop.github.com/)
- Š 2026 GitHub, Inc.
- [Terms](https://docs.github.com/en/github/site-policy/github-terms-of-service)
- [Privacy](https://docs.github.com/en/github/site-policy/github-privacy-statement)
- Manage Cookies
- Do not share my personal information
- [GitHub on LinkedIn](https://www.linkedin.com/company/github)
- [GitHub on Instagram](https://www.instagram.com/github/)
- [GitHub on YouTube](https://www.youtube.com/github)
- [GitHub on X](https://twitter.com/github)
- [GitHub on TikTok](https://www.tiktok.com/@github)
- [GitHub on Twitch](https://www.twitch.tv/github)
- [GitHubâs organization on GitHub](https://github.com/github) |
| Readable Markdown | One of the most useful features of any version control system is the ability to âundoâ your mistakes. In Git, âundoâ can mean many slightly different things.
When you make a new commit, Git stores a snapshot of your repository at that specific moment in time; later, you can use Git to go back to an earlier version of your project.
In this post, Iâm going to take a look at some common scenarios where you might want to âundoâ a change youâve made and the best way to do it using Git.
## [Undo a âpublicâ change](https://github.blog/open-source/git/how-to-undo-almost-anything-with-git/#undo-a-public-change)
**Scenario:** You just ran `git push`, sending your changes to GitHub, now you realize thereâs a problem with one of those commits. Youâd like to undo that commit.
**Undo with:** `git revert <SHA>`
**Whatâs happening:** `git revert` will create a new commit thatâs the opposite (or inverse) of the given SHA. If the old commit is âmatterâ, the new commit is âanti-matterââanything removed in the old commit will be added in the new commit and anything added in the old commit will be removed in the new commit.
This is Gitâs safest, most basic âundoâ scenario, because it doesnât *alter* historyâso you can now `git push` the new âinverseâ commit to undo your mistaken commit.
## [Fix the last commit message](https://github.blog/open-source/git/how-to-undo-almost-anything-with-git/#fix-the-last-commit-message)
**Scenario:** You just typoâd the last commit message, you did `git commit -m "Fxies bug #42"` but before `git push` you realized that really should say âFixes bug \#42â.
**Undo with:** `git commit --amend` or `git commit --amend -m "Fixes bug #42"`
**Whatâs happening:** `git commit --amend` will update and replace the most recent commit with a new commit that combines any staged changes with the contents of the previous commit. With nothing currently staged, this just rewrites the previous commit message.
## [Undo âlocalâ changes](https://github.blog/open-source/git/how-to-undo-almost-anything-with-git/#undo-local-changes)
**Scenario:** The cat walked across the keyboard and somehow saved the changes, then crashed the editor. You havenât committed those changes, though. You want to undo everything in that fileâjust go back to the way it looked in the last commit.
**Undo with:** `git checkout -- <bad filename>`
**Whatâs happening:** `git checkout` alters files in the working directory to a state previously known to Git. You could provide a branch name or specific SHA you want to go back to or, by default, Git will assume you want to checkout `HEAD`, the last commit on the currently-checked-out branch.
Keep in mind: any changes you âundoâ this way are *really* gone. They were never committed, so Git canât help us recover them later. Be sure you know what youâre throwing away here! (Maybe use `git diff` to confirm.)
## [Reset âlocalâ changes](https://github.blog/open-source/git/how-to-undo-almost-anything-with-git/#reset-local-changes)
**Scenario:** Youâve made some commits locally (not yet pushed), but everything is terrible, you want to undo the last three commitsâlike they never happened.
**Undo with:** `git reset <last good SHA>` or `git reset --hard <last good SHA>`
**Whatâs happening:** `git reset` rewinds your repositoryâs history all the way back to the specified SHA. Itâs as if those commits never happened. By default, `git reset` preserves the working directory. The commits are gone, but the *contents* are still on disk. This is the safest option, but often, youâll want to âundoâ the commits *and* the changes in one moveâthatâs what `--hard` does.
## [Redo after undo âlocalâ](https://github.blog/open-source/git/how-to-undo-almost-anything-with-git/#redo-after-undo-local)
**Scenario:** You made some commits, did a `git reset --hard` to âundoâ those changes (see above), and *then* realized: you want those changes back\!
**Undo with:** `git reflog` and `git reset` or `git checkout`
**Whatâs happening:** `git reflog` is an amazing resource for recovering project history. You can recover *almost* anythingâanything youâve committedâvia the reflog.
Youâre probably familiar with the `git log` command, which shows a list of commits. `git reflog` is similar, but instead shows a list of times when `HEAD` changed.
Some caveats:
- `HEAD` changes *only*.`HEAD` changes when you switch branches, make commits with `git commit` and un-make commits with `git reset`, but `HEAD` does *not* change when you `git checkout -- <bad filename>` (from an earlier scenarioâas mentioned before, those changes were never committed, so the reflog canât help us recover those.
- `git reflog` doesnât last forever. Git will periodically clean up objects which are âunreachable.â Donât expect to find months-old commits lying around in the reflog forever.
- Your `reflog` is yours and yours alone. You canât use `git reflog` to restore another developerâs un-pushed commits.

So⌠how do you use the reflog to âredoâ a previously âundoneâ commit or commits? It depends on what exactly you want to accomplish:
- If you want to restore the projectâs history as it was at that moment in time use `git reset --hard <SHA>`
- If you want to recreate one or more files in your working directory as they were at that moment in time, without altering history use `git checkout <SHA> -- <filename>`
- If you want to replay *exactly one* of those commits into your repository use `git cherry-pick <SHA>`
## [Once more, with branching](https://github.blog/open-source/git/how-to-undo-almost-anything-with-git/#once-more-with-branching)
**Scenario:** You made some commits, then realized you were checked out on `master`. You wish you could make those commits on a feature branch instead.
**Undo with:** `git branch feature`, `git reset --hard origin/master`, and `git checkout feature`
**Whatâs happening:** You may be used to creating new branches with `git checkout -b <name>`âitâs a popular short-cut for creating a new branch and checking it out right awayâbut you donât want to switch branches just yet. Here, `git branch feature` creates a new branch called `feature` pointing at your most recent commit, but leaves you checked out to `master`.
Next, `git reset --hard` rewinds `master` back to `origin/master`, before any of your new commits. Donât worry, though, they are still available on `feature`.
Finally, `git checkout` switches to the new `feature` branch, with all of your recent work intact.
## [Branch in time saves nine](https://github.blog/open-source/git/how-to-undo-almost-anything-with-git/#branch-in-time-saves-nine)
**Scenario:** You started a new branch `feature` based on `master`, but `master` was pretty far behind `origin/master`. Now that `master` branch is in sync with `origin/master`, you wish commits on `feature` were starting *now*, instead of being so far behind.
**Undo with:** `git checkout feature` and `git rebase master`
**Whatâs happening:** You could have done this with `git reset` (no `--hard`, intentionally preserving changes on disk) then `git checkout -b <new branch name>` and then re-commit the changes, but that way, youâd lose the commit history. Thereâs a better way.
`git rebase master` does a couple of things:
- First it locates the common ancestor between your currently-checked-out branch and `master`.
- Then it resets the currently-checked-out branch to that ancestor, holding all later commits in a temporary holding area.
- Then it advances the currently-checked-out-branch to the end of `master` and replays the commits from the holding area *after* `master`âs last commit.
## [Mass undo/redo](https://github.blog/open-source/git/how-to-undo-almost-anything-with-git/#mass-undo-redo)
**Scenario:** You started this feature in one direction, but mid-way through, you realized another solution was better. Youâve got a dozen or so commits, but you only want some of them. Youâd like the others to just disappear.
**Undo with:** `git rebase -i <earlier SHA>`
**Whatâs happening:** `-i` puts `rebase` in âinteractive modeâ. It starts off like the rebase discussed above, but before replaying any commits, it pauses and allows you to gently modify each commit as itâs replayed.
`rebase -i` will open in your default text editor, with a list of commits being applied, like this:

The first two columns are key: the first is the selected command for the commit identified by the SHA in the second column. By default, `rebase -i` assumes each commit is being applied, via the `pick` command.
To drop a commit, just delete that line in your editor. If you no longer want the bad commits in your project, you can delete lines 1 and 3-4 above.
If you want to preserve the *contents* of the commit but edit the commit *message*, you use the `reword` command. Just replace the word `pick` in the first column with the word `reword` (or just `r`). It can be tempting to rewrite the commit message right now, but that wonât workâ`rebase -i` ignores everything after the SHA column. The text after that is really just to help us remember what `0835fe2` is all about. When youâve finished with `rebase -i`, youâll be prompted for any new commit messages you need to write.
If you want to combine two commits together, you can use the `squash` or `fixup` commands, like this:

`squash` and `fixup` combine âupââthe commit with the âcombineâ command will be merged into the commit immediately before it. In this scenario, `0835fe2` and `6943e85` will be combined into one commit, then `38f5e4e` and `af67f82` will be combined together into another.
When you select `squash`, Git will prompt us to give the new, combined commit a new commit message; `fixup` will give the new commit the message from the first commit in the list. Here, you know that `af67f82` is an âooopsâ commit, so youâll just use the commit message from `38f5e4e` as is, but youâll write a new message for the new commit you get from combining `0835fe2` and `6943e85`.
When you save and exit your editor, Git will apply your commits in order from top to bottom. You can alter the order commits apply by changing the order of commits before saving. If youâd wanted, you could have combined `af67f82` with `0835fe2` by arranging things like this:

## [Fix an earlier commit](https://github.blog/open-source/git/how-to-undo-almost-anything-with-git/#fix-an-earlier-commit)
**Scenario:** You failed to include a file in an earlier commit, itâd be great if that earlier commit could somehow include the stuff you left out. You havenât pushed, yet, but it wasnât the most recent commit, so you canât use `commit --amend`.
**Undo with:** `git commit --squash <SHA of the earlier commit>` and `git rebase --autosquash -i <even earlier SHA>`
**Whatâs happening:** `git commit --squash` will create a new commit with a commit message like `squash! Earlier commit`. (You could manually create a commit with a message like that, but `commit --squash` saves you some typing.)
You can also use `git commit --fixup` if you donât want to be prompted to write a new commit message for the combined commit. In this scenario, youâd probably use `commit --fixup`, since you just want to use the earlier commitâs commit message during `rebase`.
`rebase --autosquash -i` will launch an interactive `rebase` editor, but the editor will open with any `squash!` and `fixup!` commits already paired to the commit target in the list of commits, like so:

When using `--squash` and `--fixup`, you might not remember the SHA of the commit you want to fixâonly that it was one or five commits ago. You might find using Gitâs `^` and `~` operators especially handy. `HEAD^` is one commit before `HEAD`. `HEAD~4` is four commits before `HEAD` â or, altogether, five commits back.
## [Stop tracking a tracked file](https://github.blog/open-source/git/how-to-undo-almost-anything-with-git/#stop-tracking-a-tracked-file)
**Scenario:** You accidentally added `application.log` to the repository, now every time you run the application, Git reports there are unstaged changes in `application.log`. You put `*.log` in the `.gitignore` file, but itâs still thereâhow do you tell git to to âundoâ tracking changes in this file?
**Undo with:** `git rm --cached application.log`
**Whatâs happening:** While `.gitignore` prevents Git from tracking changes to files or even noticing the existence of files itâs never tracked before, once a file has been added and committed, Git will continue noticing changes in that file. Similarly, if youâve used `git add -f` to âforceâ, or override, `.gitignore`, Git will keep tracking changes. You wonât have to use `-f` to add it in the future.
If you want to remove that should-be-ignored file from Gitâs tracking, `git rm --cached` will remove it from tracking but leave the file untouched on disk. Since itâs now being ignored, you wonât see that file in `git status` or accidentally commit changes from that file again.
***
Thatâs how to undo anything with Git. To learn more about any of the Git commands used here, check out the relevant documentation:
- [checkout](http://git-scm.com/docs/git-checkout)
- [commit](http://git-scm.com/docs/git-commit)
- [rebase](http://git-scm.com/docs/git-rebase)
- [reflog](http://git-scm.com/docs/git-reflog)
- [reset](http://git-scm.com/docs/git-reset)
- [revert](http://git-scm.com/docs/git-revert)
- [rm](http://git-scm.com/docs/git-rm)
## Written by
 |
| Shard | 129 (laksa) |
| Root Hash | 7620767358965441529 |
| Unparsed URL | blog,github!/open-source/git/how-to-undo-almost-anything-with-git/ s443 |