How do I discard unstaged changes in Git?
Asked Answered
C

40

6279

How do I discard changes in my working copy that are not in the index?

Chil answered 9/9, 2008 at 19:33 Comment(11)
See also #22620893Dormitory
git-clean only removes untracked files from the working tree git-scm.com/docs/git-cleanPoss
To clarify Asenar's comment above, git-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 . insteadAntoniettaantonin
'git clean -df ' Be warned! I tried that and lost key folders that are unable to be restored... Ouch!Caucasia
hitting git status gives a suggestion on how to do that! git checkout -- .Eastbound
git gui has a feature which will safely revert changes. .gitignore is honored by this program where as git-clean doesn't use it at all.Sexagesimal
@Readonly I think, the question should be, "How do I discard unstaged changes in Working Tree" Because you can unstage changes in staging area by git reset HEAD file1 that overwrites file1 from most recent commit in commit History.to Staging area.Weizmann
@Paulo: starting in July 2019, git status gives the suggestion: git restore. git restore is a new command exactly for this purpose. See my 2019 update.Clubhaul
I think either the question or the title should be changed. The title is not the same as the question asked, it is not clear whether the answers cover both.Headphone
Probably not what you are looking for, but of course if you are using GitHub Desktop app there is a menu item to do this. Branch -> Discard all changesSpock
just use "git restore <file>..." to discard changes in working directory)Husbandman
P
3148

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.

Preestablish answered 9/9, 2008 at 19:39 Comment(21)
I think it is better to use git reset --hard if you don't want to keep track of changesMukund
@KarimSamir: The question specifically asks about changes that are not in the index. The git reset command will discard changes in the index too.Preestablish
git checkout -- . is much fasterForgotten
Neither the git stash, nor any variety of git checkout will discard unstaged deletes. According to the output of git status, the actual correct answer here is some flavor git reset HEADKlingensmith
This pollutes the stash stack. git checkout -- . does the job with one command only.Gav
@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.Sutphin
@T.J.Crowder How in the world does Git know how to revert an untracked file? Does it just delete it?Accountable
@NathanArthur: Right. Git puts the untracked file in the stash, and then deletes it from the working tree. Restoring the stash copies the untracked file into the working tree, so it shows up as a new untracked file again.Tenderize
@ChrisWarth - git checkout -- does not work for me. Git status still shows untracked changes.Ledet
How can we the same using Source Tree.?Moten
git checkout -- fileVibraharp
In the same spirit of this answer, if you do not want to pollute the stash you can just create a new branch, switch back to the original branch, reset, then delete the newly created branch.Nunnery
You can create an alias for stash save --keep-index --include-untracked and use the stash as a recycle bin so you can always easily restore your changes if cleaning them up was a mistake.Refluent
@T.J.Crowder "Warning, doing this will permanently delete your files if you have any directory/* entries in your gitignore file." See this post: #836001Avert
I lost a bunch of stuff doing that once. Stashing untracked.Avert
git clean has a dry-run option, -nOpera
save option is deprecated in favour of git stash push. It differs from "stash push" in that it cannot take pathspecs, and any non-option arguments form the message. git-scm.comSchulte
@WojtekOwczarczyk So after using stash save --keep-index --include-untracked: How would you restore the changes if you realise that cleaning up was a mistake?Humo
git stash save && git stash drop is unusable as a general scripting solution, since it will not work (or do nasty things) if there's nothing to stash (and may drop a stash you may have wanted to keep). git checkout-index -afq && git clean -fdqx is the real deal!Bittencourt
This worked best for me since I can get my changes back if needed.Shluh
This command messed up my UAT server and now its coming back onlineIntercession
H
7217

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).

