git reset
has three modes, "hard", "soft", and "mixed" which describe what happens to the working tree (ie. your files) and the staging area.
--soft
leaves both the staging area and your files alone.
--hard
discards all changes in the staging area and files.
--mixed
resets the index but leaves the working tree alone.
With that in mind, let's look at what you did.
Let's say your repo looks like this.
A - B [master]
You commit alert("Hello");
, that becomes commit C.
A - B - C [master]
You commit alert("Hello adam");
, that becomes commit D.
A - B - C - D [master]
You run git reset --soft HEAD~1
. HEAD~1
is commit C with alert("Hello");
. So master
has moved back to commit C undoing the alert("Hello adam");
commit.
Since you used --soft
both the index and files will remain the same. The files will still say alert("Hello adam");
and you will see a diff. This gives you the opportunity to redo the commit.
Instead if you want to revise the immediately previous commit, use git commit --amend
. This rewrites the previous commit. In your current state with C checked out and alert("Hello adam");
uncommitted, you can git commit -a
to rewrite commit C with your new change.
A - B - C1 [master]
\
C
The old C will eventually be garbage collected.
In general, if you want to revise the previous commit, simply make your edits and then git commit --amend
them to the previous commit. More involved rewriting of history would involve an "interactive rebase". See Rewriting History
in the Pro Git book for more.
Incidentally, git --soft HEAD~1
is a form of "redo". It allows you to undo the previous commit while retaining its changes so you can edit them and commit them anew. Here's some useful aliases to make these commands easier to understand.
[alias]
# Undo the last commit
undo = reset --hard HEAD^
# Undo the last commit, but leave its changes in the working copy
# so we can redit them.
redo = reset --soft HEAD^
# Throw out all changes
clear = reset --hard HEAD