What are typical use cases of git-reset's --merge and --keep flags?
git, git-reset
Solution
Frankly I'm not really sure about this; I've never even used the `--merge` and `--keep` modes myself. However, the release notes indicate that `git reset --merge` was added in git version 1.6.2, with the following note:
- `git reset --merge` is a new mode that works similar to the way `git checkout` switches branches, taking the local changes while switching to another commit.
and `--keep` was added in 1.7.1:
- `git reset` learned `--keep` option that lets you discard commits near the tip while preserving your local changes in a way similar to how `git checkout branch` does.
Then, in 1.7.9:
- `git checkout -B <current branch> <elsewhere>` is a more intuitive way to spell `git reset --keep <elsewhere>`.
which tells us that the idea behind `--keep` is, you have started work on some branch, and then you realize: oh, this branch should fork off from some other point (probably the tip of some other branch). For instance you might:
$ git checkout devel
$ git checkout -b fix-bug-1234
and then do some work to fix bug 1234 for the next release; but then someone says: "hey, we need bug 1234 fixed for the old release version!" So now you want `fix-bug-1234` to branch off from `release` instead of `devel`. Meanwhile you haven't committed anything yet. So you:
$ git checkout -B fix-bug-1234 release
to move it to "coming off release" instead of "coming off devel". Which works in 1.7.9 or later, but in 1.7.1 through 1.7.8 you have to spell it `git reset --keep`.
That might explain `--keep` but `--merge` is still a bit of a mystery.
Problem
In a recent answer in which he details the typical use cases of `git-reset`'s three most commonly used options (`--hard`, `--mixed`, and `--soft`), torek mentions in passing that `git-reset` also offers two relatively esoteric flags, called `--merge` and `--keep`. The `git-reset` man page describes those two flags as follows: ``` --merge Resets the index and updates the files in the working tree that are different between <commit> and HEAD, but keeps those which are different between the index and working tree (i.e. which have changes which have not been added). 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 different between <commit> and HEAD. If a file that is different between <commit> and HEAD has local changes, reset is aborted. ``` I perfectly understand when to use `--hard`, `--mixed`, or `--soft`, but I only learned that `--merge` and `--keep` existed while reading torek's answer, and I can't think of practical use cases of those two flags... In what situations do you typically use those two flags? I'm mainly looking for a plain-English explanation. Take the following passage of this answer by VonC, which spells out a typical use case for `git reset --soft`, as a model: [...] each time: - you are satisfied with what you end up with (in term of working tree and index) - you are not satisfied with all the commits that took you to get there: `git reset --soft` is the answer. However, I'm not averse to a little experiment with those flags, similar in spirit to the silly shopping-list example I posted in this answer of mine.