George Garside Blog

A place of many ramblings about macOS and development. If you find something useful on here, it's probably an accident. • See all at

With three options to git-reset introduced in Git of the day #13: git reset --soft HEAD^ and Git of the day #6: git reset --hard ORIG_HEAD, being useful for resetting each of the three operations that one uses in regular workflows, the presence of further options seems redundant.

There are still cases where more granularity to the reset is needed. The option --keep fills one of these specific use cases: where one wants to reset the current branch to a different place, while keeping local modifications.

For example, suppose you make a feature branch in preparation to make a change.

$ git checkout master
$ git checkout -b feat/bar
$ echo "foo" >> barCode language: Shell Session (shell)

That's a reasonable change to make to the existing tracked file ‘bar’, based on its state in master.

However, now suppose the foo feature should have been made given feat/foo feature first. The branch should have been off feat/foo, not master. One way to resolve this is to stash changes, checkout and delete1/recreate the branch, then pop the stash.

$ git stash
$ git checkout feat/foo
$ git branch -D feat/bar
$ git checkout -b feat/bar
$ git stash pop

git reset --hard feat/foo would lose the changes to bar, but git reset feat/foo or git reset --soft feat/foo would also make the changes between feat/foo and feat/bar appear in the working copy. This is where --keep becomes useful.

$ git reset --keep feat/foo

Now feat/bar is branched off feat/foo and the change to bar file is kept, hence the name --keep.

  1. A better way of doing this in one command will be in a future post, as well as the previous master checkout before creating a branch. Two commands makes it clearer what's going on for now. ↩︎

Leave a Reply

No comments