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

21

2604

I ran 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
Dewdrop answered 18/7, 2009 at 7:52 Comment(0)
T
4529

To revert changes made to your working copy, do this:

git checkout .

Or equivalently, for git version >= 2.23:

git restore .

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

To revert a change that you have committed:

git revert <commit 1> <commit 2>

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
Tabriz answered 18/7, 2009 at 7:57 Comment(22)
fwiw after such a long time, git checkout path/to/file will only revert the local changes to path/to/filePapp
+1 on the answers below also mentioning git clean -f (to remove the untracked changes) and -fd (to also remove untracked directories)Gonfanon
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 --hardLongdistance
and if you also want to clean your untracked files , read this #61712Trenatrenail
➜ 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 changedHaught
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)Psittacine
Can i revert pull changes if the changes were not committed?#30764332Chalutz
git checkout . and git reset [--hard HEAD] didn't work, I had to do a git clean -fd to revert my changes.Grimaldi
I added some details on git clean as wellTabriz
git reset doesn't reset your changes, git reset --hard does that.Sybyl
@Sybyl 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-resetTabriz
One remark: do git checkout . in the root dir of your project. Or in the subdir that you want to revert.Remanent
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.Veery
git reset unstages, doesn't reset unpushed commits to masterBeore
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.Tergal
I used git clean -fd following with git fetch & git check <another branch>. It worked!Caffeine
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.Arni
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!Plasticity
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..Convenience
git restore . only for change in current dir git restore :/ for all changes in the repositoryFascinating
This answer is completely wrong, at least for meOverexpose
If you're used to using an IDE for git like Intellij git interface. Do a checkout on origin/develop(not on develop, but the remote origin/develop or whatever your remote branch name is). It will give you a warning that your local changes will be dropped, select yes and you should see those pesky local changes vanished!Payee
M
501

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.

Microwatt answered 20/7, 2009 at 5:37 Comment(4)
The file clean command is "git clean -f". Untracked directories are removed with "git clean -d"Subadar
git clean -fd (force is required for -d)Obvious
-n or --dry-run are the flags for dry-run.Pokpoke
git clean -ffd if you have another git repository in your git repository. Without double f it would not be removed.Childs
C
282

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
Canakin answered 20/3, 2017 at 12:37 Comment(11)
Sorry for stealing from above answers. I use this reference constantly, posting mostly for me.Canakin
I'm pretty sure, that the first option (Re-clone) actually DOES "delete local, non-pushed commits" :)Decencies
What does the red X and green checkmark mean? Does the red X negate the sentence next to it?Frediafredie
@Frediafredie ✅ is something it does, ❌ is something it doesn't doCanakin
@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?Frediafredie
This might make more sense in a table and put a ✅ if the command does the thing.Frediafredie
Thank you, double negatives corrected, because a single negative is MORE negativeCanakin
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 docsHinayana
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?Ester
@Ester 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".Chemisorb
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.Radiance
M
122

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.
Masquer answered 22/4, 2015 at 20:48 Comment(3)
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.Redness
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 wellGang
@Redness In my Windows 10 CMD, git reset --hard without anything else worked for me; perhaps because there were no commits/checkouts/branches, but simply a single modified file?Dubious
M
72

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.

Michi answered 4/6, 2014 at 7:25 Comment(5)
Last command gives me error: pathspec 'HEAD' did not match any file(s) known to git.Eupatrid
It worked for me when I took the "--" out. git checkout HEADGrafton
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?Cynar
We dont need the double hyphen. Must be a typo.Willman
Removed -- in git checkout -- HEAD as this is not a valid command, while git checkout HEAD is.Underslung
M
52

Look into git-reflog. It will list all the states it remembers (default is 30 days), and you can simply checkout the one you want. For example:

$ git init > /dev/null
$ touch a
$ git add .
$ git commit -m"Add file a" > /dev/null
$ echo 'foo' >> a
$ git commit -a -m"Append foo to a" > /dev/null
$ for i in b c d e; do echo $i >>a; git commit -a -m"Append $i to a" ;done > /dev/null
$ git reset --hard HEAD^^ > /dev/null
$ cat a
foo
b
c
$ git reflog
145c322 HEAD@{0}: HEAD^^: updating HEAD
ae7c2b3 HEAD@{1}: commit: Append e to a
fdf2c5e HEAD@{2}: commit: Append d to a
145c322 HEAD@{3}: commit: Append c to a
363e22a HEAD@{4}: commit: Append b to a
fa26c43 HEAD@{5}: commit: Append foo to a
0a392a5 HEAD@{6}: commit (initial): Add file a
$ git reset --hard HEAD@{2}
HEAD is now at fdf2c5e Append d to a
$ cat a
foo
b
c
d
Malodorous answered 19/7, 2009 at 12:16 Comment(4)
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.Dub
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!Hyetography
What do you mean by 30 days default !?Pongid
@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.Malodorous
V
44

