Better Git Stashing

I often find myself wanting to stash just one change or file rather than stashing all changes in the working directory. Git hasn’t historically made this easy. Although you can git add the changes you want to keep and then run git stash --keep-index to stash the other changes, it is rather clunky.

Thankfully there is a better way.

Git has an interactive stash mode you can activate with —-patch. It provides the ability to step through code changes and stash (or skip) each individually (git add has an interactive mode as well).

» git stash --patch
diff --git a/content/post/purge-redis-keys-with-lua-script.md b/content/post/purge-redis-keys-with-lua-script.md
index a5f9fc5..78069a8 100644
--- a/content/post/purge-redis-keys-with-lua-script.md
+++ b/content/post/purge-redis-keys-with-lua-script.md
@@ -6,6 +6,8 @@ slug = "purge-redis-keys-with-lua-script"

 +++

+New change here!
+
 Redis has some powerful [Lua scripting capabilities](https://www.redisgreen.net/blog/intro-to-lua-for-redis-programmers/). One of the uses I've found for this feature is purging cache keys. On occasion I need to purge a set of keys that all have the same prefix.

 The following command will do just that.
Stash this hunk [y,n,q,a,d,e,?]?

Git will display the change along with the surrounding text. If you enter y and hit enter git will stash the “hunk” and move to the next one. You can skip hunks with n and quit entirely with q.

Entering ? gives you more details about the possible commands.

y - stash this hunk
n - do not stash this hunk
q - quit; do not stash this hunk or any of the remaining ones
a - stash this hunk and all later hunks in the file
d - do not stash this hunk or any of the later hunks in the file
e - manually edit the current hunk
? - print help

Additionally there is a new option in git v2.13 that allows you to stashing a file or directory by specifying its path. The simple trick is use git stash as normal but followed by a -- and the path of the file.

» git stash -- content/post/purge-redis-keys-with-lua-script.md
Saved working directory and index state WIP on master: 0cba4a5 Hide timestamp on pages
------------------------------------------------------------
»

Finally, if you’re like me and use git stash excessively you’ll end up with many stashed changes you’ve abandoned and no longer need. View your stash list with git stash list and you’ll get something like this:

stash@{0}: WIP on master: 88dd4dd3 Merged in cst-11221/refactor-cloud-subscription-search (pull request #292)
stash@{1}: WIP on jest-bug: ad4873d7 Setup StaffId authentication for smoke tests
stash@{2}: WIP on CST-12687-pdf-link-sidebar: 25b3273c CST-12687 Fix tests
stash@{3}: WIP on ITIW18Q4-5-setup-cypress: d0d14d03 Simplify tests
stash@{5}: WIP on master: ed3aac37 Merged in cst-12175/show-upcoming-bill-changes-tab (pull request #235)
stash@{6}: WIP on master: 505e0278 Merged in remove-max-result-limit (pull request #234)
stash@{7}: WIP on master: 505e0278 Merged in remove-max-result-limit (pull request #234)
stash@{8}: WIP on statsd: 37284e82 Setup a statsd client and add some basic instrumentation
stash@{9}: WIP on CST-12027-account-disabled: 0b7e5cac CST-12027 Add account disabled badge to contact page
stash@{10}: WIP on master: bf900e1e Merged in CST-12047-backend-uat (pull request #207)
stash@{11}: WIP on CST-12027-account-disabled: 0b7e5cac CST-12027 Add account disabled badge to contact page
stash@{12}: WIP on parallel-pipelines: d85a4961 Add node cache back to pipeline. Oops...did not mean to remove.

Use git stash clear to delete your stashes. Be careful to not delete anything you actually need.

Since I use git stash a lot I’ve created the following aliases in my .zshrc file.

alias gsp='git stash push' # Push is implied with `git stash` but push allows a file to be specified without -- separator
alias gspi='git stash push --patch'
alias gspp='git stash pop'
alias gspc='git stash clear