How to undo 'git add' before commit?
I mistakenly added files to git using the command:
git add myfile.txt
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
git reset <file>
which will remove it from the current index (the "about to be committed" list) without changing anything else.
You can use
git reset
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:
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:
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).
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)
链接地址: http://www.djcxy.com/p/36254.html
上一篇: git diff不提供输出
下一篇: 如何在提交前撤销'git add'?