Table of Contents
Quick cheat sheet to discard changes in git
Discarding git changes means removing changes you no longer need along any of the three levels of git workflow: working directory, index, or history.
There are many challenges and commands to focus on when doing git discard changes.
This tutorial groups the commands into either affecting uncommitted or committed changes. Using that criterion, here are the seven key commands to git discard changes:
1. git clean command
The following git clean command can be used to git discard untracked files
git clean -f
Th following command can be used to discard both untracked files and folders or
git clean -fd
The following command can be used to interactively discard the files.
git clean -i
2. git checkout command
This is similar to the previous mode, but lets you use the interactive interface to show the "diff" output and choose which hunks to use in the result.
git checkout -p
or to discard all the changes in local working path
git checkout -- .
or to discard single file, just provide the file name with absolute path
git checkout -- <file_name>
if your git version is below 2.23. Otherwise, the recommended way to git discard changes is
3. git restore command
We can also use the following command syntax to discard changes in git
git restore <file>
for one file or
git restore .
for many files.
4. git stash command
git stash explained in detail with examples
The stash command
git stash
is one of the safest ways to discard changes from the index.
5. git reset --mixed command
Doing a mixed reset to the HEAD at the index discards the changes.
git reset HEAD
6. git reset --hard command
A practical guide to git reset hard vs soft vs mixed
git reset --hard [commit hash or HEAD~N]
where N
is the number of commits from the HEAD or
7. git revert command
How to use git revert properly [4 Different Ways]
git revert <commit hash>
where the changes affect a pushed file.
You probably wonder what we mean by uncommitted, committed, or HEAD. Besides, it would be best to see practical ways to use the above commands. Read on to find out more.
Git commit HEAD, uncommitted and committed changes explained
Git workflow entails three stages: working directory, the index, and the history. After creating or modifying files in the working directory, git temporarily takes a snapshot of the index changes before storing them in the git database when each commit becomes part of the history.
The history tells more about the commit, such as the author, date created, and most importantly, a unique hash called the commit hash.
The last commit hash is often referred to as the HEAD. Changes that have not passed the index (a.k.a staging area) are called uncommitted, while those with a history are called committed changes.
Passed the local workflow, you can send the changes to a remote server on a website like GitHub, GitLab, or Bitbucket. Then the changes are pushed. Otherwise, they are unpushed.
That is the basic explanation of the commit HEAD, uncommitted, and committed changes. Let's see their role in discarding git changes.
Lab setup to practice git discard changes
I am creating a remote called git_discard_changes
with a README.md
on GitHub.
Copy the repo URL and clone it on the command line or terminal.
cd
into the new repo git_discard_changes
and inspect the repo status as follows.
cd git_discard_changes git status
The working directory is clean.
Listing all files
ls
shows we have one file, whereas logging the history
git log
shows we have one commit in history. Both local and remote repos' HEAD point the only commit we have.
Create three text files and a directory with two files as follows
touch file1.txt f2.txt third.txt mkdir dir cd dir touch f1 f2 cd ..
Checking the status
git status
shows we have untracked files.
Let us git discard changes by applying the setup in the following examples.
Scenario-1: Git discard uncommitted changes
Example-1: Using git clean command
The git clean command is crucial in discarding changes in untracked files. Although we can use it with several flags, its most familiar forms are -f
for untracked files only, -fd
for both untracked files and directories, and -i
for interactive file discard.
For instance, let's stage file1.txt
and f2.txt
, leaving the third.txt
file and dir
directory untracked.
git add file1.txt f2.txt
Running the command
git clean -f
clears the third.txt
file from the working directory.
Similarly, introducing the -d
flag dumps untracked files and directories.
git clean -fd
Rechecking git status
git status
The untracked dir
directory got discarded!
Lastly, we can use the -i
flag by picking the clean
option.
Create a file.
touch file
Delete it.
git clean -i
Git prompts us for an option. Let's pick 1: clean
to git discard changes
Example-2: Use either git checkout or git restore command
The checkout command has several uses in the git workflow. Apart from switching between branches and commits, you can apply it to git discard changes. All you do is be at the root of the working directory and run either
git checkout -p
or
git checkout -- .
commands.
If it fails to remove your recent changes, use the restore command
git restore <file>
which has been git's preferred way to discard changes since the introduction of git version 2.23 in 2019.
Let's modify file1.txt
.
echo line1 >> file1.txt
Assume we want to delete the most recent changes on file1.txt
. We can do that by running the command:
git restore file1.txt
We can also modify file1.txt
and f2.txt
then git discard changes on them as follows
echo line1 >> file1.txt echo l2 >> f2.txt git restore .
All the new changes disappeared!
Example-3: Use git stash command to stash the changes
Assume you want to git discard changes hoping to restore them later. The command to use is git stash
. Before clearing your changes from the index, it records them in the .git/refs/stash
file in your working tree, only retaining changes as per the commit HEAD.
Let's modify the two files: file1.txt
and f2.txt
to practice git stash
.
echo line1 >> file1.txt
echo line2 >> f2.txt
Stage the changes.
git add *
then check status.
git status
Discard the changes using the stash command.
git stash
Then recheck the status.
git status
Our uncommitted changes disappeared
We can see the stashed changes using
git stash show
and restore them using git stash apply
as follows
git stash apply
Another way to discard the changes in the index is to do a mixed reset on the changes.
Example-4: Reset the HEAD
Running the mixed reset command
git reset HEAD
untracks the files from the index and dumps the changes in the working directory.
Scenario-2: Git discard changes already committed
Example-5: Discarding un-pushed files
The hard reset is the most straightforward command to git discard changes already committed. We can use it as follows.
Let's restage the files.
git add .
And commit them.
git commit -m "Reset the HEAD"
View the HEAD
.
git log
before resetting it.
git reset --hard HEAD^
Recheck the history.
git log
The hard reset command on the HEAD^
removed the latest commit.
Note: git reset hard discards both changes and files from the working directory. The only way to recover the changes is to inspect the reflog
and checkout
the target commit hash.
Better yet, avoid the hard reset command if you have pushed the changes.
Example-6: Discarding remote pushed files
Doing a hard reset on local files can cause a conflict error when used on files already committed. Git revert is the best alternative to discard commit changes on pushed files.
Let's create, stage, commit and push a file before practicing git revert.
touch f1.txt f2.txt git add . git commit -m "Feat: Add files 1 and 2" git push
Let's introduce two more commits before discarding the changes.
touch f3.txt git add f3.txt git commit -m "Fix (github): Add f3" touch track.py git add track.py git commit -m "Feat: Track text files"
Running
git log
shows we have four commits
Let's revert the last three commits by making the HEAD point the initial commit hash.
git revert b4ad96
Our default text editor prompts us for a new commit message. We can go with the default message then close the text editor.
Let's push the changes.
git push
Summary
You can discard all untracked changes using the git clean or git reset hard commands. To git discard changes at the index, use the stash, checkout, or restore commands.
Lastly, you can do a hard reset on the files after committing them. If you plan to undo changes on pushed files, use the revert command instead of git reset hard.