doc: git-reset: clarify git reset [mode]

From user feedback, there was some confusion about the differences
between the modes, including:

1. Sometimes it says "index" and sometimes "index file".
   Fix by replacing "index file" with "index".
2. Many comments about not being able to understand what `--merge` does.
   Fix by mentioning obscure situations, since that seems to be what
   it's for. Most folks will use `git <cmd> --abort`.
3. Issues telling the difference between --soft and --mixed, as well as
   --keep. Leave --keep alone because I couldn't understand its use case,
   but change `--soft` / `--mixed` / `--hard` as follows:

--mixed is the default, so put it first.

Describe --soft/--mixed/--hard with the following structure:

* Start by saying what happens to the files in the working directory,
  because the thing users want to avoid most is irretrievably losing
  changes to their working directory files.
* Then describe what happens to the staging area. Right now it seems to
  frame leaving the index alone as being a sort of neutral action.
  I think this is part of what's confusing users, because in Git when
  you update HEAD, Git almost always updates the index to match HEAD.
  So leaving the index unchanged while updating HEAD is actually quite
  unusual, and it deserves to be flagged.
* Finally, give an example for --soft to explain a common use case.

Signed-off-by: Julia Evans <julia@jvns.ca>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: D. Ben Knoble <ben.knoble+github@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Julia Evans 2026-01-05 16:48:17 -05:00 committed by Junio C Hamano
parent 296834217d
commit 7fb080a790

View File

@ -24,42 +24,46 @@ DESCRIPTION
the staged version of the specified files.
`git reset [<mode>] [<commit>]`::
This form resets the current branch head to _<commit>_ and
possibly updates the index (resetting it to the tree of _<commit>_) and
the working tree depending on _<mode>_. Before the operation, `ORIG_HEAD`
is set to the tip of the current branch. If _<mode>_ is omitted,
defaults to `--mixed`. The _<mode>_ must be one of the following:
Set the current branch head (`HEAD`) to point at _<commit>_.
Depending on _<mode>_, also update the working directory and/or index
to match the contents of _<commit>_.
_<commit>_ defaults to `HEAD`.
Before the operation, `ORIG_HEAD` is set to the tip of the current branch.
+
The _<mode>_ must be one of the following (default `--mixed`):
+
--
`--soft`::
Does not touch the index file or the working tree at all (but
resets the head to _<commit>_, just like all modes do). This leaves
all your changed files "Changes to be committed", as `git status`
would put it.
--
`--mixed`::
Resets the index but not the working tree (i.e., the changed files
are preserved but not marked for commit) and reports what has not
been updated. This is the default action.
Leave your working directory unchanged.
Update the index to match the new `HEAD`, so nothing will be staged.
+
If `-N` is specified, removed paths are marked as intent-to-add (see
If `-N` is specified, mark removed paths as intent-to-add (see
linkgit:git-add[1]).
`--soft`::
Leave your working tree files and the index unchanged.
For example, if you have no staged changes, you can use
`git reset --soft HEAD~5; git commit`
to combine the last 5 commits into 1 commit. This works even with
changes in the working tree, which are left untouched, but such usage
can lead to confusion.
`--hard`::
Resets the index and working tree. Any changes to tracked files in the
working tree since _<commit>_ are discarded. Any untracked files or
directories in the way of writing any tracked files are simply deleted.
Overwrite all files and directories with the version from _<commit>_,
and may overwrite untracked files. Tracked files not in _<commit>_ are
removed so that the working tree matches _<commit>_.
Update the index to match the new `HEAD`, so nothing will be staged.
`--merge`::
Resets the index and updates the files in the working tree that are
different between _<commit>_ and `HEAD`, but keeps those which are
Reset the index and update the files in the working tree that are
different between _<commit>_ and `HEAD`, but keep those which are
different between the index and working tree (i.e. which have changes
which have not been added).
Mainly exists to reset unmerged index entries, like those left behind by
`git am -3` or `git switch -m` in certain situations.
If a file that is different between _<commit>_ and the index has
unstaged changes, reset is aborted.
+
In other words, `--merge` does something like a `git read-tree -u -m <commit>`,
but carries forward unmerged index entries.
`--keep`::
Resets index entries and updates files in the working tree that are