Harkey answered 9/9, 2008 at 19:37 Comment(32)
This seems to be the git canonical way. i.e. exactly what git tells you to do if you type git statusBoding
Doesn't work if there are untracked files. Git says error: The following untracked working tree files would be overwritten by checkout: ....Jenniejennifer
newbie question, what does "git checkout -- ." mean semantically?Contiguous
Michael: start with git clean -df to remove all untracked files first, as suggested in Mariusz' answer above.Burlesque
@Ninjack git checkout -- . means the same thing as git 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 do git checkout branch-name directory-or-file-name in general, you get the HEAD version of directory-or-file-name on branch branch-name.Gavrah
git checkout . is shorterHoly
IMO this suggestion doesn't handle deletes while stash variant does.Sheerlegs
"git checkout path/to/file/to/revert" what I have to add if I am on branch, and want contents of file to be replaced by last revision of that file on branch.Christiachristian
IMO 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.Amygdalate
@Amygdalate "update to HEAD" means cleaning the changes. HEAD is the revision that is currently checked out.Amalekite
yes, indeed, my bad. However git checkout HEAD does not actually discard the changes for me, so stash based solution is still preferred.Amygdalate
@alexykot: you have to specify a path with git checkout otherwise it will not kill changes you made! The trick with . is that a checkout with path also includes all subdirectories.Sire
I do this and get warnings about unmerged files. How do I discard these unmerged files?Illusive
This will only discard changes to existing files. It will not discard any new files that you have added since the last commit.Semiliterate
Interesting. For some reason, this doesn't actually work in a submodule. This has just been driving me nuts! I was CERTAIN that git clean -- . should do what I wanted it to do. Reading this answer and testing it confirmed it. But for some reason, IT DOESN'T WORK IN SUBMODULES! Why not? <sigh>Gracegraceful
I prefer the git stash save --keep-index solution, because it creates a commit. Even if I do a git stash drop immediately after the stash save the commit can still be restored. So the git stash save ... solution is safer just in case you discarded too much. E.g. using https://mcmap.net/q/11480/-how-do-i-recover-a-dropped-stash-in-gitFinance
Although it seems obvious, I think it's worth noting that this command should be run from the repository's top-level directory, as it cleans only the current working directory.Inman
Here's a scenario where "git checkout -- ." worked well: I had transferred a repo from Cygwin to Linux via a FAT-formatted USB drive. After transferring the data to Linux, "git status" and "git diff" showed signs of many file permission changes. There were also some other files present (notes and stuff). I used "git checkout -- ." to undo the file permission changes. Now git diff is clean and git status only shows the few files that have been added. The "clean" step from the other answer would be useful if I wanted to get rid of the untracked files.Motherwort
Is it always better using a double dash git checkout -- path/to/file/to/revert?Machination
@MichałTrybus to clean the whole repository regardless of where you are inside it, you can use git checkout -- :/ (I was looking for this myself!)Maishamaisie
I am very confused, this (git checkout -- .) just does not work. I still have all my changes (unstaged) files.Aila
That's strange PandaWood. I just used this solution and it did exactly what I wanted.Derris
Suppose I made changes in file A (state1), and the file has been modified at Master (state2). If I do git checkout A, to which state will it point now, the previous state1, or updated state2..??Preempt
Based on information elsewhere and personal experiment, git checkout -- . only considers overwriting files if a corresponding file already exists in the index. @MichaelIles It appears to me that the files causing you trouble must have had checked-in versions elsewhere.Delladelle
This removes all the uncommitted changes. If I want to remove only changes made after git add <filename>?Jaimiejain
@ABMagil: there is now a new command: git restore and it is the one now given by git status. See my 2019 updateClubhaul
To revert an entire sub folder, this works well for me git checkout -f -- path/to/revert/ whereas this does NOT work git checkout -f -- path/to/revert/* as any new files git doesn't have a record of.Evvoia
I had only un-staged changes and git checkout -- . worked for me. Thanks.Spic
I have new files in my repo that I want Git to delete. Neither of these options got rid of them, they only affect already-tracked files.Fachini
@Boding Apparently, git status doesn't always suggest a way to discard unstaged files. It isn't doing so for me (git 2.23.0). It does suggest using "git restore --staged <file>..." to unstage staged files.Aragon
This answer (git restore .) doesn't discard all unstaged files in the current working directory. In particular it doesn't discard new, untracked files. Just tested in git 2.23.0. The new untracked files are still there.Aragon
@Harkey I'm sure people who vote this up (including me) do it for the first recipe (given by something else). I suggest making this a community answer. There are now so many contributions from other people that the small part you had has become marginal.Refutative
P
3148

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.

Preestablish answered 9/9, 2008 at 19:39 Comment(21)
I think it is better to use git reset --hard if you don't want to keep track of changesMukund
@KarimSamir: The question specifically asks about changes that are not in the index. The git reset command will discard changes in the index too.Preestablish
git checkout -- . is much fasterForgotten
Neither the git stash, nor any variety of git checkout will discard unstaged deletes. According to the output of git status, the actual correct answer here is some flavor git reset HEADKlingensmith
This pollutes the stash stack. git checkout -- . does the job with one command only.Gav
@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.Sutphin
@T.J.Crowder How in the world does Git know how to revert an untracked file? Does it just delete it?Accountable
@NathanArthur: Right. Git puts the untracked file in the stash, and then deletes it from the working tree. Restoring the stash copies the untracked file into the working tree, so it shows up as a new untracked file again.Tenderize
@ChrisWarth - git checkout -- does not work for me. Git status still shows untracked changes.Ledet
How can we the same using Source Tree.?Moten
git checkout -- fileVibraharp
In the same spirit of this answer, if you do not want to pollute the stash you can just create a new branch, switch back to the original branch, reset, then delete the newly created branch.Nunnery
You can create an alias for stash save --keep-index --include-untracked and use the stash as a recycle bin so you can always easily restore your changes if cleaning them up was a mistake.Refluent
@T.J.Crowder "Warning, doing this will permanently delete your files if you have any directory/* entries in your gitignore file." See this post: #836001Avert
I lost a bunch of stuff doing that once. Stashing untracked.Avert
git clean has a dry-run option, -nOpera
save option is deprecated in favour of git stash push. It differs from "stash push" in that it cannot take pathspecs, and any non-option arguments form the message. git-scm.comSchulte
@WojtekOwczarczyk So after using stash save --keep-index --include-untracked: How would you restore the changes if you realise that cleaning up was a mistake?Humo
git stash save && git stash drop is unusable as a general scripting solution, since it will not work (or do nasty things) if there's nothing to stash (and may drop a stash you may have wanted to keep). git checkout-index -afq && git clean -fdqx is the real deal!Bittencourt
This worked best for me since I can get my changes back if needed.Shluh
This command messed up my UAT server and now its coming back onlineIntercession
C
2287

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.

Castled answered 29/8, 2012 at 18:28 Comment(25)
The other two answers don't actually work, this one did.Inoculum
this reverted to previous commit for some reasonRosales
@Rosales 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 --hardPersons
use -dff if the untracked directory is a git clone.Occupational
How to understand this command? -- .? Does it say checkout current last commit to current folder?Leschen
Be 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.Cultivar
As @Cultivar 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.Option
This is actually the correct answer. stash and checkout only applies for staged changes. git clean will doBenefaction
@Cultivar if those are in your repository then you have bigger problems.Larghetto
The 2 answers above don't work for unstaged changes.Only this one .Benevento
I suspect this works where the others don't perhaps because in my case I deleted not just files but also folders.Arriviste
Erorgh!!! Did I just delete my project folders with git clean -df? How do i get this back? Please help!!!! I dod a ls and I cannot see another folder that I had no intention to deleteBeecher
@user2441441: you're out of luck: you've cleaned files that were not under version control. Important files should always be under version control (not necessarily as part of the repository they're located in: you can put them in another, private repository and symlink to them). And files that are in a repo's working directory but not in the version controlled by that repo should always be .gitignored.Many
i've been using these commands for years. have a case now where none of them works. it just keeps saying "changes not staged for commit" and listing the same files. there are no errors when i do clean or checkout!Hypoglycemia
You have to be at the root of your git repository for this to work correctly.Nihi
Downvoted as it might remove your files. Not reliable solution.Tabbatha
To understand and get used to how git -df works, I recommend adding the n option if you are still new to running the command, i.e. git -dfn. This will run it in dry-run mode so you can see what will get deleted without it actually deleting and doing anything. If you are okay with the result, you would run it again without the n option.Faze
@Footniko, deleting untracked files may be part of the desired behavior, depending on what Readonly meant by "changes".Mensal
sometime we need to keep test files so this solution is dangerous, we don't want to stash at all to keep stash and just need us to avoid stash command to pull the data.Middelburg
A good explantation of git clean, options and usage: atlassian.com/git/tutorials/undoing-changes/git-cleanInstanter
One of my favorite answers on SO that I come back to. As with what some commenters mentioned above, everything has a time and place. My best use case for this is that I have just pushed a working version to the remote and now I started working on something which should not see the light of day and I just want to get back to the previous version and do not mind all the changes being (files/directories) being deleted.Promiscuity
This answer was a key part of my answer to Why git can't do hard/soft resets by path? / How to do git --hard/--soft resets by path.Glossary
Update: git clean -df and git checkout-index -fa is much better. I think git checkout-index -fa produces a more-desirable result than git checkout -- .. I've added these commands, with thorough explanations, to my answer here: Using git, how do you reset the working tree (local file system state) to the state of the index (“staged” files)?.Glossary
When using for the first time, try git clean -i to run in interactive mode. That should help prevent the deletion of config files and the like.Calliper
Just using git clean -df already worked for meYaroslavl
R
403

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
Regine answered 20/6, 2009 at 10:28 Comment(4)
+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.Vivle
git checkout -- does not work if you have only one branch. git checkout . always works.Ammon
Thank you so much! Finally an answer that ALWAYS works! This may be combined with git clean to also remove untracked files.Bittencourt
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.Ipoh
K
308
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

Kindred answered 7/12, 2011 at 13:9 Comment(3)
why this answer doesn't have all the votes? answered back in the 2011 and still correct.Aracelyaraceous
This should be the accepted answer.Verrocchio
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.Iddo
C
218

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 the git checkout command into git restore for files and git 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 of git 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 additional git clean -df.
Clubhaul answered 11/9, 2019 at 1:30 Comment(11)
I wanted to revert my unstaged changes only without affecting newly added files so a git restore . worked perfectly. Thanks.Edmonson
I did git restore <filename> and it worked perfectly.Cecrops
Worked fine for me.Prolactin
According to the man page git restore . restores all files in current directory, not in the whole repository.Lyon
You 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.Clubhaul
@bob 2.23 github.com/git/git/blob/master/Documentation/RelNotes/…Lyon
Thanks @Tycholiz. At the time the question was asked and the answer accepted, this new command did not exist :) So it makes a lot of sense that it is not the accepted answer :)Clubhaul
Thank you! That's a life-changer. I was previously doing git commit -m "wip" && git reset --hard && git reset --soft HEAD~1 && git reset.Merengue
Should be the accepted answer in September 2021!Coad
How do I delete untracked files that show up in git status without deleting untracked files that are in .gitignore?Fachini
@Aaron Franke: There is no automatic way to do this in Git. You can do it manually by deleting the relevant files, you can do it interactively with git clean -idf and select the relevant files, or you can write a bash script.Clubhaul
D
129

My favorite is

git checkout -p

That lets you selectively revert chunks.

See also:

git add -p
Dagenham answered 10/10, 2014 at 12:31 Comment(3)
I love the ability to see the actual change before it's discarded.Circumbendibus
This is what I use. git checkout -p and then "a" to accept all.Hilar
I've never thought about. That -p adds a nice extra layer of safety. Combine it with git clean -d to actually answer OP.Tenet
M
127

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.

Mesotron answered 28/4, 2016 at 19:46 Comment(5)
+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 to git reset --hard HEAD and should work whichever is the current directory...)Vu
Also regarding the first command git clean -dfx, here is a tip I use to be on the safe side before running it: just run git clean -d -x -n before, to display the list of files-to-be-removed, then confirm the operation by running git clean -d -x -f (I put the argument -n, resp. -f in the end to be able to quickly change it in a terminal)Vu
Quick note that this is unreversable, and if you have files in .gitignore you will lose them. So consider backing up your project before this.Estevez
@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!Vu
How do I delete untracked files that show up in git status without deleting untracked files that are in .gitignore?Fachini
A
86

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 interactive clean, 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.
Adaptive answered 18/3, 2018 at 0:19 Comment(2)
This will exactly convert your changes and discard newly added files from previous commit.Breadbasket
will it remove the newly added files? or just undo the changes in the old unstaged files?Amplitude
M
68

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

http://git-scm.com/docs/git-stash

Medwin answered 12/4, 2017 at 9:27 Comment(4)
Twice I've come here, read this answer, and forgotten the . at the end. To future me: the period is essential!Nihi
I needed to get rid of all local changes in a sub directory, without blowing away every other change. This answer helped a lot, thanksClaudie
Please describe what the two commands do. It's really unhelpful to have no explanation.Gerrit
excellent. 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.Lidia
O
66

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:

  1. 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

  2. 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.

Oecology answered 13/8, 2012 at 21:31 Comment(0)
C
52

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
Compatriot answered 28/7, 2011 at 5:27 Comment(0)
J
48

As you type git status, (use "git checkout -- ..." to discard changes in working directory) is shown.

e.g. git checkout -- .

Jacobus answered 17/5, 2016 at 11:27 Comment(2)
Downvoted 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 keepYasui
Of 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..Praise
M
46

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

Magner answered 11/9, 2015 at 11:59 Comment(0)
L
45

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.

Lithuanian answered 17/5, 2014 at 2:28 Comment(1)
This would discard changes in the index!! (And the OP requires to leave them as is.)Sire
H
39

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}
Hoodoo answered 7/8, 2015 at 21:15 Comment(8)
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.Bria
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"Hoodoo
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 :)Bria
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 againHoodoo
If you haven't committed or staged a new file git completely ignores it and won't touch it. It doesn't want to accidentally delete something you might want. You can see here at --untracked-files[=<mode>] that untracked files are shown by default in git status, and you can tell it not to show them if it bothers you! For the record, git add --all will stage the files ready for commit, at which point git recognises them (hence git reset --hard will then work). git clean removes untracked files see hereBria
Thanks - So basically if you git add --all, you can reset, or you have to git add --all , then get clean Guess clean is a few less characters ;)Hoodoo
Pretty much, although if there are untracked files lingering I tend to just leave them alone. Paranoia and all that, makes me think I'll break something :DBria
A nice little variation of this I like is git reset --hard @{u} which resets the branch to wherever the current remote-tracking branch isFabrice
R
36

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.

Ricardoricca answered 14/10, 2011 at 21:7 Comment(0)
S
34

To do a permanent discard: git reset --hard

To save changes for later: git stash

Someday answered 3/7, 2019 at 12:41 Comment(0)
R
25

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 :)

Rejection answered 8/9, 2016 at 6:19 Comment(2)
Note: git stash -u will soon (Git 2.14.x/2.15, Q3 2017) evolve a bit: https://mcmap.net/q/11482/-why-can-39-t-stash-be-applied-to-the-working-directoryMere
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.Gowan
R
23

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

Resoluble answered 24/4, 2015 at 12:19 Comment(0)
B
21

you have a very simple git command git checkout .

Bismarck answered 27/8, 2019 at 7:58 Comment(0)
P
17

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.

Popover answered 5/2, 2016 at 0:59 Comment(1)
This will also discard everything in the index (not just things not in the index), which is beyond what the OP is asking for.Crotchet
S
16

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

Soapbox answered 5/9, 2013 at 9:38 Comment(4)
Beware though, that the git ignored content will not retain it's original permissions! Hence it can cause a security risk.Constantina
@Constantina You're wrong, please read git help clean "-d Remove untracked directories in addition to untracked files."Soapbox
Why did you set all your files to be world read/write? Not good practice.Baseborn
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.Slovenly
J
16
cd path_to_project_folder  # take you to your project folder/working directory 
git checkout .             # removes all unstaged changes in working directory
Jemadar answered 30/5, 2014 at 9:26 Comment(0)
G
15

Final working solution

git restore .
git clean -f   
git clean -df (if you have folders in your local changes)
Gymnosperm answered 1/3, 2023 at 8:29 Comment(0)
P
14

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.

Platoon answered 14/7, 2016 at 7:3 Comment(0)
S
10

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).

Spermatophyte answered 15/6, 2012 at 8:55 Comment(0)
S
10

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

Squaw answered 8/2, 2017 at 11:58 Comment(1)
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.Piecedyed
V
10

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

Vallee answered 31/7, 2017 at 15:57 Comment(0)
R
10
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 )

Rinee answered 19/7, 2022 at 16:46 Comment(0)
J
9

What follows is really only a solution if you are working with a fork of a repository where you regularly synchronize (e.g. pull request) with another repo. Short answer: delete fork and refork, but read the warnings on github.

I had a similar problem, perhaps not identical, and I'm sad to say my solution is not ideal, but it is ultimately effective.

I would often have git status messages like this (involving at least 2/4 files):

$ git status
# Not currently on any branch.
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       modified:   doc/PROJECT/MEDIUM/ATS-constraint/constraint_s2var.dats
#       modified:   doc/PROJECT/MEDIUM/ATS-constraint/parsing/parsing_s2var.dats
#
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   doc/PROJECT/MEDIUM/ATS-constraint/constraint_s2Var.dats
#       modified:   doc/PROJECT/MEDIUM/ATS-constraint/parsing/parsing_s2Var.dats

A keen eye will note that these files have dopplegangers that are a single letter in case off. Somehow, and I have no idea what led me down this path to start with (as I was not working with these files myself from the upstream repo), I had switched these files. Try the many solutions listed on this page (and other pages) did not seem to help.

I was able to fix the problem by deleting my forked repository and all local repositories, and reforking. This alone was not enough; upstream had to rename the files in question to new filenames. As long as you don't have any uncommited work, no wikis, and no issues that diverge from the upstream repository, you should be just fine. Upstream may not be very happy with you, to say the least. As for my problem, it is undoubtedly a user error as I'm not that proficient with git, but the fact that it is far from easy to fix points to an issue with git as well.

Jeffery answered 5/1, 2014 at 4:53 Comment(0)
I
9

You could create your own alias which describes how to do it in a descriptive way.

I use the next alias to discard changes.


Discard changes in a (list of) file(s) in working tree

discard = checkout --

Then you can use it as next to discard all changes:

discard .

Or just a file:

discard filename

Otherwise, if you want to discard all changes and also the untracked files, I use a mix of checkout and clean:

Clean and discard changes and untracked files in working tree

cleanout = !git clean -df && git checkout -- .

So the use is simple as next:

cleanout

Now is available in the next Github repo which contains a lot of aliases:

Inhospitality answered 5/6, 2017 at 4:44 Comment(0)
C
8

When you want to transfer a stash to someone else:

# add files
git add .  
# diff all the changes to a file
git diff --staged > ~/mijn-fix.diff
# remove local changes 
git reset && git checkout .
# (later you can re-apply the diff:)
git apply ~/mijn-fix.diff

[edit] as commented, it ís possible to name stashes. Well, use this if you want to share your stash ;)

Constantina answered 8/7, 2013 at 15:7 Comment(1)
Actually Git stash can have a title. For instance git stash save "Feature X work in progress".Samala
M
7

If you are in case of submodule and no other solutions work try:

  • To check what is the problem (maybe a "dirty" case) use:

    git diff

  • To remove stash

    git submodule update

Misreckon answered 1/10, 2015 at 21:32 Comment(0)
I
7

Just as a reminder, newer versions of git has the restore command, which also is a suggestion when typing git status when you have changed files:

(use "git add ..." to update what will be committed)

(use "git restore ..." to discard changes in working directory)

So git 'restore' is the modern solution to this. It is always a good idea to read the suggestions from git after typing 'git status' :-)

Impulsion answered 18/9, 2020 at 6:3 Comment(2)
This just repeat https://mcmap.net/q/11279/-how-do-i-discard-unstaged-changes-in-git.Mere
It sure is, just stating the obvious and that git tries to help with the comments from a 'git status' call :-)Impulsion
H
6

If all the staged files were actually committed, then the branch can simply be reset e.g. from your GUI with about three mouse clicks: Branch, Reset, Yes!

So what I often do in practice to revert unwanted local changes is to commit all the good stuff, and then reset the branch.

If the good stuff is committed in a single commit, then you can use "amend last commit" to bring it back to being staged or unstaged if you'd ultimately like to commit it a little differently.

This might not be the technical solution you are looking for to your problem, but I find it a very practical solution. It allows you to discard unstaged changes selectively, resetting the changes you don't like and keeping the ones you do.

So in summary, I simply do commit, branch reset, and amend last commit.

Helot answered 20/3, 2015 at 15:38 Comment(0)
P
6

If you want to restore unstaged files use git restore --staged .

Paulinapauline answered 8/7, 2021 at 15:36 Comment(0)
E
5

None of the solutions work if you just changed the permissions of a file (this is on DOS/Windoze)

Mon 23/11/2015-15:16:34.80 C:\...\work\checkout\slf4j+> git status
On branch SLF4J_1.5.3
Changes not staged for commit:
  (use "git add ..." to update what will be committed)
  (use "git checkout -- ..." to discard changes in working directory)

        modified:   .gitignore
        modified:   LICENSE.txt
        modified:   TODO.txt
        modified:   codeStyle.xml
        modified:   pom.xml
        modified:   version.pl

no changes added to commit (use "git add" and/or "git commit -a")

Mon 23/11/2015-15:16:37.87 C:\...\work\checkout\slf4j+> git diff
diff --git a/.gitignore b/.gitignore
old mode 100644
new mode 100755
diff --git a/LICENSE.txt b/LICENSE.txt
old mode 100644
new mode 100755
diff --git a/TODO.txt b/TODO.txt
old mode 100644
new mode 100755
diff --git a/codeStyle.xml b/codeStyle.xml
old mode 100644
new mode 100755
diff --git a/pom.xml b/pom.xml
old mode 100644
new mode 100755
diff --git a/version.pl b/version.pl
old mode 100644
new mode 100755

Mon 23/11/2015-15:16:45.22 C:\...\work\checkout\slf4j+> git reset --hard HEAD
HEAD is now at 8fa8488 12133-CHIXMISSINGMESSAGES MALCOLMBOEKHOFF 20141223124940 Added .gitignore

Mon 23/11/2015-15:16:47.42 C:\...\work\checkout\slf4j+> git clean -f

Mon 23/11/2015-15:16:53.49 C:\...\work\checkout\slf4j+> git stash save -u
Saved working directory and index state WIP on SLF4J_1.5.3: 8fa8488 12133-CHIXMISSINGMESSAGES MALCOLMBOEKHOFF 20141223124940 Added .gitignore
HEAD is now at 8fa8488 12133-CHIXMISSINGMESSAGES MALCOLMBOEKHOFF 20141223124940 Added .gitignore

Mon 23/11/2015-15:17:00.40 C:\...\work\checkout\slf4j+> git stash drop
Dropped refs/stash@{0} (cb4966e9b1e9c9d8daa79ab94edc0c1442a294dd)

Mon 23/11/2015-15:17:06.75 C:\...\work\checkout\slf4j+> git stash drop
Dropped refs/stash@{0} (e6c49c470f433ce344e305c5b778e810625d0529)

Mon 23/11/2015-15:17:08.90 C:\...\work\checkout\slf4j+> git stash drop
No stash found.

Mon 23/11/2015-15:17:15.21 C:\...\work\checkout\slf4j+> git checkout -- .

Mon 23/11/2015-15:22:00.68 C:\...\work\checkout\slf4j+> git checkout -f -- .

Mon 23/11/2015-15:22:04.53 C:\...\work\checkout\slf4j+> git status
On branch SLF4J_1.5.3
Changes not staged for commit:
  (use "git add ..." to update what will be committed)
  (use "git checkout -- ..." to discard changes in working directory)

        modified:   .gitignore
        modified:   LICENSE.txt
        modified:   TODO.txt
        modified:   codeStyle.xml
        modified:   pom.xml
        modified:   version.pl

no changes added to commit (use "git add" and/or "git commit -a")

Mon 23/11/2015-15:22:13.06 C:\...\work\checkout\slf4j+> git diff
diff --git a/.gitignore b/.gitignore
old mode 100644
new mode 100755
diff --git a/LICENSE.txt b/LICENSE.txt
old mode 100644
new mode 100755
diff --git a/TODO.txt b/TODO.txt
old mode 100644
new mode 100755
diff --git a/codeStyle.xml b/codeStyle.xml
old mode 100644
new mode 100755
diff --git a/pom.xml b/pom.xml
old mode 100644
new mode 100755
diff --git a/version.pl b/version.pl
old mode 100644
new mode 100755

The only way to fix this is to manually reset the permissions on the changed files:

Mon 23/11/2015-15:25:43.79 C:\...\work\checkout\slf4j+> git status -s | egrep "^ M" | cut -c4- | for /f "usebackq tokens=* delims=" %A in (`more`) do chmod 644 %~A

Mon 23/11/2015-15:25:55.37 C:\...\work\checkout\slf4j+> git status
On branch SLF4J_1.5.3
nothing to commit, working directory clean

Mon 23/11/2015-15:25:59.28 C:\...\work\checkout\slf4j+>

Mon 23/11/2015-15:26:31.12 C:\...\work\checkout\slf4j+> git diff

Erythrocytometer answered 23/11, 2015 at 4:30 Comment(1)
There was another solution to me: 'Telling git to ignore changed permission: git config core.fileMode false'. Maybe someone is helped with thatMenes
C
1

Just use:

git stash -k -u

This will stash unstaged changes and untracked files (new files) and keep staged files.

It's better than reset/checkout/clean, because you might want them back later (by git stash pop). Keeping them in the stash is better than discarding them.

Canonry answered 23/12, 2016 at 17:33 Comment(0)
K
1

To discard changes in working directory use git checkout -- <file> -- means changes in current branch references:-

Kwok answered 31/10, 2022 at 9:18 Comment(2)
git checkout is obsolete since Git 2.23 (Q3 2019). You would use git restore -- . now (in complement git git clean -df)Mere
It seems that regarding the old syntax (git checkout …), you answer is subsumed by previous ones, e.g. @MartinG's one; and for the new syntax (git restore …), see also the answer @Mere mentioned.Vu

© 2022 - 2024 — McMap. All rights reserved.