views:

38

answers:

2

I am looking to split a commit up and not sure which reset option to use.

I was looking at the page that has a promising title, but I realized I don't really understand what the git index or staging area is and thus the explanations didn't help.

Also the use cases for --mixed and --soft look the same to me in that answer (when you want to fix and recommit.) Can someone break it down even more? I realize --mixed is probably the option to go with, but I want to know why.

Can someone give me a workflow example of how selecting the two options would happen?

+3  A: 

When you modify a file in your repository, the change is initially unstaged. 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.

git reset changes, at minimum, where your current branch is pointing. The difference between --mixed and --soft is whether or not your index is also modified. So, if we're on branch master with this series of commits:

- A - B - C (master)

HEADpoints to C and the index matches C.

When we run git reset --soft B, master (and thus HEAD) now points to B, but the index still has the changes from C; git status will show them as staged. So if we run git commit at this point, we'll get a new commit with the same changes as C.


Okay, so starting from here again:

- A - B - C (master)

Now let's do git reset --mixed B. Once again, master and HEAD point to B, but this time the index is also modified to match B. If we run git commit at this point, nothing will happen since the index matches HEAD. We still have the changes in the working directory, but since they're not in the index, git status shows them as unstaged. To commit them, you would git add and then commit as usual.


And finally, --hard is the same as --mixed (it changes your HEAD and index), except that --hard also modifies your working directory. If we're at C and run git reset --hard B, then the changes added in C, as well as any uncommitted changes you have, will be removed, and the files in your working copy will match commit B. Since you can permanently lose changes this way, you should always run git status before doing a hard reset to make sure your working directory is clean or that you're okay with losing your uncommitted changes.

mkarasek
It may be useful to describe `--hard`'s behaviour as well (to be comprehensive).
strager
Very helpful, thank you.
fsmc
Added section on `--hard`.
mkarasek
If you don't specify which one "--mixed" is the default.
Casey
A: 

Changes are moved to "index/stage area" when you call git add .... So if you call git reset --mixed, it undo all git add and git del operations and changes HEAD. If you call git reset --soft it only changes HEAD.

Tomasz Wysocki