Undoing Local Changes in Git when in the Working area or Staging area


Reading time: 40 minutes | Coding time: 10 minutes

Before going into our main objective "Undoing Local Changes in Git when in the Working area or Staging area", we will go through two basic concepts "Working area" and "Staging".

What is Working area?

It is the remote local space where you code on your machine. You have not added your code to git yet.

What is staging?

It means to prepare a file for a commit. You have added your file to git staging area, but not committed it yet.

Staging area lies in between of the working area and the repository area, you can see three of the areas in the diagrams below.

Undoing local changes in git when in the working area

Following is the scenario:
Suppose you are working on a project. You check git status and find your working directory clean as follows:

git status
on branch master
nothing to commit, working directory clean

Now suppose you changed a bit of code and added to git, although not committed yet as that part still needs some additions..! (in our case, we have only added comment saying adding to git but not committing, the rest two lines were already present in the git repo. )

#adding to git but not committing!
togreet = "readers"
print("hello "+togreet)

git status
on branch master
changes to be committed:
(use "git reset HEAD file ..." to unstage
modified: hello.py

This is how it all looks like:
drawio0
Now after some time, again you have been writing some code in your local repository and it looks like this..
Remember, you have not added this bad commit in the git staging area yet!

#adding to git but not committing!
togreet = "readers"
print("hello "+ togreet)
#this commit needs to be removed, neither adding not committing in git

git status
on branch master
changes to be committed:
(use "git reset HEAD file ..." to unstage)
modified: hello.py
Changes not staged for commit:
(use "git add file.." to upadate what will be commited)
(use "git checkout -- file.." to discard changes in working directory

If it seems a bit confusing, refer the following diagram in relation to what was explained above:
drawio1
Then you realize, the recent changes were not useful to your feature. You need to remove them and get back whatever there was in the code you added in the git previously.
What would you do ?
In your code editor, find all these green highlights to know where you have added the changes ? That's okay but a lot difficult when you have a lot of files changed!

We can use the checkout filename command to get the file that is in the staging area as below:

git checkout hello.py

Now, this is how the file looks like:

#adding to git but not committing!
togreet = "readers"
print("hello "+togreet)

All the code that was not added in the staging area was removed and we got back all the code that was present in the staging area.

drawiogit2

Undoing staged changes in git when in the staging area

When you commit a file, it get's added in the repository area.

We have a repository that has some code already committed. This is how the code already committed looks like:

togreet="readers"
print("hello "+togreet)

Now suppose we add some comment in the code, and also add it to git in the staging area:

togreet="readers"
print("hello "+togreet)
#Adding in the staging area.....But need to remove this after adding as it is not needed. 

After some time, we realize that we need to remove everything we have added and get back the code to the state it was like in the last commit (happens a lot of time and probably happened with you as well if you are here!). So everything in the staging area as well as working area (local) needs to be same as in the last commit (in our case the comment needs to be removed).

This is how it all looks like now:
c2
The HEAD you can see, it is like a reference. It is like the pointer to the last commit in the currently checked out branch.

The reset HEAD command resets the staging area to be whatever is in HEAD. The command is:

git reset HEAD hello.py

git reset HEAD hello.py
Unstaged changes after reset:
M hello.py

However remember that reset command does not change the working directory, it only changes the staging area.
It can be seen as:
Staging area got back the changes in the last commit but since working area (local) is still the same, it shows modified but not staged for commit.

git status
on branch master
Changes not staged for commit:
(use "git add file.." to upadate what will be commited)
(use "git checkout -- file.." to discard changes in working directory)
modified : hello.py
no changes added to commit (use "git add" and or "git commit -a")

Working area:

togreet = "readers"
print("hello "+togreet)

#Adding in the staging area..........But need to remove this after adding as it is not needed. 

This is how the scenario is:
c6

In order to get the changes back in working area as well, we can use checkout as is explained in an article of undoing local changes when in working area.

git checkout hello.py
togreet = "readers"
print("hello "+togreet)

c9

Note that in the diagrams above, HEAD is not present in the staging area, it is just a pointer that points to the most recent commit in the branch, it is shown for only representation purpose.

Thus, with this article at OpenGenus, we saw how to undo any code either when we are in the local working area or in the staging area. In the next article we will see what to do when we have already code committed! If there are any doubts relating to the above two concepts, please write in the comments section.