Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why explicitly call git reset --soft before git reset (--mixed)

Tags:

git

In the git docs (and numerous SO threads) this reset approach is recommended:

$ git reset --soft HEAD^ ;# go back to WIP state  <2>
$ git reset                                       <3>

.2. This removes the WIP commit from the commit history, and sets your working tree to the state just before you made that snapshot.

.3. At this point the index file still has all the WIP changes you committed as snapshot WIP. This updates the index to show your WIP files as uncommitted.

https://www.kernel.org/pub/software/scm/git/docs/git-reset.html

Obviously that's fine, but it seems that these two commands could be replaced by

$ git reset HEAD^

(which is equivalent to)

$ git reset --mixed HEAD^

which should reset both the HEAD pointer and the index to the previous commit. Is there in fact a difference between the result of this command and the previous two? If not, is there some reason to prefer the two-stage process? Or was it just done that way in the docs to explicitly illustrate the behavior of --soft?

like image 235
Nathan Stretch Avatar asked Jul 20 '13 11:07

Nathan Stretch


People also ask

What is the use of git reset soft?

git reset --soft , which will keep your files, and stage all changes back automatically. git reset --hard , which will completely destroy any changes and remove them from the local directory. Only use this if you know what you're doing.

What does git reset -- soft `` head do?

When using git reset --soft HEAD~1 you will remove the last commit from the current branch, but the file changes will stay in your working tree. Also, the changes will stay on your index, so following with a git commit will create a commit with the exact same changes as the commit you "removed" before.

How do I undo a git reset soft?

So, to undo the reset, run git reset HEAD@{1} (or git reset d27924e ). If, on the other hand, you've run some other commands since then that update HEAD, the commit you want won't be at the top of the list, and you'll need to search through the reflog .


1 Answers

No, there doesn't seem to be any difference.
It is more to illustrate the git reset --soft (i.e. moving HEAD only, which can have other more practical uses)

git reset HEAD is for "unstaging", and a simple git reset HEAD^ does both (move the HEAD, and unstage, no need for --mixed, since it is the default option)


Here is a quick test to see what that looks like:

Before (you just switch back to feature, where you committed a "wip" -- work in progress):

C:\Users\VonC\prog\git\test\r\r3>gl
* 6ac95bd - (origin/master, origin/HEAD, master) fix in master (2 minutes ago) <VonC>
| * fd8d97d - (HEAD, origin/feature, feature) snap WIP (3 minutes ago) <VonC>
| * 16066dd - f1 (3 minutes ago) <VonC>
|/
* e8ad96f - f1 (3 minutes ago) <VonC>

The reset itself:

C:\Users\VonC\prog\git\test\r\r3>git reset "HEAD^"
Unstaged changes after reset:
M       f

That gives you the status:

C:\Users\VonC\prog\git\test\r\r3>git st
# On branch feature
# Your branch is behind 'origin/feature' by 1 commit, and can be fast-forwarded.
#   (use "git pull" to update your local branch)
#
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   f
#
no changes added to commit (use "git add" and/or "git commit -a")

log after git reset HEAD^

C:\Users\VonC\prog\git\test\r\r3>gl
* 6ac95bd - (origin/master, origin/HEAD, master) fix in master (6 minutes ago) <VonC>
| * fd8d97d - (origin/feature) snap WIP (7 minutes ago) <VonC>
| * 16066dd - (HEAD, feature) f1 (7 minutes ago) <VonC>
|/
* e8ad96f - f1 (8 minutes ago) <VonC>

In two steps, you would have seen the following log after the git reset --soft HEAD^:

C:\Users\VonC\prog\git\test\r\r2>gl
* 6ac95bd - (origin/master, origin/HEAD, master) fix in master (65 seconds ago) <VonC>
| * fd8d97d - (origin/feature) snap WIP (89 seconds ago) <VonC>
| * 16066dd - (HEAD, feature) f1 (2 minutes ago) <VonC>
|/
* e8ad96f - f1 (2 minutes ago) <VonC>

You index would still reflect what was staged for wip:

C:\Users\VonC\prog\git\test\r\r2>git st
# On branch feature
# Your branch is behind 'origin/feature' by 1 commit, and can be fast-forwarded.
#   (use "git pull" to update your local branch)
#
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       modified:   f
#

The reset would then unstaged, bringing you back to the same stage than a git reset HEAD^ would have in one step:

C:\Users\VonC\prog\git\test\r\r2>git reset
Unstaged changes after reset:
M       f

C:\Users\VonC\prog\git\test\r\r2>git st
# On branch feature
# Your branch is behind 'origin/feature' by 1 commit, and can be fast-forwarded.
#   (use "git pull" to update your local branch)
#
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   f
#
no changes added to commit (use "git add" and/or "git commit -a")
like image 98
VonC Avatar answered Sep 28 '22 02:09

VonC