I'm trying to add succinct summaries of Git's reset modes for the Git-Savvy Sublime extension. It's hard!
I have this:
mixed (default): update index
soft: move branch pointer only
hard: update index & working dir, discard local changes
merge: update index & working dir, keep local changes
keep: update index & working dir, abort if local changes
(Hopefully it's implied that the branch pointer moves in all modes.)
The documentation around the reset
modes is pretty murky, and uses the phrases "updates the index", "touches the index file", "resets the index" and "resets index entries" with no way of knowing whether they're synonymous or not.
Are there other subtle differences between --hard
, --merge
and --keep
?
Ok, since I can't find a complete side-by-side analysis of the different modes, I'll make a table, using language which is hopefully more understandable to the user. I'm also including git checkout
.
For clarity, the "Effect on..."
Clean working directory:
Effect on | soft | mixed | hard | merge | keep |checkout
-----------------+---------------------------------------------|--------
HEAD | Move | Move | Move | Move | Move | Move
Branch pointer | Move | Move | Move | Move | Move | -
Empty index | Add* | - | - | - | - | -
Tracked files | - | - | Change | Change | Change |Change
Untracked files | - | - | - | - | - | -
Changes in working directory (possibly staged) that aren't affected by the commit we're resetting/checking out. (eg, we change file.txt, but there's no change in it between the current commit and where we're going)
(-
means "keep in current state", Both
means staged and unstaged changes to the same file)
Staged changes | - | Unstage | Discard | Discard | Unstage| -
Unstaged changes | - | - | Discard | - | - | -
Both | - * | Unstage | Discard | Abort | Unstage| -
Changes in working directory (possibly staged) that are affected by the commit we're resetting/checking out. Sometimes expressed as asking if the operation is "working directory safe".
Effect on | soft | mixed | hard | merge | keep |checkout
-----------------+---------------------------------------------|--------
Staged changes | - | Unstage | Discard | Discard | Abort | Abort
Unstaged changes | - * | - | Discard | Abort | Abort | Abort
Both | - * | Unstage | Discard | Abort | Abort | Abort
--soft
git reset --soft X
turns changes between working directory (including current HEAD) and X into staged changes. Git's man page counter-intuitively describes this as "not touching the index file".
When there are staged changes, --soft
combines them with new staged changes.
When there unstaged changes, --soft
keeps the unstaged changes, but also stages new changes as above. It's consistent but potentially confusing.
The different git reset
modes are defined by these questions:
soft
), unstaged (mixed
, keep
) or discarded (merge
, hard
)hard
), only if safe (keep
, merge
) or never (soft
, mixed
)soft
, mixed
, merge
, keep
) or discarded (hard
)My final succinct descriptions of each:
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