How do I revert all local changes in Git managed project to previous state?

2,033,896

Solution 1

If you want to revert changes made to your working copy, do this:

git checkout .

If you want to revert changes made to the index (i.e., that you have added), do this. Warning this will reset all of your unpushed commits to master!:

git reset

If you want to revert a change that you have committed, do this:

git revert <commit 1> <commit 2>

If you want to remove untracked files (e.g., new files, generated files):

git clean -f

Or untracked directories (e.g., new or automatically generated directories):

git clean -fd

Solution 2

Note: You may also want to run

git clean -fd

as

git reset --hard

will not remove untracked files, where as git-clean will remove any files from the tracked root directory that are not under git tracking. WARNING - BE CAREFUL WITH THIS! It is helpful to run a dry-run with git-clean first, to see what it will delete.

This is also especially useful when you get the error message

~"performing this command will cause an un-tracked file to be overwritten"

Which can occur when doing several things, one being updating a working copy when you and your friend have both added a new file of the same name, but he's committed it into source control first, and you don't care about deleting your untracked copy.

In this situation, doing a dry run will also help show you a list of files that would be overwritten.

Solution 3

Re-clone

GIT=$(git rev-parse --show-toplevel)
cd $GIT/..
rm -rf $GIT
git clone ...
  • ✅ Deletes local, non-pushed commits
  • ✅ Reverts changes you made to tracked files
  • ✅ Restores tracked files you deleted
  • ✅ Deletes files/dirs listed in .gitignore (like build files)
  • ✅ Deletes files/dirs that are not tracked and not in .gitignore
  • 😀 You won't forget this approach
  • 😔 Wastes bandwidth

Following are other commands I forget daily.

Clean and reset

git clean --force -d -x
git reset --hard
  • ❌ Deletes local, non-pushed commits
  • ✅ Reverts changes you made to tracked files
  • ✅ Restores tracked files you deleted
  • ✅ Deletes files/dirs listed in .gitignore (like build files)
  • ✅ Deletes files/dirs that are not tracked and not in .gitignore

Clean

git clean --force -d -x
  • ❌ Deletes local, non-pushed commits
  • ❌ Reverts changes you made to tracked files
  • ❌ Restores tracked files you deleted
  • ✅ Deletes files/dirs listed in .gitignore (like build files)
  • ✅ Deletes files/dirs that are not tracked and not in .gitignore

Reset

git reset --hard
  • ❌ Deletes local, non-pushed commits
  • ✅ Reverts changes you made to tracked files
  • ✅ Restores tracked files you deleted
  • ❌ Deletes files/dirs listed in .gitignore (like build files)
  • ❌ Deletes files/dirs that are not tracked and not in .gitignore

Notes

Test case for confirming all the above (use bash or sh):

mkdir project
cd project
git init
echo '*.built' > .gitignore
echo 'CODE' > a.sourceCode
mkdir b
echo 'CODE' > b/b.sourceCode
cp -r b c
git add .
git commit -m 'Initial checkin'
echo 'NEW FEATURE' >> a.sourceCode
cp a.sourceCode a.built
rm -rf c
echo 'CODE' > 'd.sourceCode'

See also

  • git revert to make new commits that undo prior commits
  • git checkout to go back in time to prior commits (may require running above commands first)
  • git stash same as git reset above, but you can undo it

Solution 4

If you want to revert all changes AND be up-to-date with the current remote master (for example you find that the master HEAD has moved forward since you branched off it and your push is being 'rejected') you can use

git fetch  # will fetch the latest changes on the remote
git reset --hard origin/master # will set your local branch to match the representation of the remote just pulled down.

Solution 5

After reading a bunch of answers and trying them, I've found various edge cases that mean sometimes they don't fully clean the working copy.

Here's my current bash script for doing it, which works all the time.

#!/bin/sh
git reset --hard
git clean -f -d
git checkout HEAD

Run from working copy root directory.

Share:
2,033,896
Daniel
Author by

Daniel

aka Gavin

Updated on July 11, 2022

