删除与特定分支关联的所有stashes

时间:2013-07-10 17:17:58

标签: git

我习惯于在git中存储我的更改并使用git stash apply再次应用它们。这样做的好处是可以防止我不小心丢失了我制作的藏品,但这也意味着我的藏匿列表增长得相当快。

当我完成分支后,我会通过我的存储列表返回并手动删除与分支相关的所有存储。有没有办法在一个命令中执行此操作?

例如,我当前的藏匿列表如下所示:

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

是否有一个命令会丢弃second_issues的所有藏匿处?

3 个答案:

答案 0 :(得分:4)

这个怎么样?这是一种快速而肮脏的方式,可以删除在给定分支上创建的藏匿处。

它只是列出所有的藏匿处,使用grep搜索在分支上创建的藏匿处,获取其藏匿名称,最后将这些名称git stash drop传递给xargs。

git stash list | grep -E 'stash@{[0-9]+}.+ YOUR_BRANCH_NAME' | cut -d ':' -f 1 | xargs git stash drop

修改

在手册页中,它表示git stash list也接受git log格式选项 因此,我们告诉它打印仅匹配YOUR_BRANCHNAME的行,以及这些行只打印其手册页中的“reflag identity name”(%gd: shortened reflag selector, e.g., stash@{1})。
然后,我们将输出传递给xargs以删除存储。

git stash list --grep='YOUR_BRANCHNAME' --format='%gd' | xargs git stash drop

答案 1 :(得分:2)

存储不依赖于任何分支。存储只是存储库的存储。每个存储库只有一个存储区,但您可以在存储区中放置任意数量的更改集,并将其保留以供日后使用。因此,不是分支之间的存储不同的情况。在您的情况下,无论您检查了哪个分支,存储@ {6}都会向您显示相同的提交。如果你想清除你的存储,你可以运行git stash clear,这将清除你对该回购的所有藏匿更改的藏匿。这是一个非常具有破坏性的操作,因此在使用时要小心。

答案 2 :(得分:1)

检查存储和给定分支之间关系的一种方法是检查存储的父提交是否包含在您的分支中。

存储的父提交是从中创建存储的提交。如果您的感兴趣的分支中存在此提交,您可以删除它们或采取必要的操作。

有一个小的bash脚本可以检测你的任何存储是否来自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