Undo
git checkout
, git reset
, git revert
, git clean
.
work tree, index(staging area)
- When you modify a file in your repository, the change is initially unstaged, in work tree.
- In order to commit it, you must stage it—that is, add it to the index, using
git add
. - When you make a commit, the changes that are committed are those that have been added to the index. Remember, the index is git's "staging area" - it's where things go when you say git add in preparation to commit.
git checkout
to undo one file, simply:
git checkout <file>
This command checks-out content from the repository and puts it in your work tree. It can also have other effects
undo all files, git reset
It modifies the index (the so-called "staging area").
In general, git reset
is to take the current branch and reset it to point somewhere else, and possibly bring the index and work tree along.
if we're on branch master with this series of commits:
- A - B - C (HEAD, master)
and you want master to point to B, not C, you will use git reset B
to move it there:
- A - B (HEAD, master) # - C is still here, but there's no branch pointing to it anymore
--hard can cause you to really lose work. It modifies your work tree.
There are four main options to control what happens to your work tree and index during the reset.
- --hard makes everything match the commit you've reset to. It blows away your work but not switching commits:
git reset --hard
meansgit reset --hard HEAD
, i.e. don't change the branch but get rid of all local changes. This is the one that can really make you lose work, because it modifies your work tree. - --mixed is the default,
git reset
resets the index, but not the work tree. This means all your files are intact, but any differences between the original commit and the one you reset to will show up as local modifications (or untracked files) with git status. Use this when you realize you made some bad commits, but you want to keep all the work you've done so you can fix it up and recommit. In order to commit, you'll have to add files to the index again (git add ...). - --soft doesn't touch the index or work tree. All your files are intact as with --mixed, but all the changes show up as changes to be committed with git status (i.e. checked in in preparation for committing). Use this when you realize you've made some bad commits, but the work's all good - all you need to do is recommit it differently. The index is untouched, so you can commit immediately if you want - the resulting commit will have all the same content as where you were before you reset.
- --merge was added recently, and is intended to help you abort a failed merge. This is necessary because git merge will actually let you attempt a merge with a dirty work tree (one with local modifications) as long as those modifications are in files unaffected by the merge. git reset --merge resets the index (like --mixed - all changes show up as local modifications), and resets the files affected by the merge, but leaves the others alone. This will hopefully restore everything to how it was before the bad merge. You'll usually use it as git reset --merge (meaning git reset --merge HEAD) because you only want to reset away the merge, not actually move the branch. (HEAD hasn't been updated yet, since the merge failed)
To be more concrete, suppose you've modified files A and B, and you attempt to merge in a branch which modified files C and D. The merge fails for some reason, and you decide to abort it. You use git reset --merge. It brings C and D back to how they were in HEAD, but leaves your modifications to A and B alone, since they weren't part of the attempted merge.
git revert
This command creates a new commit that undoes the changes from a previous commit. This command adds new history to the project (it doesn't modify existing history).
Removes untracked files
git clean
Removes untracked files from your working directory. This is really more of a convenience command, since it’s trivial to see which files are untracked with git status and remove them manually using an ordinary rm command.git clean –f
The -f (force) flag is required unless the clean.requireForce configuration option is set to false (it's true by default). This will not remove untracked folders or files specified by .gitignore.git clean -xf
The -x option remove any files that Git usually ignores as well. For example, the .o and .exe binaries generated by a C compiler. This is occasionally a necessary step before packaging a project for release.
The git reset --hard
and git clean -f
commands are your best friends if you want to burn the evidence.
What is difference between “git reset --hard HEAD” and “git checkout -f”?
Same effect. Basically with a reset you move the current branch and the HEAD to a specific commit but with a checkout, you only move the HEAD. Note: git reset --hard HEAD might still keep some weird changes. Then, git checkout -f seems to solve the problem.