按名称/消息删除 Git 隐藏的工作区

4
据我所知,Git无法根据名称/消息删除stash(尽管可以使用git stash save“name”按名称保存它)。然而,我真的很想拥有这个选项,用于创建我的工作流程的“组合别名”(特别是对于不熟悉Git并且应该尊重工作流程的同事)。
我知道我可以自己创建一个bash脚本,但是我想知道是否已经有人制作了这样的脚本!?这样我就可以按名称删除stash...
我的“update”别名大致如下:
git stash save -u "tempstash"
git fetch origin
[apply our workflow/update strategy]
git stash pop --index (should be: git stash delete "tempstash")

当前别名的问题在于,如果没有需要隐藏的内容,它将恢复旧的隐藏内容。

另一个选择是检查是否需要隐藏,但我总是想要一种按名称删除git隐藏内容的选项,这就是我提出这个问题的原因。

PS:我正在使用posh-git,但bash命令应该可以在别名中使用。

谢谢


就你的例子而言,"tempstash"并不是一个名称,它更像是一条消息(类似于日志消息)。 - John Szakmeister
4个回答

2
我找到了一种通过名称丢弃存储的方法。您可以按照以下步骤操作:
git stash drop stash@{$((git stash list | grep -w NAME_OF_THE_STASH) | cut -d "{" -f2 | cut -d "}" -f1)}

以下是脚本的详细说明:
  1. 我正在使用标准的git stash drop stash@{n}结构
  2. 我们需要获取想要删除的stash名称的n。为此,我们列出stash并使用匹配名称的grep筛选项。我使用了以下脚本:git stash list | grep -w NAME_OF_THE_STASH
  3. 从该项中,我们需要提取括号{}内的索引。我们可以通过在第2项脚本中添加以下内容来提取该数字:| cut -d "{" -f2 | cut -d "}" -f1
我已经测试过它,对我来说效果很好。
另外,如果您输入的名称不存在,则不会删除任何内容。
此外,只有完全匹配的名称才会被删除。如果您不一定需要完全匹配,则可以在grep后面删除-w

谢谢,我修改了命令以适应同名的多个存储库情况:它会返回"指定的修订版本过多"的错误信息。详见链接:https://dev59.com/AHrZa4cB1Zd3GeqP35Lt#76604077 - Yann Dìnendal

2
您可以通过首先检查是否有需要存储的内容来解决该问题。您可以使用在Checking for a dirty index or untracked files with Git中提出的一种检查索引是否脏的方法之一。
例如,如果没有要存储的更改,则此命令不会输出任何内容:
git status --porcelain

使用此命令,脚本可能如下所示:
is_stashing=$(git status --porcelain)
test -n "$is_stashing" && git stash save -u
git fetch origin
[apply our workflow/update strategy]
test -n "$is_stashing" && git stash pop --index

我该如何将这个放入别名中? - GerjanOnline

1
一种解决方法是使用存储名称作为正则表达式搜索 git reflog stash 并以 stash@{<number>} 格式获取其名称。
然后,您可以在 git 中创建别名以将其用作命令。 一个快速而简单的解决方案(可以大大改进)如下:
[alias]
   sshow = "!f() { git stash show `git reflog stash | egrep $* | awk '{printf $2}' | sed 's/://' `; }; f"
   ssdrop = "!f() { git stash drop `git reflog stash | egrep $* | awk '{printf $2}' | sed 's/://' `; }; f"

通过在您的.git/config中添加这两个别名,您可以查看存储中修改的文件:
git sshow <regexp matching the name of the stash>

你可以使用以下命令丢弃暂存:

git ssdrop <regexp matching the name of the stash>

1
我喜欢这个想法,但正如你所说,它应该得到改进,因为当没有匹配时,它只会选择最后一个存储区,这显然是危险的。 - GerjanOnline

0
基于 @eyal-gerber 的解决方案:
如果有多个结果,说明命令没有生效,所以我们需要保留第一个(或最后一个)结果,并循环运行它几次。
例如,要清除名为 "lint-staged automatic backup" 的最后一个存储区:
git stash drop stash@{$((git stash list | grep -w "lint-staged automatic backup" | tail -n1) | cut -d "{" -f2 | cut -d "}" -f1)}

运行此命令直到没有更多的情况(在这种情况下,它不会丢弃任何存储,只会打印错误信息)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接