Git newbie here, quick question. I mistakenly added files using the command "git add file". I have not yet run "git commit". Is there a way to remove these files from the commit?
git remove / git rm can be used for this, with the --cached flag Try git help rm
You can also git reset FILE
, which will remove it from the current index (the "about to be committed" area) without changing anything else.
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.
Also a newbie I 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.
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 newbie 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 Stackoverflow - 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 .
UPDATE Oh yeah forgot to mention - 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)
I can confirm. git rm removes the file from the repository. Check out the example laid out below: We have an example repository in /tmp/foo and add three untracked files a, b, and c. Make an add to all all take it back with git rm --cached
. Looks alright. Now we commit a to the rep. Now we make a slight change to a and also again accidentally do git add .
in this scenario. And then use git rm --cached
again. And we see that it also throws a out of the repository and marks it as deleted. Not exactly what you want.
mac:tmp neo$ mkdir foo
mac:tmp neo$ cd foo/
mac:foo neo$ git --version
git version 1.5.4.3
mac:foo neo$ git init
Initialized empty Git repository in .git/
mac:foo neo$ touch a
mac:foo neo$ touch b
mac:foo neo$ touch c
mac:foo neo$ git add .
mac:foo neo$ git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
# (use "git rm --cached <file>..." to unstage)
#
# new file: a
# new file: b
# new file: c
#
mac:foo neo$ git rm --cached *
rm 'a'
rm 'b'
rm 'c'
mac:foo neo$ git status
# On branch master
#
# Initial commit
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# a
# b
# c
nothing added to commit but untracked files present (use "git add" to track)
mac:foo neo$ git add a
mac:foo neo$ git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
# (use "git rm --cached <file>..." to unstage)
#
# new file: a
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# b
# c
mac:foo neo$ git commit -m 'st.ov test'
Created initial commit 68867dc: st.ov test
0 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 a
mac:foo neo$ git add .
mac:foo neo$ echo 'foo' > a
mac:foo neo$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: b
# new file: c
#
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
#
# modified: a
#
mac:foo neo$ git rm --cached *
rm 'a'
rm 'b'
rm 'c'
mac:foo neo$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# deleted: a
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# a
# b
# c
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.
Same problem here, git reset --HARD resets the head to the last commit but not undoes the uncommited add or remove.
git reset FILE gives me: fatal: Needed a single revision
The question is how to undo a not commited add, seems like reset is not the solution. Correct me if I am wrong.
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)
:)
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.
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
git rm --cached . -r
will "un-add" everything you've added from your current directory recursively
Just type "git reset" and it is like you never typed "git add ." since your last commit.
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
As per many of the answers above you can git reset BUT, I found this great little post that actually adds the git command (well an alias) for "git unadd"
http://pivotallabs.com/users/alex/blog/articles/1001-git-unadd
Simply,
git config --global alias.unadd "reset HEAD"
now you can
git unadd foo.txt bar.txt