I’ve used a lot of SCM‘s in my time, and none of them have been as esoteric as Git. This post serves as a reminder of the different ways to “revert” changes to a git repository
Scenario:
We are in directory with a local git repository. This repo contains 4 files and no sub-directories. Each file is in one of the 4 different states a file could be in for Git (not considering ignored files for the time being)
File Name |
State |
Unchanged.txt |
File is unchanged in local directory |
New.txt |
File is new to the repo |
Deleted.txt |
File has been deleted from local directory |
Modified.txt |
File has been modified in the local directory |
All files except New.txt are being tracked and none of these changes have been staged/committed (yet).
Action: checkout
$> git checkout
- This command has an implicit head of [HEAD]
- This command has an implicit working file/directory of the CWD
- This command will only affect tracked files
File Name |
State |
Unchanged.txt |
no action |
New.txt |
no action (because it’s untracked) |
Deleted.txt |
no action (will not restore the file UNLESS explicitly stating file in command) |
Modified.txt |
no action (will not restore the file UNLESS explicitly stating file in command) |
Action: checkout <file/path>
$> git checkout .
$> git checkout Deleted.txt
- This command has an implicit head of [HEAD]
- This command has an explicit working file/directory of the path on line 1, and of the file Deleted.txt on line 2
- This command will only affect tracked files
File Name |
State |
Unchanged.txt |
no action |
New.txt |
no action (because it’s untracked) |
Deleted.txt |
File is reverted back to its original from the current head |
Modified.txt |
File is reverted back to its original from the current head |
Action: reset
$> git reset .
- This command has an implicit head of [HEAD]
- This command has an explicit working directory of the CWD
- This command will unstage staged changes
File Name |
State |
Unchanged.txt |
no action (changes are unstaged) |
New.txt |
no action (changes are unstaged) |
Deleted.txt |
no action (changes are unstaged) |
Modified.txt |
no action (changes are unstaged) |
Action: reset (with staged content)
$> git add .
$> git reset
- This action assumes that all changes have been staged (line 1), so the repo is in the following state:
File Name |
State |
Unchanged.txt |
File is unchanged in repo |
New.txt |
File is staged for adding |
Deleted.txt |
File has been staged for deletion |
Modified.txt |
File has been staged with modification |
- This command has an implicit head of [HEAD]
- This command has an implicit working directory of the CWD
- This command will unstage staged changes
File Name |
State |
Unchanged.txt |
no action (changes are unstaged) |
New.txt |
no action (changes are unstaged) |
Deleted.txt |
no action (changes are unstaged) |
Modified.txt |
no action (changes are unstaged) |
Action: clean
$> git clean -d -f
- This command has an implicit head of [HEAD]
- This command has an explicit working directory of the CWD
- This command will remove files and directories which are untracked in the repo
File Name |
State |
Unchanged.txt |
no action |
New.txt |
File would be deleted |
Deleted.txt |
no action |
Modified.txt |
no action |
So in summary, if you want to completely revert your working directory to a clean state (IE: the equivalent of an svn revert) is to:
$> git clean -fd
$> git checkout .
My favourite is:
git reset –hard
(Yeh, bit dangerous, but does the trick :))