simply execute -

git stash

it will remove all your local changes. and you can also use it later by executing -

git stash apply 
Vincennes answered 24/4, 2015 at 12:18 Comment(3)
use git stash pop would automatically remove topmost the stashed change for youYemen
git stash drop to remove the latest stashed state without apply to working copy.Mitrailleuse
git stash apply wont add newly created filesJardine
M
38

DANGER AHEAD: (please read the comments. Executing the command proposed in my answer might delete more than you want)

to completely remove all files including directories I had to run

git clean -f -d
Mikaelamikal answered 11/9, 2013 at 7:10 Comment(3)
To save anyone the pain I just went through: this will delete .gitignore-d files too!Scab
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 :-)Mikaelamikal
no harm done. I had backups, but this probably warrants a disclaimer ;)Scab
B
32

Try this if you are in top project directory:

git restore .

If not then use:

git restore :/

If you would like to revert local changes for a subset:

  • restore all working tree files with top pathspec magic: git restore :/
  • restore all files in the current directory: git restore .
  • file type (e.g. all C source files): git restore '*.c'

For details see git restore documentation.

To remove untracked files: git clean -f

Benedict answered 22/7, 2021 at 8:21 Comment(2)
Thanks for this. That "magic" is an abomination, though. Why not support a wildcard?Thier
SO post on pathspec for those wondering. @Thier pathspec also has wildcards included in its syntax; not sure how well though.Yelp
T
29

I met a similar problem. The solution is to use git log to look up which version of the local commit is different from the remote. (E.g. the version is 3c74a11530697214cbcc4b7b98bf7a65952a34ec).

Then use git reset --hard 3c74a11530697214cbcc4b7b98bf7a65952a34ec to revert the change.

Trudey answered 28/8, 2013 at 7:34 Comment(0)
C
26

I searched for a similar issue,

Wanted to throw away local commits:

  1. cloned the repository (git clone)
  2. switched to dev branch (git checkout dev)
  3. did few commits (git commit -m "commit 1")
  4. but decided to throw away these local commits to go back to remote (origin/dev)

So did the below:

git reset --hard origin/dev

Check:

git status  

        On branch dev  
        Your branch is up-to-date with 'origin/dev'.  
        nothing to commit, working tree clean  

now local commits are lost, back to the initial cloned state, point 1 above.

Clack answered 25/2, 2017 at 10:3 Comment(1)
thanks, that's the only thing that worked for me - "git reset --hard origin"Extensive
O
18

The other answers seemed way too complicated, so here is a simple solution that worked for me:

How to discard all local changes and reset the files to the last commit on my current branch?

# Execute on the root of the working tree...

# Discard all changes to tracked files
git checkout .

# Remove all untracked files 
git clean -fd

Note: ignored files will remain unaffected

Overexpose answered 26/8, 2022 at 17:1 Comment(1)
Far and away the best answer here. Thanks.Ski
A
10

Two simple steps

git fetch origin
git reset --hard origin/master

or if your git uses main instead master use this:

git reset --hard origin/main
Avisavitaminosis answered 23/2, 2022 at 11:45 Comment(0)
P
9

Try this for revert all changes uncommited in local branch

$ git reset --hard HEAD

But if you see a error like this:

fatal: Unable to create '/directory/for/your/project/.git/index.lock': File exists.

You can navigate to '.git' folder then delete index.lock file:

$ cd /directory/for/your/project/.git/
$ rm index.lock

Finaly, run again the command:

$ git reset --hard HEAD
Passional answered 3/1, 2017 at 12:49 Comment(0)
D
8

Adding another option here.

I'm referring to the title: Revert local changes.
It can also apply to changes that weren't staged for commit.

In this case you can use:

git restore <file>

To go back to previous state.

