1247

I'm trying to undo all changes since my last commit. I tried git reset --hard and git reset --hard HEAD after viewing this post. I responds with head is now at 18c3773... but when I look at my local source all the files are still there. What am I missing?

CommonSenseCode
  • 23,522
  • 33
  • 131
  • 186
Antarr Byrd
  • 24,863
  • 33
  • 100
  • 188
  • 6
    This is a great resource straight from Github: [How to undo \(almost\) anything with Git](https://github.com/blog/2019-how-to-undo-almost-anything-with-git) – jasonleonhard Feb 03 '17 at 21:14
  • 4
    Easy to understand and simple to read: https://git-scm.com/book/en/v2/Git-Basics-Undoing-Things – WelcomeTo Dec 09 '19 at 15:25

16 Answers16

2395
  • This will unstage all files you might have staged with git add:

    git reset
    
  • This will revert all local uncommitted changes (should be executed in repo root):

    git checkout .
    

    You can also revert uncommitted changes only to particular file or directory:

    git checkout [some_dir|file.txt]
    

    Yet another way to revert all uncommitted changes (longer to type, but works from any subdirectory):

    git reset --hard HEAD
    
  • This will remove all local untracked files, so only git tracked files remain:

    git clean -fdx
    

    WARNING: -x will also remove all ignored files, including ones specified by .gitignore! You may want to use -n for preview of files to be deleted.


To sum it up: executing commands below is basically equivalent to fresh git clone from original source (but it does not re-download anything, so is much faster):

git reset
git checkout .
git clean -fdx

Typical usage for this would be in build scripts, when you must make sure that your tree is absolutely clean - does not have any modifications or locally created object files or build artefacts, and you want to make it work very fast and to not re-clone whole repository every single time.

mvp
  • 111,019
  • 13
  • 122
  • 148
  • @turibe that is right. I had to start my project several times because it was removing all downloaded dependencies and my .idea folder. Need a better solution. – Eres Sep 07 '18 at 23:30
  • 2
    @EresDev, you don't have to execute `git clean`, it will undo uncommitted changes but keep all untracked or added files. But, it may affect build outcome because some of untracked files may be interfering. E.g. what if your .idea directory was corrupted? – mvp Sep 08 '18 at 00:47
  • `git reset` tells me I have changes I need to save –  Oct 18 '19 at 22:06
  • 55
    running `git clean -fdx` deleted my `node_modules` and `.env`, great – fires3as0n Feb 12 '20 at 14:21
  • 14
    @fires3as0n What else did you expect? This was bound to happen. There is a warning in the answer too. – Rishav Feb 20 '20 at 13:53
  • Never undo uncommitted changes with reset. It will ruin your other branches in case you rebase. – Dinu Nicolae Feb 27 '20 at 07:56
  • @DinuNicolae: it will not ruin other branches. But yes, don't let kids play with knife, they can get hurt. That said, we can't get around without using knife. – mvp Feb 27 '20 at 09:15
  • @mvp if you reset and then change branch and rebase on the reseted branch this will hurt. Reset is useful, but should not be used to drop uncommitted changes. In the case of dropping uncommitted changes just stash and drop the stash. – Dinu Nicolae Feb 27 '20 at 13:42
  • 5
    for all those who are googling why "git checkout ." does not work, thank you for remaining that it "should be executed in repo root". – Kamil Czerski Mar 24 '20 at 19:49
  • @DinuNicolae - I've never seen this problem. Not that I don't trust your judgement, but I need to see this happening. – luis.espinal May 01 '21 at 10:29
  • 3
    The comment about git clean is misleading. Yes, I should have read the warning, yes I am still mad that I lost my .env and some other stuff. But most importantly, I think it's completely missing the point. I want to remove the files that show as unstaged or untracked in `git status`. So this variant of `git clean` makes no sense for that purpose. – Luxalpa Jan 07 '22 at 10:29
  • Not entirely exact, `git checkout .` will not revert all uncommited changes, it will only overwrite the working tree with the index. Thus changes in the staging area remain unchanged. You need to type `git checkout HEAD .` However, even this will not revert untracked changes, of course. – smartly Sep 11 '22 at 18:49
  • @smartly, `git checkout .` yields exactly the same outcome as `git checkout HEAD .` - it will revert any locally uncommitted changes – mvp Sep 11 '22 at 20:48
  • @mvp well, I tested it second time now just to be sure and yes the staging area remains untouched. So it is not the same. Even official doc says: "When the (most often a commit) is not given, overwrite working tree with the contents in the index." So, obviously the index remains untouched. If you want to revert also the index, you have to add the param, or HEAD. Also doc says so: "When the is given, overwrite both the index and the working tree with the contents at the " – smartly Sep 11 '22 at 22:45
  • @smartly, this is not what I observe. I've been using this for 10+ years, never failed to do what is asked for – mvp Sep 11 '22 at 23:31
  • @mvp hm who knows why is that, maybe different default configs in newer versions? anyway, just added my five cents for whoever else might have the same problem – smartly Sep 13 '22 at 19:53
  • Why the hell would you suggest : -x to remove all ignored files in the main answer ! the guys didn't ask for that... it should be put as a remark and not in your main answer !!! please change (the comment is +50 upvoted !), Please change your answer – KADEM Mohammed Apr 18 '23 at 01:26
220

If you wish to "undo" all uncommitted changes simply run:

git stash
git stash drop

If you have any untracked files (check by running git status), these may be removed by running:

Warning: This will remove all non-commited data, even what is in .gitignore

git clean -fdx

git stash creates a new stash which will become stash@{0}. If you wish to check first you can run git stash list to see a list of your stashes. It will look something like:

stash@{0}: WIP on rails-4: 66c8407 remove forem residuals
stash@{1}: WIP on master: 2b8f269 Map qualifications
stash@{2}: WIP on master: 27a7e54 Use non-dynamic finders
stash@{3}: WIP on blogit: c9bd270 some changes

Each stash is named after the previous commit messsage.

Alex
  • 2,784
  • 2
  • 32
  • 46
Abram
  • 39,950
  • 26
  • 134
  • 184
  • 7
    A good solution indeed but you need to stage changes using `git add .` before `git stash` because it was showing me uncommited changes even after `git stash` – Eres Sep 07 '18 at 23:42
  • 1
    You can also do `git stash --include-untracked` to get all files then there's no need to do the clean which gets rid of ignored files. – esteuart Mar 02 '21 at 23:59
  • 5
    `git stash -u` is better for this purpose. And never run `git clean -fdx`, it will delete files that are gitignored. – Luxalpa Jan 07 '22 at 10:31
77

What I do is

git add . (adding everything)
git stash 
git stash drop

One liner: git add . && git stash && git stash drop

A shorter version as pointed out by M. Justin

git stash -u && git stash drop

Ralph
  • 1,480
  • 11
  • 16
39

Adding this answer because the previous answers permanently delete your changes

The Safe way

git stash -u

Explanation: Stash local changes including untracked changes (-u flag). The command saves your local modifications away and reverts the working directory to match the HEAD commit.

Want to recover the changes later?

git stash pop

Explanation: The command will reapply the changes to the top of the current working tree state.

Want to permanently remove the changes?

git stash drop

Explanation: The command will permanently remove the stashed entry

Link to git stash documentation

bsheps
  • 1,438
  • 1
  • 15
  • 26
25

there is also git stash - which "stashes" your local changes and can be reapplied at a later time or dropped if is no longer required

more info on stashing

keshav
  • 866
  • 11
  • 19
17

Another option to undo changes that weren't staged for commit is to run:

git restore <file>

To discard changes in the working directory.

Rot-man
  • 18,045
  • 12
  • 118
  • 124
12

I'm using source tree.... You can do revert all uncommitted changes with 2 easy steps:

1) just need to reset the workspace file status

