Reputation: 15974
I'm in the habit of stashing my changes in git and applying them again with git stash apply
. This has the advantage of keeping me from accidentally losing a stash I made, but it also means that my list of stashes grows rather quickly.
When I'm done with a branch, I go back through my stash list and manually remove all of the stashes associated with the branch. Is there a way to do this in a single command?
For example, my current stash list looks like this:
kevin@localhost:~/my/dev/work$ git stash list
stash@{0}: WIP on master: 346f844 Commit comment
stash@{1}: WIP on second_issues: a2f63e5 Commit comment
stash@{2}: WIP on second_issues: c1c96a9 Commit comment
stash@{3}: WIP on second_issues: d3c7949 Commit comment
stash@{4}: WIP on second_issues: d3c7949 Commit comment
stash@{5}: WIP on second_issues: d3c7949 Commit comment
stash@{6}: WIP on second_issues: 9964898 Commit comment
Is there a command that would drop all of the stashes from second_issues
?
Upvotes: 11
Views: 688
Reputation: 14875
What about this? It's a quick and dirty way that drops the stashes created on a given branch.
It simply lists all stashes, searches with grep for the stashes created on a branch, gets its stash name and finally passes those names git stash drop
through xargs.
git stash list | grep -E 'stash@{[0-9]+}.+ YOUR_BRANCH_NAME' | cut -d ':' -f 1 | xargs git stash drop
Edit
Digging in the man pages, it says the git stash list
also accepts git log
format options.
So we tell it to print lines that only match YOUR_BRANCHNAME
, and of those lines to just print its "reflag identity name" (%gd: shortened reflag selector, e.g., stash@{1}
, from the man page).
Then, we pass the output to xargs
to drop the stash.
git stash list --grep='YOUR_BRANCHNAME' --format='%gd' | xargs git stash drop
Upvotes: 4
Reputation: 10901
One approach to check the relationship between a stash and a given branch is to check if the parent commit of the stash is contained in your branch.
The parent commit of a stash is the commit from which the stash was created. If this commit is present in your branch of interest you could drop them or take the necessary action.
There is a small bash script to detect if any of your stashes originated from a commit that is currently contained in HEAD
:
#!/bin/bash
# Get a list of all stashes, like "stash@{0}", "stash@{1}", and so on
stashList=$(git stash list | grep -o "^stash@{[0-9]*}")
for stashRef in $stashList; do
# Obtain hashes for the stash and its first parent
currentHash=$(git rev-parse $stashRef)
parentHash=$(git rev-parse $stashRef^)
echo "$stashRef: $currentHash"
echo "parent: $parentHash"
# merge-base checks for the common parent
mergeBase=$(git merge-base $parentHash HEAD)
# If a commit is contained in another commit, it will be the base
# commit returned by merge-base
if [[ $mergeBase == $parentHash ]]; then
echo 'Contained in HEAD'
else
echo 'Not contained in HEAD'
fi
done
Upvotes: 1
Reputation: 3568
The stash is not dependent on any branch. The stash is just the stash for your repository. Each repository has exactly one stash, but you can put as many change sets as you want in a stash and it will keep them for later. As such it is not the case that your stashes are different between branches. In your case stash@{6} will show you the same commit no matter what branch you have checked out. If you want to clear your stash you can run git stash clear
and that will clear your stash of all stashed changes for that repo. This is a pretty destructive operation so be careful when using it.
Upvotes: 4