Dratted answered 6/9, 2020 at 13:37 Comment(3)
To restore all file changes in a current local directory you can use: git restore .Passivism
The best answer out hereSauerkraut
Please run git help - you should see it there..(:Dratted
A
6

You may not necessarily want/need to stash your work/files in your working directory but instead simply get rid of them completely. The command git clean will do this for you.

Some common use cases for doing this would be to remove cruft that has been generated by merges or external tools or remove other files so that you can run a clean build.

Keep in mind you will want to be very cautious of this command, since its designed to remove files from your local working directory that are NOT TRACKED. if you suddenly change your mind after executing this command, there is no going back to see the content of the files that were removed. An alternative which is safer is to execute

git stash --all

which will remove everything but save it all in a stash. This stash can then later be used.

However, if you truly DO want to remove all the files and clean your working directory, you should execute

git clean -f -d

This will remove any files and also any sub-directories that don't have any items as a result of the command. A smart thing to do before executing the git clean -f -d command is to run

git clean -f -d -n

which will show you a preview of what WILL be removed after executing git clean -f -d

So here is a summary of your options from most aggressive to least aggressive


Option 1: Remove all files locally(Most aggressive)

git clean -f -d

Option 2: Preview the above impact(Preview most aggressive)

git clean -f -d -n

Option 3: Stash all files (Least aggressive)

git stash --all
Audubon answered 14/6, 2016 at 22:31 Comment(1)
I believe this answer is basically wrong. clean -fd deals with new files, but doesn't revert modifications.Ski
E
4

If you just want to delete all the changes, go for git checkout . It's the faster and simpler one.

Edom answered 10/6, 2021 at 23:6 Comment(1)
This does not remove files or folders added since the commit. For example, I find myself needing to revert most often after renaming a directory which results in a multitude of errors due to "deleting" and "adding" files and directories.Innocent
L
1

It's a headache, you can try:

git stash --all
git stash apply 

This will discard all local changes from the history and keep the files inside the folder.

Leaf answered 28/9, 2023 at 1:54 Comment(0)
N
0

This question is more about broader repository reset / revert, but in case if you're interested in reverting individual change - I've added similar answer in here:

https://mcmap.net/q/11765/-contaminated-remote-master-branch-or-anti-cherry-pick

Answers to questions:

  • How to revert individual change with or without change preserving in git history

  • How to return back to old version to restart from same state

Nerti answered 28/3, 2020 at 8:25 Comment(0)
L
0

Using git version "2.37.1"

I reverted all my local changes ( not yet committed ) to previous state ( prior to my local changes ) by using the following command :

git checkout -p

Documentation snippet :

you can use git checkout -p to selectively discard edits from your current working tree

From man git-checkout

  -p, --patch
       Interactively select hunks in the difference between the <tree-ish>
       (or the index, if unspecified) and the working tree. The chosen
       hunks are then applied in reverse to the working tree (and if a
       <tree-ish> was specified, the index).

       **This means that you can use git checkout -p to selectively discard
       edits from your current working tree.** See the “Interactive Mode”
       section of git-add(1) to learn how to operate the --patch mode.

       Note that this option uses the no overlay mode by default (see also
       --overlay), and currently doesn’t support overlay mode.
Larry answered 3/5, 2023 at 4:21 Comment(0)
I
0

The multitude of answers here, including the accepted answer, always leaves me questioning which commands I should run.

Many have warnings, and despite visiting this question many times, I can never remember which combination I should, or more importantly should not, run.

So, I am leaving this here for myself when I revisit the topic next week.

git restore .
git clean -f
git clean -fd

For most scenarios you can simply combine the commands, but as I point out in my explanation some cases require you delete files first, then the directories that hold them.

 git restore . && git clean -fd

Explanation:

The command git restore . performs a checkout on the current branch to the current directory. This will undo any changes made to any files. More specifically, the command will revert all changes in tracked files to their last committed state in the current directory and subdirectories.

The command git clean -f removes any newly added (untracked) files since the restore. This command permanently deletes files and cannot be undone.

The command git clean -fd removes any newly added directories since the restore. This command permanently deletes directories and their files and cannot be undone.

Note: I am not a git expert, just someone who uses git professionally, every day, all day, for many years. I advise you to consult the documenation.

With that said -fd should take care of -f but there are exceptions where it blows up. In my experience, executing all three commands works. It is kind of like calling Directory.Delete(path, recursive=true) which should delete all files but sometimes for whatever reason (depending on your OS) you must delete each file first before deleting the directory.

Another Note: Misleading Warning in Accepted Answer And Other Answers: The accepted answer's warning regarding git reset ("Warning this will reset all of your unpushed commits to master!") might be misleading. git reset without any arguments defaults to git reset --mixed HEAD, which only affects the staging area (index) and not the working tree or commit history. git reset does not revert commits or affect the branch history unless combined with a commit reference (like git reset --hard <commit>), which indeed can change the commit history in the local repository.

Innocent answered 2/3 at 4:31 Comment(1)
Obligatory: xkcd.com/1597Fabricant

© 2022 - 2024 — McMap. All rights reserved.