enter image description here 2) select all unstage files (command +a), right click and select remove

enter image description here

It's that simple :D

user1872384
  • 6,886
  • 11
  • 61
  • 103
  • If you reset and then change branch and rebase on the reseted branch this will hurt. Reset is useful, but should not be used to drop uncommitted changes. In the case of dropping uncommitted changes just stash and drop the stash. – Dinu Nicolae Feb 27 '20 at 13:46
  • Don't rely on UI tools. Learn to use the CLI because when things break (and UI front ends always do), or you are forced to work through a remote SSH connection, the CLI is what will save ya ;) – luis.espinal May 01 '21 at 10:30
11

If you want to "undo" all uncommitted changes or local changes simply run:

git add . 
git stash 
git stash drop
git clean -fdx
M. Justin
  • 14,487
  • 7
  • 91
  • 130
Santosh Kumar
  • 552
  • 4
  • 13
10

git restore [filename_path]

For example I need to discard my last changes in index.html file:

git restore /usr/myPC/folder/index.html
Obsidian
  • 3,719
  • 8
  • 17
  • 30
Single96
  • 101
  • 1
  • 4
8

For those who reached here searching if they could undo git clean -f -d , by which a file created in eclipse was deleted,

You can do the same from the UI using "restore from local history" for ref:Restore from local history

