Categories
git git-add undo

How do I undo ‘git add’ before commit?

10588

I mistakenly added files to Git using the command:

git add myfile.txt

I have not yet run git commit. How do I undo this so that these changes will not be included in the commit?

10

  • 41

    Starting with Git v1.8.4, all the answers below that use HEAD or head can now use @ in place of HEAD instead. See this answer (last section) to learn why you can do that.

    – user456814

    Jul 26, 2013 at 2:04

  • 4

    I made a little summery which shows all ways to unstage a file: stackoverflow.com/questions/6919121/…

    Apr 26, 2014 at 12:09

  • 8

    If you use Eclipse, it is as simple as unchecking the files in the commit dialogue box

    – Hamzahfrq

    Nov 17, 2016 at 12:49

  • 2

    This is a great resource straight from Github: How to undo (almost) anything with Git

    Feb 3, 2017 at 21:13

  • 2

    Before you post a new answer, consider there are already 25+ answers for this question. Make sure that your answer contributes what is not among existing answers

    Jun 15, 2017 at 15:29

12556

Undo git add for uncommitted changes with:

git reset <file>

That will remove the file from the current index (the “about to be committed” list) without changing anything else.


To unstage all changes for all files:

git reset

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

Documentation: git reset

13

  • 137

    Of course, this is not a true undo, because if the wrong git add overwrote a previous staged uncommited version, we can’t recover it. I tried to clarify this in my answer below.

    – leonbloy

    May 6, 2013 at 19:10

  • 11

    git reset HEAD *.ext where ext is the files of the given extension you want to unadd. For me it was *.bmp & *.zip

    Nov 26, 2013 at 14:25

  • 27

    @Jonny, the index (aka staging area) contains all the files, not just changed files. It “starts life” (when you check out a commit or clone a repo) as a copy of all the files in the commit pointed to by HEAD. So if you remove a file from the index (git rm --cached) it means you are preparing to make a commit that deletes that file. git reset HEAD <filename> on the other hand will copy the file from HEAD to the index, so that the next commit won’t show any changes being made to that file.

    – Wildcard

    Mar 16, 2016 at 12:27

  • 21

    I just discovered that there is a git reset -p just like git add -p. This is awesome!

    Jul 17, 2016 at 23:23

  • 19

    You actually can recover overwriten previously staged but uncommited changes but not in a userfriendly way and not 100% secure (at least none I had found): goto .git/objects, search for files created at the time of git add you want to recover (61/3AF3... -> object id 613AF3...), then git cat-file -p <object-id> (might be worth it to recover several hours of work but also a lesson to commit more often…)

    Jul 31, 2017 at 14:03


2357

You want:

git rm --cached <added_file_to_undo>

Reasoning:

When I was new to 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:

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

    … lots of crap scrolls by …

    => Damn, I didn’t want to add all of that.

  5. google “undo git add”

    => find Stack Overflow – yay

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

22

  • 26

    Hah. I followed this same process. Except I gave up and said rm -rf .git, git init because I didn’t trust git rm --cached to keep my working copy. It says a little for how git is still overly complex in some places. git unstage should just be a stock standard command, I don’t care if I can add it as an alias.

    Mar 29, 2011 at 3:45

  • 6

    For me git says git reset HEAD <File>...

    – drahnr

    Sep 12, 2012 at 6:50


  • 23

    git rm –cached <file> is actually the correct answer, if it is the initial import of <file> into the repository. If you’re trying to unstage a change to the file, git reset is the correct answer. People saying that this answer is wrong are thinking of a different question.

    Feb 28, 2013 at 22:14

  • 17

    This will actually work, but only on the first commit, where the file didn’t exist before, or where the git add command added new files, but not changes to existing files.

    – naught101

    Apr 10, 2013 at 2:33

  • 9

    just goes to show how unintuitive and convoluted git is. instead of having parallel “undo” commands, you have to find out how to undo them. Like trying to free your leg in quick sand, and then getting your arm stuck, then getting your other arm stuck… every command should be done through GUI, with dropdown menus items for the options… Think of all the UI, productivity gains we’ve had, but we have this mess of a retro command line interface. It’s not like the git GUI programs make this any more intuitive.

    – ahnbizcad

    May 24, 2014 at 10:54

604

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)

4

  • 24

    The message will be different depending on whether the added file was already being tracked (the add only saved a new version to the cache – here it will show your message). Elsewhere, if the file was not previously staged, it will display use "git rm --cached <file>..." to unstage

    – leonbloy

    May 6, 2013 at 18:25


  • Great! The git reset HEAD <file> one is the only one that will work in case you want to unstage a file delete

    – skerit

    Feb 24, 2018 at 0:25

  • 3

    My git version 2.14.3 says git reset HEAD to unstage.

    Apr 23, 2018 at 19:16

  • 5

    Since Git v2.23 the message has changed yet again. It now says git restore --staged <file>. See my answer below for an update.

    – prosoitos

    Nov 19, 2020 at 17:02