kjo
kjo

Reputation: 35321

Discard all non-staged changes without committing?

Is there a simple way to discard all the changes that have not been staged without first committing the latter?

E.g., suppose that A is a tracked file, as in

% git init -q
% echo "state 1" > A
% git add A && git commit -q -m 'initial commit'
% cat A
state 1

Next one modifies A, and stages it:

% echo "state 2" > A
% git add A
% cat A
state 2

Finally, one modifies A a third time, but this time A remains unstaged:

% echo "state 3" > A
% cat A
state 3

How can one revert A to its staged state, namely state 2.

EDIT: I've changed the code sequence a little, hopefully it is now clearer. I also posted a solution that occurred to me after I posted the question. This solution strikes me as roundabout (there has to be something more direct), but at least it shows clearly the state where I want A to end up, both in the working directory and in the index.

Upvotes: 0

Views: 152

Answers (3)

Tuxdude
Tuxdude

Reputation: 49483

Assuming this has been your workflow:

  1. You committed a file
  2. You made some changes and staged it
  3. You made some more changes, but you want to revert to the version with the staged changes in step 2.

You just need to run git checkout -- A. This will get rid of any unstaged changes but will preserve the changes at the end of step 2.

Look at this example workflow which will clear things up:

Contents of A is just version1

$ echo "version1" > A

Commit the change $ git add A && git commit -q -m 'initial commit'

$ git log
commit 4fd90642df048ca4beeb29c65c5f7a436e83055a
Author: Tuxdude <foo@bar>
Date:   Fri Mar 8 16:28:36 2013 -0800

    initial commit

Contents of A is now version2

$ echo "version2" > A

$ cat A
version2

Stage the file changes

$ git add A

Check the current git status

$ git status
# On branch master
# Your branch is ahead of 'origin/master' by 1 commit.
#
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   modified:   A
#

Make some more changes to A

$ echo "version3" > A

$ cat A
version3

Now you decide, that you want to get rid of the local unstaged changes in `A. You just need to checkout the file from git's cache i.e the staging area.

$ git checkout -- A

$ cat A
version2

You can run git status once again and it will let you know about the staged changes.

$ git status
# On branch master
# Your branch is ahead of 'origin/master' by 1 commit.
#
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   modified:   A
#

Upvotes: 2

kjo
kjo

Reputation: 35321

I thought of a possible answer to my question. It's not particularly elegant, and I can't tell if it has any potential pitfalls, but at the very least it shows clearly the state where I want A to end up. Hopefully someone will know a less roundabout route.

After the sequence given in the original question, do:

% git stash -q -k
% git stash drop -q
% cat A
state 2

Upvotes: 0

alestanis
alestanis

Reputation: 21863

You just have to do

git checkout -- .

If you want to revert a single file, you do

git checkout -- myfile

If the file has already been added, you have to un-stage it by doing

git reset HEAD myfile

Upvotes: 1

Related Questions