Undo 'git add' before commit
28
I mistakenly added files using the command 

I have not yet run git commit. Is there a way to undo this or remove these files from the commit?
improve this question | comment
Aileen MacGyver Created at: 2013-11-13 17:07:37 UTC By Aileen MacGyver
The second answer is the correct one, not the first: 'git rm -r --cached .' - Russell Hane
The comment on the accepted answer works, and is in fact what is documented when you run git status. Just do git reset HEAD file. - Laila Lockman
Tip: I just noticed that if you do git status, it will tell you exactly what command to enter to undo the last thing you did. Handy! - Quentin Jerde
But "git reset HEAD file" doesn't work... I get the "ambiguous argument 'HEAD': unknown revision or path not in the working tree."  What is the reason behind not using the "git rm -r --cached" - Mrs. Elyssa Cummerata
@BasilMusa The second answer sorted by age, or votes? At which point in time? And is git rm -r --cached the 'first' (incorrect) or 'second' (correct) answer to which you refer? - Liza Langosh
26 Answers
0
As this is your first commit, you can run this instead: 

rm -fr .git


And start again from scratch! (this is not the first time I'm, going through this cycle of init, add, commit, sh!t, google add undo, oh, why not remove the repository and start again)

:)
0
To add to the accepted anwser: if your mistakenly added file was huge, you'll probably notice that, even after removing it from the index with 'git reset', it still seems to occupy space in the .git directory. This is nothing to be worried about, the file is indeed still in the repository, but only as a "loose object", it will no be copied to other repositories (via clone, push), and the space will be eventually reclaimed - though perhaps not very soon. If you are anxious, you can run:

git gc --prune=now


Update (what follows is my attempt to clear some confusion that can arise from the most upvoted answers):

So, which is the real undo of git add? 

Is it git reset HEAD <file> or git rm --cached <file>? 

Strictly speaking, and if I'm not mistaken: none. git add cannot be undone -safely, in general.

Recall first what git add <file>  does:

If <file> was not previously tracked, git add  adds it to the cache, with its current content.
If <file> was already tracked, git add  saves the current content (snapshot, version) to the cache. Note that, in GIT parlance, we say that we're "adding" the file, (not mere "updating" it), because two different versions (snapshots) of a file are regarded as two different "items": we are adding a new item to the cache, to be commited later.
In light of this, the question is slightly ambiguous: 


  I mistakenly added files using the command...


The OP seems to be thinking of case 1 (untracked file), so that the "undo" should remove the file (not just the current contents) from the tracked items. If this is the case, then it's ok to run  git rm --cached <file>.  

But we could also run git reset HEAD <file>; and this is in general preferrable, because it works in both scenarios: it also does the undoing when we wrongly added a version of an already tracked item.

Two caveats. 

First: The only scenario in which git rm --cached <file> works and the other doesn't, is for a new repository (no commits), as pointed out in the answer. But, really, this a practically irrelevant case.

Second: Then why do I claim that git reset HEAD <file> is not a true undo of git add? Because it isn't: it doesn't magically recover the previously cached file content, it just syncs it from the HEAD. If our wrong git add overwrote a previous staged uncommited version, we can't recover it. Hence: no undo.

Example:

$ git init
$ echo "version 1" > file.txt
$ git add file.txt   # first add  of file.txt
$ git commit -m 'first commit'
$ echo "version 2" > file.txt
$ git add  file.txt   # stage (don't commit) "version 2" of file.txt
$ git diff --cached file.txt
-version 1
+version 2
$ echo "version 3" > file.txt   
$ git diff  file.txt
-version 2
+version 3
$ git add  file.txt    # oops we didn't mean this
$ git reset HEAD file.txt  # undo ?
$ git diff --cached file.txt  # no dif, of course. stage == HEAD
$ git diff file.txt   # we have lost irrevocably "version 2"
-version 1
+version 3


Of course, all this is rather irrelevant if we follow the usual/lazy workflow of doing 'git add' only for adding new files (case 1), and the case is 2 done together with the commit, git commit -a
0
To reset every file in a particular folder (and its subfolders), you can use the following command:

git reset *

0
You want:

git rm --cached <added_file_to_undo>


Reasoning:

When I was new this, I first tried

git reset .


(to undo my entire initial add), only to get this (not so) helpful message:

fatal: Failed to resolve 'HEAD' as a valid ref.


It turns out that this is because the HEAD ref (branch?) doesn't exist until after the first commit. That is, you'll run into the same beginner's problem as me if your workflow, like mine, was something like:

cd to my great new project directory to try out Git, the new hotness
git init
git add .
git status

... lots of crap scrolls by ...

=> Damn, I didn't want to add all of that.
google "undo git add"

=> find Stack Overflow - yay
git reset .

=>    fatal: Failed to resolve 'HEAD' as a valid ref.
It further turns out that there's a bug logged against the unhelpfulness of this in the mailing list.

