How to undo 'git add' before commit?
I mistakenly added files to git using the command:
I have not yet run git commit
. Is there a way to undo this, so these files won't be included in the commit?
There are 48 answers so far (some deleted). Please don't add a new one unless you have some new information.
You can undo git add
before commit with
which will remove it from the current index (the "about to be committed" list) without changing anything else.
You can use
without any file name to unstage all due changes. This can come in handy when there are too many files to be listed one by one in a reasonable amount of time.
In old versions of Git, the above commands are equivalent to git reset HEAD <file>
and git reset HEAD
respectively, and will fail if HEAD
is undefined (because you haven't yet made any commits in your repo) or ambiguous (because you created a branch called HEAD
, which is a stupid thing that you shouldn't do). This was changed in Git 1.8.2, though, so in modern versions of Git you can use the commands above even prior to making your first commit:
"git reset" (without options or parameters) used to error out when
you do not have any commits in your history, but it now gives you
an empty index (to match non-existent commit you are not even on).
You want:
Reasoning:
When I was new this, I first tried
(to undo my entire initial add), only to get this (not so) helpful message:
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:
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)
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
to remove everything and start again. Didn't work though, because while add .
is recursive, turns out rm
needs -r
to recurse. Sigh.
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:
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).
If you type:
git will tell you what is staged, etc, including instructions on how 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:
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 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:
We can easily create an alias for this:
And finally, we have new commands:
Personally I use even shorter aliases:
An addition to the accepted answer, 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 not 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:
Update (what follows is my attempt to clear some confusion that can arise from the most up-voted answers):
So, which is the real undo of git add
?
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.
Let's recall first what git add <file>
actually 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. In GIT, this action is still called add, (not mere update it), because two different versions (snapshots) of a file are regarded as two different items: hence, we are indeed adding a new item to the cache, to be eventually commited later.
In light of this, the question is slightly ambiguous:
I mistakenly added files using the command...
The OP's scenario seems to be the first one (untracked file), we want the "undo" to 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>
.
And we could also run git reset HEAD <file>
. This is in general preferable, because it works in both scenarios: it also does the undo when we wrongly added a version of an already tracked item.
But there are two caveats.
First: There is (as pointed out in the answer) only one scenario in which git reset HEAD
doesn't work, but git rm --cached
does: a new repository (no commits). But, really, this a practically irrelevant case.
Second: Be aware that git reset HEAD
can't magically recover the previously cached file contents, it just resyncs it from the HEAD. If our misguided git add
overwrote a previous staged uncommitted version, we can't recover it. That's why, strictly speaking, we cannot undo.
Example:
Of course, this is not very critical if we just follow the usual lazy workflow of doing 'git add' only for adding new files (case 1), and we update new contents via the commit, git commit -a
command.
will "un-add" everything you've added from your current directory recursively
Run
and remove all the files manually or by selecting all of them and clicking on the unstage from commit button.
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:
What you want:
Remove the file from the index, but keep it versioned and left with uncommitted changes in working copy:
Reset the file to the last state from HEAD, undoing changes and removing them from the index:
This is needed since git reset --hard HEAD
won't work with single files.
Remove <file>
from index and versioning, keeping the un-versioned file with changes in working copy:
Remove <file>
from working copy and versioning completely:
The question is not clearly posed. The reason is that git add
has two meanings:
if in doubt, use
Because it does the expected thing in both cases.
Warning: if you do git rm --cached file
on a file that was modified (a file that existed before in the repository), then the file will be removed on git commit
! It will still exist in your file system, but if anybody else pulls your commit, the file will be deleted from their work tree.
git status
will tell you if the file was a new file or modified:
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
Undo a file which already added is quite easy using git, for resetting myfile.txt
which already added, use:
Explain:
After you staged unwanted file(s), to undo, you can do git reset
, Head
is head of your file in local and the last parameter is the name of your file.
I create the steps in the image below in more details for you, including all steps which may happen in these cases:
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
: see git unadd for details or..
Simply,
Now you can
git remove
or git rm
can be used for this, with the --cached
flag. Try:
Use git add -i
to remove just-added files from your upcoming commit. Example:
Adding the file you didn't want:
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):
That's it! Here's your proof, showing that "foo" is back on the untracked list:
Here's a way to avoid this vexing problem when you start a new project:
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:
Maybe Git has evolved since you posted your question.
Now, you can try:
This should be what you are looking for.
Note that if you fail to specify a revision then you have to include a separator. Example from my console:
(git version 1.7.5.4)
To remove new files from the staging area (and only in case of a new file), as suggested above:
Use rm --cached only for new files accidentally added.
use the *
command to handle multiple files at a time
etc
To reset every file in a particular folder (and its subfolders), you can use the following command:
Just type git reset
it will revert back and it is like you never typed git add .
since your last commit. Make sure you have committed before.
Suppose I create a new file newFile.txt
.
Suppose I add the file accidently, git add newFile.txt
Now I want to undo this add, before commit, git reset newFile.txt
This command will unstash your changes:
You can also use
to add parts of files.
To undo git add use
git reset filename
I'm surprised that no one mention interactive mode:
choose option 3 to un add files. In my case i often want to add more than one file, with interactive mode you can use numbers like this to add files. This will take all but 4: 1,2,3,5
To choose a sequence just type 1-5 to take all from 1 to 5.
Git staging files
For a specific file:
git reset my_file.txt
git checkout my_file.txt
For all added files:
git reset .
git checkout .
Will remove a file named filename.txt from the current index, the "about to be committed" area, without changing anything else.
In SourceTree you can do this easily via the gui.
You can check which command sourcetree uses to unstage a file.
I created a new file and added it to git. Then I unstaged it using the SourceTree gui.
This is the result:
Unstaging files [08/12/15 10:43]
git -c diff.mnemonicprefix=false -c core.quotepath=false -c credential.helper=sourcetree reset -q -- path/to/file/filename.java
SourceTree uses reset
to unstage new files.
git add myfile.txt
# this will add your file into to be committed list
Quite opposite to this command is,
so, you will be in previous state. specified will be again in untracked list (previous state).
it will reset your head with that specified file. so, if your head doesn't have it means, it will simply reset it
Will remove a file named filename.txt from the current index, the "about to be committed" area, without changing anything else.
Thank you for your interest in this question.
Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).
Would you like to answer one of these unanswered questions instead?