Comments

  • Daniel
    Daniel almost 2 years

    I have a project in which I ran git init. After several commits, I did git status which told me everything was up to date and there were no local changes.

    Then I made several consecutive changes and realized I wanted to throw everything away and get back to my original state. Will this command do it for me?

    git reset --hard HEAD
    
  • palaniraja
    palaniraja over 13 years
    thanks a ton William, for git reflog. I reset my tree to old version and not sure how to retrive to recent. your git reflog saved me. Thanks once again.
  • Jonathan Mitchell
    Jonathan Mitchell about 13 years
    The file clean command is "git clean -f". Untracked directories are removed with "git clean -d"
  • electblake
    electblake about 13 years
    git clean -fd (force is required for -d)
  • Matijs
    Matijs almost 13 years
    fwiw after such a long time, git checkout path/to/file will only revert the local changes to path/to/file
  • ptdev
    ptdev almost 12 years
    +1 on the answers below also mentioning git clean -f (to remove the untracked changes) and -fd (to also remove untracked directories)
  • Huluvu424242
    Huluvu424242 over 11 years
    With the git command "git checkout branchId" it will be listet the modified files but no revert will be done. I must use git reset --hard
  • Surasin Tancharoen
    Surasin Tancharoen over 11 years
    and if you also want to clean your untracked files , read this stackoverflow.com/questions/61212/…
  • paneer_tikka
    paneer_tikka about 11 years
    saved me as well! In my case my adventure with git rebase -i had gone wrong (ended up wiping out some commits due to an editing mistake). Thanks to this tip I'm back in a good state!
  • landons
    landons almost 11 years
    To save anyone the pain I just went through: this will delete .gitignore-d files too!
  • Tobias Gassmann
    Tobias Gassmann over 10 years
    sorry if I caused you any trouble. Back then I just tried to revert and delete everything in that folder. I don't recall the exact circumstances, but the "-d" was the only thing working for me. I hope I did not cause you too much pain :-)
  • landons
    landons over 10 years
    no harm done. I had backups, but this probably warrants a disclaimer ;)
  • stephenbez
    stephenbez almost 10 years
    -n or --dry-run are the flags for dry-run.
  • antiqe
    antiqe over 9 years
    ➜ API git:(master) ✗ git checkout . ➜ API git:(master) ✗ git reset ➜ API git:(master) ✗ git revert ... fatal: empty commit set passed ➜ API git:(master) ✗ gst On branch master Your branch is up-to-date with 'origin/master'. Untracked files: (use "git add <file>..." to include in what will be committed) V1/ css/ js/ nothing changed
  • 0xC0000022L
    0xC0000022L over 9 years
    Last command gives me error: pathspec 'HEAD' did not match any file(s) known to git.
  • falsarella
    falsarella about 9 years
    Be careful: git reset reverts your commits to master! (It wasn't clear enough for me that added would include committed, and I have accidentally lost my changes)
  • Android Developer
    Android Developer about 9 years
    Can i revert pull changes if the changes were not committed?stackoverflow.com/questions/30763832/…
  • BrainSlugs83
    BrainSlugs83 about 9 years
    git checkout . and git reset [--hard HEAD] didn't work, I had to do a git clean -fd to revert my changes.
  • 1800 INFORMATION
    1800 INFORMATION about 9 years
    I added some details on git clean as well
  • Jester
    Jester almost 9 years
    It worked for me when I took the "--" out. git checkout HEAD
  • v.shashenko
    v.shashenko over 8 years
    git reset --hard reverts tracked files (staged or not), git clean -f -d removes untracked files, git checkout -- HEAD why do we need this then?
  • Arrow Cen
    Arrow Cen over 8 years
    use git stash pop would automatically remove topmost the stashed change for you
  • deerchao
    deerchao over 8 years
    git stash drop to remove the latest stashed state without apply to working copy.
  • Cerin
    Cerin almost 8 years
    git reset doesn't reset your changes, git reset --hard does that.
  • 1800 INFORMATION
    1800 INFORMATION almost 8 years
    @Cerin git reset acts as git reset --mixed ("Resets the index but not the working tree (i.e., the changed files are preserved but not marked for commit) and reports what has not been updated. This is the default action.") which is what I said. git-scm.com/docs/git-reset
  • exebook
    exebook almost 8 years
    One remark: do git checkout . in the root dir of your project. Or in the subdir that you want to revert.
  • Trismegistos
    Trismegistos over 7 years
    git clean -ffd if you have another git repository in your git repository. Without double f it would not be removed.
  • Mohe TheDreamy
    Mohe TheDreamy over 7 years
    What do you mean by 30 days default !?
  • William Pursell
    William Pursell over 7 years
    @MoheTheDreamy I mean that there is a time limit. Eventually the garbage collector will delete unreachable references when their age goes over that limit. The default used to be (and maybe still is) 30 days. So older references may not be available.
  • Farax
    Farax over 7 years
    We dont need the double hyphen. Must be a typo.
  • William Entriken
    William Entriken over 7 years
    Sorry for stealing from above answers. I use this reference constantly, posting mostly for me.
  • danio
    danio about 7 years
    git checkout . in the root of my project only applied to the files in that dir, I had to do git checkout * to revert all sub-directories too.
  • Marandil
    Marandil about 7 years
    I'm pretty sure, that the first option (Re-clone) actually DOES "delete local, non-pushed commits" :)
  • styfle
    styfle about 7 years
    What does the red X and green checkmark mean? Does the red X negate the sentence next to it?
  • William Entriken
    William Entriken about 7 years
    @styfle ✅ is something it does, ❌ is something it doesn't do
  • styfle
    styfle about 7 years
    @FullDecent It's kind of confusing to read. "❌ Does NOT delete local, non-pushed commits". That means it doesn't NOT delete. The double negative means that it does delete?
  • styfle
    styfle about 7 years
    This might make more sense in a table and put a ✅ if the command does the thing.
  • rok
    rok over 6 years
    git reset unstages, doesn't reset unpushed commits to master
  • disklosr
    disklosr over 6 years
    The warning is totally wrong! First of all, git reset works on the current branch (HEAD) and what it does has nothing to do with the "master" branch. Also, reset has nothing to do with unpushed commits and no you don't automatically lose them just because you used git reset.
  • Khachornchit Songsaen
    Khachornchit Songsaen about 6 years
    I used git clean -fd following with git fetch & git check <another branch>. It worked!
  • William Entriken
    William Entriken almost 6 years
    Thank you, double negatives corrected, because a single negative is MORE negative
  • THE JOATMON
    THE JOATMON over 5 years
    You don't always have to use --hard. In fact, sometimes that's not right... to do. You might have more luck with the --gentle command.
  • Alex
    Alex almost 5 years
    About -x flag in git clean -f -d -x: if the -x option is specified, ignored files are also removed. This can, for example, be useful to remove all build products.- from GIT docs
  • Ravistm
    Ravistm almost 5 years
    git stash apply wont add newly created files
  • Jake
    Jake over 4 years
    It seems important to specify origin in git reset --hard origin/master (which works) – without it (i.e. git reset --hard) nothing seems to be changed.
  • Nisim Naim
    Nisim Naim over 4 years
    thanks, that's the only thing that worked for me - "git reset --hard origin"
  • Manohar Reddy Poreddy
    Manohar Reddy Poreddy over 4 years
    happy to know it helped.
  • abhishek ringsia
    abhishek ringsia over 4 years
    I had some local changes and not able to get rid of them by any command I did git reset --hard origin/master and it was able to pull master's changes as well
  • calyxofheld
    calyxofheld over 4 years
    i ran git reset --hard and it restored my tracked files but did NOT delete untracked files. in fact, when i ran git status after, it said Untracked files: (use "git add <file>..." to include in what will be committed). which is what i wanted! why do you say it deletes untracked files, though?
  • Dominic Comtois
    Dominic Comtois almost 4 years
    Removed -- in git checkout -- HEAD as this is not a valid command, while git checkout HEAD is.
  •   vrnvorona
    vrnvorona over 3 years
    @calyxofheld it doesn't say it deletes untracked files. ❌ means "it doesn't do", ✅ means it does. In Reset part i see "❌ Deletes files/dirs that are not tracked and not in .gitignore".
  • Mike
    Mike over 3 years
    Totally agree with @disklosr, the warning about git reset is misleading at best and false at worst. It makes the impression that reset will somehow revert your current branch to the master branch, which is totally wrong. reset does not operate on branches, so whatever it does refers to your current branch, even if it's not master. Second, it does not change the working tree, therefore you cannot lose data with reset. If you have unpushed commits, then the commits will disappear from the local history, but the actual files will not be changed. You can commit the same thing again!
  • John C
    John C over 3 years
    To restore all file changes in a current local directory you can use: git restore .
  • Traderhut Games
    Traderhut Games over 3 years
    I would be mean and down-vote this (not that it would matter), but I reverted a change (did NOT push it), and after git reset, git reset --hard, git clean, git checkout, git checkout --force... I finally figured out that maybe, the answer is 'rm -rf .; git clone... .' because the dang thing KEEPS saying I'm one commit AHEAD of the remote, and Dang it, I just reset and wiped out all my local changes so, NO I am not! Found answer below: git reset --hard origin/develop Without the origin/branch_name it won't actually fully reset..
  • maverick
    maverick about 3 years
    The best answer out here
  • RtmY
    RtmY almost 3 years
    Please run git help - you should see it there..(:
  • pdoherty926
    pdoherty926 almost 3 years
    Thanks for this. That "magic" is an abomination, though. Why not support a wildcard?
  • TestingWithArif
    TestingWithArif almost 3 years
    this is the only thing that worked for me. THANKS much
  • legends2k
    legends2k over 2 years
    SO post on pathspec for those wondering. @pdoherty926 pathspec also has wildcards included in its syntax; not sure how well though.
  • francescortiz
    francescortiz over 2 years
    It is worth noting that git clone ... does not work as it is, you need to replace ... with your repository url or use your own custom clone command.