I'm new to GIT, and trying to understand the difference between git reset --soft
and git reset --mixed
. I know the latter resets the index, while the former does not, but I'm trying to understand what the material difference is: when would I use one versus the other?
I've read this Stack Overflow post, which seems to suggest that mixed
lends itself to making some changes before re-committing, while soft
lends itself to simply re-committing immediately. I'm using SourceTree, with the staging pane turned off, and struggling to see why this is so; I can't for the life of me see any actual real differences.
The only difference I can see is that a newly added file that I reset over shows up as added with a soft reset, but not so with mixed. But in either case I can successfully make changes to the newly added file, and re-commit. And of course any new changes I make to existing files get seamlessly added to my current un-committed changes, ready to be committed.
Do I have to use the Staging Pane with Source Tree to see any practical difference, or am I just missing something? To be clear, with how I have the tool set up now, I see un-committed changes, which I commit in one step.
First, read the link suggested by @Ant P above.
Whats the difference between git reset --mixed, --soft, and --hard?
Let me supplement that with a bit of model of what's going on.
'git reset' works with three different things.
So if you create a git repo with two files, foo.txt and bar.txt.
In your first revision put 'v1' in each file. In your second revision put 'v2' in each file. Now, put 'v3' in each, and do 'git add foo.txt'.
At this point, you change your mind, and decide to reset to the first revision. What state do you want to end up in?
So why would you want to do git reset --soft?
Let's say you create a commit, and decide you didn't get it right, and want to fix it before you push. (IMPORTANT! Once you push, you want to consider commits as permanent, or you'll make things hard for everyone else)
You could make your changes, and do 'git commit --amend'. But that only works for the last commit. Or you could do 'git rebase --interactive', and make your change to a specific commit, merge commits, etc.
Or you could do 'git reset --soft', add, change, rm, or reset any files, until you get the state you want for your new commit, and then commit it as your new commit.
'git reset --mixed' (or without the --mixed; it's the default) is just useful for undoing 'git add' or 'git rm'.
Bottom line is, in my opinion you probably don't want to use --soft in interactive usage. There's nothing wrong with using it, but 'git commit --amend' or 'git rebase --interactive' may be a more intuitive way to get what you want.
'git reset --mixed' you will use a lot.
If you're using a .gitignore
which is not checked into the repo or changed between the commits, you won't be able to add ignored files from a mixed reset except as manually, neither will git diff
or git status
show you they are there.
With a soft reset, everything you had reset will be guaranteed to be included into the commit should you make one.
Actually, either of those might be the way you need, that's why both methods (and explicit access to the index itself) are there in GIT.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With