How can you undo the last git add?

Is it possible to unstage the last staged (not committed) change in git? Suppose there were a lot of files in the current branch, some staged, some not. At some point, some foolish programmer accidentally executed:

git add -- .

...instead of:

git checkout -- .

Can this programmer now unstage his last changes with some magical git command? Or should he have committed before experimenting in the first place?


Solution 1:

You can use git reset. This will 'unstage' all the files you've added after your last commit.

If you want to unstage only some files, use git reset -- <file 1> <file 2> <file n>.

Also it's possible to unstage some of the changes in files by using git reset -p.

Solution 2:

You cannot undo the latest git add, but you can undo all adds since the last commit. git reset without a commit argument resets the index (unstages staged changes):

git reset

Solution 3:

So the real answer to

Can this programmer now unstage his last changes with some magical git command?

is actually: No, you cannot unstage just the last git add.

That is if we interpret the question as in the following situation:

Initial file:

void foo() {

}

main() {
    foo();
}

First change followed by git add:

void foo(int bar) {
    print("$bar");
}

main() {
    foo(1337);
}

Second change followed by git add:

void foo(int bar, String baz) {
    print("$bar $baz");
}

main() {
    foo(1337, "h4x0r");
}

In this case, git reset -p will not help, since its smallest granularity is lines. git doesn't know that about the intermediate state of:

void foo(int bar) {
    print("$bar");
}

main() {
    foo(1337);
}

any more.

Solution 4:

You could use git reset (see docs)