git-stash changes without reverting
This can be achieved by manually creating a stash commit object, then storing it in the stash.
git stash store $(git stash create) -m "Stash commit message"
Explanation
I too like throwing things into the stash as a rollback point, before proceeding with a change or refactoring that I feel might not pan out. I find that throwing it onto the stash with a brief description is quicker, easier, and requires less mental context switching than using a branch does. Using a branch involves creating the branch, remembering the branch name, and then deleting the interim branch commit and the branch it self when resuming.
Git has commands to store things into the stash without removing the files from the working directory, as explained in https://stackoverflow.com/a/44330944/1108305. A stash commit object can be created with git stash create
and then saved to the stash using git stash store
:
git stash store $(git stash create) -m "Stash commit message"
This can be saved to a Git alias to make it more convenient:
git config --global alias.stash-keep '!git stash store $(git stash create)'
git stash-keep -m "Stash commit message"
Note that this does not do everything that git stash push
does. For one, it does not append the branch name to the commit, e.g. "stash@{0}: On myBranch: Stash commit message
". Secondly, the above simple alias will error with ""git stash store" requires one <commit> argument
" instead of "No local changes to save
" when there are no changes to stash. Those limitations could be addressed with a more complex alias or script, though the minimal version provided here will likely be sufficient.
When I posted this question I was new to git and didn't understand its power in full. Now I realize that stashing is not what I needed and that git's local branches do the job much better.
Assume you are on main_branch, which you want to keep clean from experimental changes.
Simply create a new branch in order to store your experimental changes.
git checkout -b temp_branch
Assume you do some changes and want to save your progress. Simply commit, nothing to worry about, it's all on the temp_branch:
git commit -a -m "first change"
Assume you do some more changes and want to store again:
git commit -a -m "second change"
Finally, assume you are happy with your experimental changes and want to merge them to the main branch. There are two cases:
1) If you want to merge all changes, do:
git fetch . temp_branch:main_branch
This brings all changes of temp_branch into the main_branch, without switching to the main branch, which means your files are not modified and no recompilation is required. Note it's possible only if you haven't done any other changes on main_branch in the meantime. If main_branch has changed you need to use git merge
or git rebase
, but this scenario is beyond what the question is asking.
2) Assume you want to merge only some of the commits of temp_branch into main_branch. You can do this with git cherry-pick
. First do git checkout main_branch
to switch to the main_branch (this modifies the files but this is inevitable since you are dropping some of your changes), then do git cherry-pick <SHA>
(where <SHA>
is the hash of the commit you want to merge). You can see the list of commits by doing git log temp_branch
. Note that merging only some of the changes might give conflicts which you 'll need to resolve.