2014-09-29 43 views

回答

1

Stashes不是真的“在一个分支上”,他们在特定的提交(请参阅this answer针对我的意思图的不同问题)。这就是说,任何指定的提交,可以说是“上”零个或多个分支,所以给出一个分支的名字,你会发现和测试每个藏匿:

let to_drop = empty_set() 
for (s in all_stashes): 
    let c = commit_of(s) 
    if is_on_branch(c, branch): 
     add_to_set(s, to_drop) 
for s in reverse(to_drop): 
    execute("git stash drop " + s) 

更多或更少(这是假的Python ,我发现它比伪外壳更像伪代码)。这定义了一个“在分支上”的存储概念,这是我在本答案的其余部分使用的概念。

(倒退的原因是,“所有窗口”可能会出现“存储@ {0},存储@ {1},存储@ {2},...,存储@ {n }“并且当我们放下某个存储时,所有更高编号的存储都会重新编号,所以如果我们向后工作,我们可以避免重新编号剩余存储。)

要将上面的代码转换为工作shell脚本代码,我们只需要做明显的翻译。这里有一堆件(主要是未经测试,一些作品在隔离测试):

# Produce a list of all refs/[email protected]{n} and sha-1. 
# Might be nice if we could use --reverse here, but 
# we can't. 
all_stashes() { 
    git log -g --pretty=format:"%gd %H" refs/stash 
} 

(以上仅仅是git stash list砍死了一下打印藏匿名称和完整的哈希值)

# Determine whether the given commit ($2) is on the given branch ($1). 
# If the commit is on multiple branches, we say "yes" if ANY of those 
# match $1 (but the match must be exact). Note that the while loop 
# runs in a subshell so we use an eval trick here. (Probably would 
# be better to just write this in awk.) 
# 
# Note that "git branch --contains" prints " A -> B" for indirect 
# branches; we ignore these. It prefixes the current branch with "* " 
# and others with " ", and we discard these prefixes. You may want 
# to fiddle with the first decision. 
is_on() { 
    local branch 
    eval $(git branch --contains $2 | sed -e '/ -> /d' -e 's/^..//' | 
     while read branch; do 
      [ "$branch" = "$1" ] && echo return 0 
     done) 
    return 1 
} 

# Given branch name ($1), find all stashes whose parent commit 
# is on that branch. 
stashes_on_branch() { 
    local refname hash 

    all_stashes | while read refname hash; do 
     is_on "$1" ${hash}^ && echo "$refname" 
    done 
} 

(顺便说一句,sh似乎让return 0 1 2 3但bash的抱怨,因此上述可能需要在某些系统上呼应return 0后居然跳出循环。)

逆转行的列表,“TAC”将是理想的,但大多数系统没有它。我们可以使用bash阵列等,但这是简单了很多,虽然效率低,受到问题,如果一个分支命名为-e例如:

# Reverse a list of lines 
reverse() { 
    local line text nl=$'\n' 
    while read line; do 
     text="$line$nl$text" 
    done 
    echo -n "$text" 
} 

与所有这些碎片它现在微不足道的下降属于藏匿处“在”给定分支:

for stash in $(stashes_on_branch foobranch); do git stash drop $stash; done 

所有这一切说,仅仅因为一个分支合并并不一定意味着都藏匿“上”分支应该被丢弃。如果这是您特定的工作流程,那么很好;但这是非常不寻常的,没有什么特别的理由,隐藏脚本应该有这个内置的。