And that the correct solution was right there in the Git status output (which, yes, I glossed over as 'crap)


...
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
...



And the solution indeed is to use git rm --cached FILE.

Note the warnings elsewhere here - git rm deletes your local working copy of the file, but not if you use --cached.  Here's the result of git help rm:


  --cached
      Use this option to unstage and remove paths only from the index.
      Working tree files, whether modified or not, will be left.


I proceed to use

git rm --cached .


to remove everything and start again. Didn't work though, because while add . is recursive, turns out rm needs -r to recurse. Sigh.

git rm -r --cached .


Okay, now I'm back to where I started. Next time I'm going to use -n to do a dry run and see what will be added:

git add -n .


I zipped up everything to a safe place before trusting git help rm about the --cached not destroying anything (and what if I misspelled it).
0
If you type:

git status


git will tell you what is staged, etc, including instructions on how to unstage:

use "git reset HEAD <file>..." to unstage


I find git does a pretty good job of nudging me to do the right thing in situations like this.

Note: Recent git versions (1.8.4.x) have changed this message:

(use "git rm --cached <file>..." to unstage)

0
As per many of the other answers you can use git reset

BUT:

I found this great little post that actually adds the Git command (well an alias) for "git unadd", git unadd:

Simply,

git config --global alias.unadd "reset HEAD"


Now you can

git unadd foo.txt bar.txt

0
This command will unstash your changes:

git reset HEAD filename.txt


You can also use 

git add -p 


to add parts of files.
0
To clarify: git add moves changes from the current working directory to the staging area (index). 

This process is called staging. So the most natural command to stage the changes (changed files) is the obvious one:

git stage


git add is just an easier to type alias for git stage

Pity there is no git unstage nor git unadd commands. The relevant one is harder to guess or remember,
but is pretty obvious:

git reset HEAD --


We can easily create an alias for this:

git config --global alias.unadd 'reset HEAD --'
git config --global alias.unstage 'reset HEAD --'


And finally, we have new commands:

git add file1
git stage file2
git unadd file2
git unstage file1


Personally I use even shorter aliases:

git a #for staging
git u #for unstaging

0
DO NOT USE "git rm" as suggested in another answer. This is used to stop tracking a file, and depending on the flags, it may even remove it from your file system which is not what you want to do.
0
Please don't use git remove or git rm. It will remove the file. git reset FILE is the correct command.
0
git rm --cached . -r


will "un-add" everything you've added from your current directory recursively 
0
Run

git gui


and remove all the files manually or by selecting all of them and clicking on the unstage from commit button.
0
If you're on your initial commit and you can't use git reset, just declare "Git bankruptcy" and delete the .git folder and start over
0
Note that if you fail to specify a revision then you have to include a separator. Example from my console:

$ git reset <path_to_file>
fatal: ambiguous argument '<path_to_file>': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions
$ git reset -- <path_to_file>
Unstaged changes after reset:
M   <path_to_file>


(git version 1.7.5.4)
0
git has commands for every action imaginable, but needs extensive knowledge to get things right and because of that it is counter-intuitive at best...

What you did before:

changed a <file> and used git add . or git add <file>
What you want:

remove <file> from index, but keep it versioned and left with uncommitted changes in working copy:git reset head <file>
reset <file> to last state from head, undoing changes and removing it from the index:
(Think svn revert <file> IIRC.)git reset head <file>git checkout <file>
(if you have a <branch> named like <file>, use: git checkout -- <file>)
This is needed since git reset --hard head won't work with single files.
remove <file> from index and versioning, keeping the unversioned file with changes in working copy:git rm --cached <file>
remove <file> from working copy and versioning completely:git rm <file>
0
Here's a way to avoid this vexing problem when you start a new project:

Create the main directory for your new project.
Run git init.
Now create a .gitignore file (even if it's empty).
Commit your .gitignore file.
Git makes it really hard to do git reset if you don't have any commits.  If you create a tiny initial commit just for the sake of having one, after that you can git add -A and git reset as many times as you want in order to get everything right.

Another advantage of this method is that if you run into line-ending troubles later and need to refresh all your files, it's easy:

Check out that initial commit.  This will remove all your files.
Then check out your most recent commit again.  This will retrieve fresh copies of your files, using your current line-ending settings.
0
Use git add -i to remove just-added files from your upcoming commit.  Example:

Adding the file you didn't want:

$ git add foo
$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       new file:   foo
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
# [...]#


Going into interactive add to undo your add (the commands typed at git here are "r" (revert), "1" (first entry in the list revert shows), 'return' to drop out of revert mode, and "q" (quit):

$ git add -i
           staged     unstaged path
  1:        +1/-0      nothing foo

*** Commands ***
  1: [s]tatus     2: [u]pdate     3: [r]evert     4: [a]dd untracked
  5: [p]atch      6: [d]iff       7: [q]uit       8: [h]elp
What now> r
           staged     unstaged path
  1:        +1/-0      nothing [f]oo
Revert>> 1
           staged     unstaged path
* 1:        +1/-0      nothing [f]oo
Revert>> 
note: foo is untracked now.
reverted one path

*** Commands ***
  1: [s]tatus     2: [u]pdate     3: [r]evert     4: [a]dd untracked
  5: [p]atch      6: [d]iff       7: [q]uit       8: [h]elp
What now> q
Bye.
$


That's it!  Here's your proof, showing that "foo" is back on the untracked list:

$ git status
# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
# [...]
#       foo
nothing added to commit but untracked files present (use "git add" to track)
$

0
Maybe Git has evolved since you posted your question.

$> git --version
git version 1.6.2.1


Now, you can try:

git reset HEAD .


This should be what you are looking for.
0
To remove new files from the staging area (and only in case of a new file), as suggested above:

git rm --cached FILE


Use rm --cached only for new files accidentally added.
0
git remove or git rm can be used for this, with the --cached flag. Try:

git help rm

0
Just type "git reset" and it is like you never typed "git add ." since your last commit.
0
The command git reset --hard HEAD should work.  The one thing to note is that you need to changed directory (cd) back into your normal working directory. Otherwise if you run the command from the directory you mistakenly did the git add .   .... you will not be able to revert out and instead get the errors mentioned in other posts regard "unknown revision or path not in the working tree".
0
use the * command to handle multiple files at a time

git reset HEAD *.prj
git reset HEAD *.bmp
git reset HEAD *gdb*


etc
0
git clean -f -d should help as it cleans up untracked files along with directories.
0
You can simply reset the code by using the following code 

git reset HEAD .

0
You can also git reset HEAD <file>, which will remove it from the current index (the "about to be committed" area) without changing anything else.
Your Answer