iwein
  • 25,788
  • 10
  • 70
  • 111
Abdul Rahman K
  • 664
  • 5
  • 16
  • 3
    I did not down vote however your answer is less than clear on your intent; it would help if you were to reword the first sentence in the answer. – Mark Schultheiss Aug 09 '16 at 20:46
8

There are three options in Git that help to undo your local changes.

To view the changes that have been made in your working directory, you should run git status:

git status

Undoing changes with git stash
To discard all local changes, but also to save them for later use, you can run the git stash command:

git stash

Undoing changes with git checkout
To discard local changes to a file permanently, you can run:

git checkout -- <file>

Undoing changes with git reset
To discard all local changes to all the files permanently, you can do:

git reset --hard

SOURCE: https://www.w3docs.com/snippets/git/how-to-discard-unstaged-changes.html

S.B
  • 13,077
  • 10
  • 22
  • 49
Xab Ion
  • 1,105
  • 1
  • 11
  • 20
6

States transitioning from one commit to new commit

0. last commit,i.e. HEAD commit
1. Working tree changes, file/directory deletion,adding,modification.
2. The changes are staged in index
3. Staged changes are committed

Action for state transitioning

0->1: manual file/directory operation
1->2: git add .
2->3: git commit -m "xxx"

Check diff

0->1: git diff
0->2: git diff --cached
0->1, and 0->2: git diff HEAD
last last commit->last commit: git diff HEAD^ HEAD

Revert to last commit

2->1: git reset
1->0: git checkout .     #only for tracked files/directories(actions include modifying/deleting tracked files/directories)
1->0: git clean -fdx     #only for untracked files/directories(action includes adding new files/directories)
2->1, and 1->0: git reset --hard HEAD

Equivalent of git clone, without re-downloading anything

git reset && git checkout . && git clean -fdx
TheTechRobo the Nerd
  • 1,249
  • 15
  • 28
Zii
  • 359
  • 4
  • 10
  • 1
    I don't see how this relates to question asked. This is just series of strange recipes, without any real substance. – mvp May 10 '18 at 09:31
6

Use this to remove unwanted changes after last commit.

git reset --hard HEAD
Al-Amin Sarker
  • 508
  • 3
  • 16
2

The following defines a reusable Git command alias to remove any local changes, which can then be used any time in the future to delete any uncommitted changes:

git config --global alias.remove-changes '!git stash push --include-untracked && git stash drop'

Using the alias is straightforward:

git remove-changes

The alias pushes all changes to the stash (including uncommitted ones) using git stash push --include-untracked, then drops the newly created stash entry using git stash drop.

M. Justin
  • 14,487
  • 7
  • 91
  • 130
  • 1
    This should be the answer. – luis.espinal May 01 '21 at 10:32
  • Can I achieve this behaviour without stashing (its slow, excessive)? The answer is really great. `git clean -fxd`, `git reset`, `git checkout .` do not remove `untracked files`. What this solution does. Moreover `git clean -fxd` removed all my configs and installed modules :( – avdotion Oct 19 '21 at 06:28
  • I'm using `git add -A`, `git reset --hard HEAD`. – avdotion Oct 19 '21 at 06:51
2
# Navigate to project root, `.` works too.
git restore *

git status showed that I had some files that were changed, but I wanted to get rid of those and start a new branch. Until today, I had been using git reset approach, which I do like for jumping back to other specific commits.

https://www.git-tower.com/learn/git/commands/git-restore/

Kermit
  • 4,922
  • 4
  • 42
  • 74
2

I just stumbled upon a github repository that made undoing something in git very easy. its called ugit

just type ugit and it provides to you a list of options that you can choose to undo that git command

enter image description here

badger
  • 2,908
  • 1
  • 13
  • 32