How do I discard changes in my working copy that are not in the index?
40 Answers
For all unstaged files in current working directory use:
git restore .
For a specific file use:
git restore path/to/file/to/revert
That together with git switch
replaces the overloaded git checkout
(see here), and thus removes the argument disambiguation.
If a file has both staged and unstaged changes, only the unstaged changes shown in git diff
are reverted. Changes shown in git diff --staged
stay intact.
Before Git 2.23
For all unstaged files in current working directory:
git checkout -- .
For a specific file:
git checkout -- path/to/file/to/revert
--
here to remove ambiguity (this is known as argument disambiguation).
-
150This seems to be the git canonical way. i.e. exactly what git tells you to do if you type
git status
– ABMagilCommented Aug 18, 2014 at 16:01 -
40Doesn't work if there are untracked files. Git says
error: The following untracked working tree files would be overwritten by checkout: ...
. Commented Aug 24, 2014 at 13:26 -
114newbie question, what does "git checkout -- ." mean semantically?– kaidCommented Sep 7, 2014 at 19:21
-
136@Ninjack
git checkout -- .
means the same thing asgit checkout .
, except that you're explicit about the fact that you're not specifying the branch name. They both say checkout the HEAD version on the branch I am currently on for '.' or './'. If you dogit checkout branch-name directory-or-file-name
in general, you get the HEAD version ofdirectory-or-file-name
on branchbranch-name
.– akgillCommented Oct 29, 2014 at 19:55 -
28IMO this variant is imperfect, as it doesn't handle situation when your changed repository is not on the HEAD revision at the moment of changes cleaning and you DO NOT want to update it to HEAD, and want to just clean the changes.– alexykotCommented Jan 5, 2015 at 17:27
Another quicker way is:
git stash save --keep-index --include-untracked
You don't need to include --include-untracked
if you don't want to be thorough about it.
After that, you can drop that stash with a git stash drop
command if you like.
-
13@KarimSamir: The question specifically asks about changes that are not in the index. The
git reset
command will discard changes in the index too. Commented Apr 12, 2015 at 17:28 -
173
-
45Neither the
git stash
, nor any variety ofgit checkout
will discard unstaged deletes. According to the output ofgit status
, the actual correct answer here is some flavorgit reset HEAD
Commented May 27, 2015 at 22:27 -
156This pollutes the stash stack.
git checkout -- .
does the job with one command only. Commented Sep 9, 2015 at 11:17 -
3@FelipeTonello I wish I could give you 100 rep for that comment. In my test, that seemed to do exactly what I wanted. Instead, I spent the last hour using "git checkout -- *" and working around all the untracked file errors. Commented Dec 11, 2015 at 3:36
It seems like the complete solution is:
git clean -df
git checkout -- .
WARNING: while it won't delete ignored files mentioned directly in .gitignore, git clean -df
may delete ignored files residing in folders.
git clean
removes all untracked files and git checkout
clears all unstaged changes.
-
158
-
20@dval this is becues the first command removed the unindexed files and the second one removed the unstaged changes (of indexed files). So if you did not have any staged changes this it is the same as reverting to the last commit with
git reset --hard
Commented Oct 31, 2014 at 10:47 -
3
-
95Be careful running git clean -df. If you don't understand what it does, you might be deleting files you mean to keep, like robots.txt, uploaded files, etc.– ctlockeyCommented Jan 28, 2015 at 14:57
-
46As @ctlockey said, the first command also delete directories if they are composed of ignored files only... Lost a whole bunch of configuration files on my project :( Be careful. Commented Jul 16, 2015 at 8:00
This checks out the current index for the current directory, throwing away all changes in files from the current directory downwards.
git checkout .
or this which checks out all files from the index, overwriting working tree files.
git checkout-index -a -f
-
22+1 This is the RIGHT ANSWER, as it correctly handles the case where some files have both staged and un-staged changes. Note that this solution DISCARDS the unstaged changes; if you wish to retain them, then you should use @greg-hewgill 's answer of
git stash save --keep-index
.– RhubbarbCommented Jun 15, 2015 at 15:12 -
git checkout --
does not work if you have only one branch.git checkout .
always works. Commented Jun 29, 2018 at 16:23 -
Thank you so much! Finally an answer that ALWAYS works! This may be combined with
git clean
to also remove untracked files.– jlhCommented Jan 22, 2021 at 15:02 -
Not being funny but this appears to be the only working answer. The higher rated answers appear to do nothing. I'm sure they do something, but they certainly don't "reset" the unstaged changes. Commented Aug 15, 2021 at 19:48
git clean -df
Cleans the working tree by recursively removing files that are not under version control, starting from the current directory.
-d
: Remove untracked directories in addition to untracked files
-f
: Force (might be not necessary depending on clean.requireForce
setting)
Run git help clean
to see the manual
-
why this answer doesn't have all the votes? answered back in the 2011 and still correct. Commented Mar 1, 2018 at 13:20
-
-
This should be accepted. The definition shown by git when running git help says clearly: "Remove untracked files from the working tree" This is precisely what the OP was asking for.– fjplaurrCommented Feb 26, 2023 at 10:09
2019 update
You can now discard unstaged changes in one tracked file with:
git restore <file>
and in all tracked files in the current directory (recursively) with:
git restore .
If you run the latter from the root of the repository, it will discard unstaged changes in all tracked files in the project.
Notes
git restore
was introduced in July 2019 and released in version 2.23 as part of a split of thegit checkout
command intogit restore
for files andgit switch
for branches.git checkout
still behaves as it used to and the older answers remain perfectly valid.- When running
git status
with unstaged changes in the working tree, this is now what Git suggests to use to discard them (instead ofgit checkout -- <file>
as it used to prior to v2.23). - As with
git checkout -- .
, this only discards changes in tracked files. So Mariusz Nowak's answer still applies and if you want to discard all unstaged changes, including untracked files, you could run, as he suggests, an additionalgit clean -df
.
-
3I wanted to revert my unstaged changes only without affecting newly added files so a
git restore .
worked perfectly. Thanks. Commented Dec 2, 2019 at 10:23 -
4
-
1
-
2According to the man page
git restore .
restores all files in current directory, not in the whole repository.– jarnoCommented May 22, 2020 at 12:48 -
3You are right. Thanks! I just tested it and indeed, that is the case. It is, however, recursive. So when run from the root of the project, it applies to the whole repository. I will edit my answer. Commented May 22, 2020 at 19:57
My favorite is
git checkout -p
That lets you selectively revert chunks.
See also:
git add -p
-
14I love the ability to see the actual change before it's discarded. Commented Feb 3, 2015 at 21:42
-
This is what I use. git checkout -p and then "a" to accept all.– MattisCommented Apr 24, 2015 at 6:51
-
3I've never thought about. That
-p
adds a nice extra layer of safety. Combine it withgit clean -d
to actually answer OP. Commented Apr 27, 2016 at 6:39
Since no answer suggests the exact option combination that I use, here it is:
git clean -dxn . # dry-run to inspect the list of files-to-be-removed
git clean -dxf . # REMOVE ignored/untracked files (in the current directory)
git checkout -- . # ERASE changes in tracked files (in the current directory)
This is the online help text for the used git clean
options:
-d
Remove untracked directories in addition to untracked files. If an untracked directory is managed by a different Git repository, it is not removed by default. Use -f
option twice if you really want to remove such a directory.
-x
Don’t use the standard ignore rules read from .gitignore
(per directory) and $GIT_DIR/info/exclude
, but do still use the ignore rules given with -e
options. This allows removing all untracked files, including build products. This can be used (possibly in conjunction with git reset
) to create a pristine working directory to test a clean build.
-n
Don’t actually remove anything, just show what would be done.
-f
If the Git configuration variable clean.requireForce
is not set to false
, Git clean will refuse to delete files or directories unless given -f
, -n
, or -i
. Git will refuse to delete directories within the .git
subdirectory or file, unless a second -f
is given.
-
+1 for this solution. Regarding your remark that "git checkout . needs to be done in the root of the repo", maybe you might mention we can just do
git reset --hard
instead? (which is actually equivalent togit reset --hard HEAD
and should work whichever is the current directory...)– ErikMDCommented Jan 15, 2018 at 20:19 -
2Also regarding the first command
git clean -dfx
, here is a tip I use to be on the safe side before running it: just rungit clean -d -x -n
before, to display the list of files-to-be-removed, then confirm the operation by runninggit clean -d -x -f
(I put the argument-n
, resp.-f
in the end to be able to quickly change it in a terminal)– ErikMDCommented Jan 15, 2018 at 20:33 -
6Quick note that this is unreversable, and if you have files in
.gitignore
you will lose them. So consider backing up your project before this.– RobCommented Apr 3, 2018 at 3:47 -
@MartinG I just took the opportunity to incorporate my two suggestions, including the one that adds a "dry-run" step (as better safe than sorry!). Anyway, feel free to amend my edit if need be!– ErikMDCommented Jun 25, 2020 at 23:07
-
1How do I delete untracked files that show up in
git status
without deleting untracked files that are in.gitignore
? Commented Nov 2, 2021 at 21:20
If you merely wish to remove changes to existing files, use checkout
(documented here).
git checkout -- .
- No branch is specified, so it checks out the current branch.
- The double-hyphen (
--
) tells Git that what follows should be taken as its second argument (path), that you skipped specification of a branch. - The period (
.
) indicates all paths.
If you want to remove files added since your last commit, use clean
(documented here):
git clean -i
- The
-i
option initiates an interactiveclean
, to prevent mistaken deletions. - A handful of other options are available for a quicker execution; see the documentation.
If you wish to move changes to a holding space for later access, use stash
(documented here):
git stash
- All changes will be moved to Git's Stash, for possible later access.
- A handful of options are available for more nuanced stashing; see the documentation.
-
This will exactly convert your changes and discard newly added files from previous commit. Commented Feb 21, 2019 at 1:07
-
will it remove the newly added files? or just undo the changes in the old unstaged files?– KawaiKxCommented Nov 9, 2020 at 4:45
The easiest way to do this is by using this command:
This command is used to discard changes in working directory -
git checkout -- .
https://git-scm.com/docs/git-checkout
In git command, stashing of untracked files is achieved by using:
git stash -u
-
23Twice I've come here, read this answer, and forgotten the
.
at the end. To future me: the period is essential!– bejadoCommented Jun 16, 2017 at 17:13 -
3I needed to get rid of all local changes in a sub directory, without blowing away every other change. This answer helped a lot, thanks– AllyCommented Sep 7, 2017 at 4:00
-
2Please describe what the two commands do. It's really unhelpful to have no explanation. Commented Sep 9, 2017 at 17:22
-
2excellent. the checkout does in one command what the most popular one does in two. can also be followed up with
git clean -fd
to clean files not in the index. Commented Nov 28, 2017 at 9:03
I really found this article helpful for explaining when to use what command: http://www.szakmeister.net/blog/2011/oct/12/reverting-changes-git/
There are a couple different cases:
If you haven't staged the file, then you use
git checkout
. Checkout "updates files in the working tree to match the version in the index". If the files have not been staged (aka added to the index)... this command will essentially revert the files to what your last commit was.git checkout -- foo.txt
If you have staged the file, then use git reset. Reset changes the index to match a commit.
git reset -- foo.txt
I suspect that using git stash
is a popular choice since it's a little less dangerous. You can always go back to it if you accidently blow too much away when using git reset. Reset is recursive by default.
Take a look at the article above for further advice.
If you aren't interested in keeping the unstaged changes (especially if the staged changes are new files), I found this handy:
git diff | git apply --reverse
As you type git status, (use "git checkout -- ..." to discard changes in working directory) is shown.
e.g. git checkout -- .
-
1Downvoted because it doesn't help to quickly discard all files. The three dots indicate that you are required to list all the files. This is especially bad if you need to discard tons of files at once, eg. during a large merge after you have staged all the modifications you like to keep Commented Jun 9, 2016 at 15:26
-
3Of course, the correct command is "git checkout -- ." a single dot. In the comment, the three dots were a grammatical thing, to indicate there are many other options that could have been used..– Josef.BCommented Sep 20, 2016 at 11:01
You can use git stash - if something goes wrong, you can still revert from the stash. Similar to some other answer here, but this one also removes all unstaged files and also all unstaged deletes:
git add .
git stash
if you check that everything is OK, throw the stash away:
git stash drop
The answer from Bilal Maqsood with git clean
also worked for me, but with the stash I have more control - if I do sth accidentally, I can still get my changes back
UPDATE
I think there is 1 more change (don't know why this worked for me before):
git add . -A
instead of git add .
without the -A
the removed files will not be staged
git checkout -f
man git-checkout
:
-f, --force
When switching branches, proceed even if the index or the working tree differs from HEAD. This is used to throw away local changes.
When checking out paths from the index, do not fail upon unmerged entries; instead, unmerged entries are ignored.
-
3This would discard changes in the index!! (And the OP requires to leave them as is.) Commented Apr 19, 2015 at 13:59
Instead of discarding changes, I reset my remote to the origin. Note - this method is to completely restore your folder to that of the repo.
So I do this to make sure they don't sit there when I git reset (later - excludes gitignores on the Origin/branchname)
NOTE: If you want to keep files not yet tracked, but not in GITIGNORE you may wish to skip this step, as it will Wipe these untracked files not found on your remote repository (thanks @XtrmJosh).
git add --all
Then I
git fetch --all
Then I reset to origin
git reset --hard origin/branchname
That will put it back to square one. Just like RE-Cloning the branch, WHILE keeping all my gitignored files locally and in place.
Updated per user comment below: Variation to reset the to whatever current branch the user is on.
git reset --hard @{u}
-
This is my preferred option, but why do you add all changes first? So far as I'm aware this just modifies the directory listing in Git files, while using git reset --hard, this will be lost anyway while the directories will still be removed.– XtrmJoshCommented Sep 30, 2015 at 10:00
-
I dont on mac or linux, github windows powershell sometimes leaves the files there after reset. I think its because git reset sets all files in the repo to its original state. If theyre not added, theyre not touched. The desktop client then will pickup the "hey this file is in here and needs to be committed"– NickCommented Oct 1, 2015 at 17:04
-
Sense made. I don't use Windows so haven't seen that issue (haven't used Windows for the last few months at least, don't remember much before that - it's one huge regrettable blur). Might be worth noting the rationale in your main answer :)– XtrmJoshCommented Oct 2, 2015 at 12:18
-
I ran across this issue on a Mac too now. If the file is not tracked in the Repo sometimes git reset doesnt touch it. I cant really isolate the "WHY" but when that happens, if I reset, and i still have 1 uncommitted file or two, i add --all and reset --hard again– NickCommented Nov 19, 2015 at 2:18
-
3A nice little variation of this I like is
git reset --hard @{u}
which resets the branch to wherever the current remote-tracking branch is Commented Jan 6, 2016 at 19:39
Tried all the solutions above but still couldn't get rid of new, unstaged files.
Use git clean -f
to remove those new files - with caution though! Note the force option.
Just use:
git stash -u
Done. Easy.
If you really care about your stash stack then you can follow with git stash drop
. But at that point you're better off using (from Mariusz Nowak):
git checkout -- .
git clean -df
Nonetheless, I like git stash -u
the best because it "discards" all tracked and untracked changes in just one command. Yet git checkout -- .
only discards tracked changes,
and git clean -df
only discards untracked changes... and typing both commands is far too much work :)
-
Note:
git stash -u
will soon (Git 2.14.x/2.15, Q3 2017) evolve a bit: stackoverflow.com/a/46027357/6309– VonCCommented Sep 3, 2017 at 20:10 -
If i get the question of the OP correct the indexed files should be kept. Only unstage changes should be removed. So is should be
git stash -k
in my opinion.– snapCommented Feb 1, 2018 at 8:19
simply say
git stash
It will remove all your local changes. You also can use later by saying
git stash apply
or git stash pop
No matter what state your repo is in you can always reset to any previous commit:
git reset --hard <commit hash>
This will discard all changes which were made after that commit.
-
4This will also discard everything in the index (not just things not in the index), which is beyond what the OP is asking for. Commented Jul 8, 2018 at 7:51
cd path_to_project_folder # take you to your project folder/working directory
git checkout . # removes all unstaged changes in working directory
This works even in directories that are; outside of normal git permissions.
sudo chmod -R 664 ./* && git checkout -- . && git clean -dfx
Happened to me recently
-
Beware though, that the git ignored content will not retain it's original permissions! Hence it can cause a security risk.– twicejrCommented Dec 10, 2014 at 18:06
-
@twicejr You're wrong, please read
git help clean
"-d Remove untracked directories in addition to untracked files." Commented Dec 10, 2014 at 22:40 -
Why did you set all your files to be world read/write? Not good practice.– GhotiCommented Sep 28, 2015 at 11:31
-
Setting all permissions to 664 makes a lot of assumptions about what kind of permissions the project needs. I think using that part of the command will cause issues for some people. Commented Nov 20, 2018 at 17:12
In my opinion,
git clean -df
should do the trick. As per Git documentation on git clean
git-clean - Remove untracked files from the working tree
Description
Cleans the working tree by recursively removing files that are not under version control, starting from the current directory.
Normally, only files unknown to Git are removed, but if the -x option is specified, ignored files are also removed. This can, for example, be useful to remove all build products.
If any optional ... arguments are given, only those paths are affected.
Options
-d Remove untracked directories in addition to untracked files. If an untracked directory is managed by a different Git repository, it is not removed by default. Use -f option twice if you really want to remove such a directory.
-f --force If the Git configuration variable clean.requireForce is not set to false, git clean will refuse to run unless given -f, -n or -i.
Final working solution
git restore .
git clean -f
git clean -df (if you have folders in your local changes)
git checkout .
This will discard any uncommitted changes to the branch. It won't reset it back if any changes were committed. This is handy when you've done some changes and decide you don't want them for some reason and you have NOT committed those changes. It actually just checks out the branch again and discards any current uncommitted changes.
( must be in the app's root or home dir for this to work )
Another way to get rid of new files that is more specific than git clean -df (it will allow you to get rid of some files not necessarily all), is to add the new files to the index first, then stash, then drop the stash.
This technique is useful when, for some reason, you can't easily delete all of the untracked files by some ordinary mechanism (like rm).
I had a weird situation where a file is always unstaged, this helps me to resolve.
git rm .gitattributes
git add -A
git reset --hard
-
I had similar. If you had an error in your .gitattributes file then doing "git reset --hard" won't renormalize your files as you expect. I fixed my gitattributes and then "git reset --hard" removed files from both staging and also their modified status.– timB33Commented Feb 9, 2023 at 11:33
If it's almost impossible to rule out modifications of the files, have you considered ignoring them? If this statement is right and you wouldn't touch those files during your development, this command may be useful:
git update-index --assume-unchanged file_to_ignore
git-clean
only removes untracked files from the working tree git-scm.com/docs/git-cleangit-clean -df
can be dangerous. It will delete local untracked files (e.g. covered by a .gitignore) Read all below carefully and consider git checkout . insteadgit status
gives a suggestion on how to do that!git checkout -- .
git status
gives the suggestion:git restore
.git restore
is a new command exactly for this purpose. See my 2019 update.