在我的印象中,你可以通过git stash save stashname
给一个储藏库起个名字,之后你可以通过git stash apply stashname
来应用它。但在这种情况下,似乎所有发生的事情都是stashname
将被用作储藏库的描述。
是否没有办法真正地命名一个储藏库?如果没有,你有什么建议来实现同等的功能?基本上,我有一个小的储藏库,我想定期应用,但不想总是在git储藏库列表
中寻找它的实际储藏库编号是什么。
这就是你如何做的。
git stash save "my_stash"
其中"my_stash"
是储藏室的名称。
还有一些有用的东西要知道。所有的藏书都存储在一个堆栈中。 类型。
git stash list
这将列出你所有的藏品。
要应用一个藏品并将其从藏品堆栈中删除,请输入。
git stash pop stash@{n}
要应用一个藏品并将其保留在藏品堆栈中,请键入。
git stash apply stash@{n}
其中`n'是储藏的变化的索引。
git stash save
在2.15.x/2.16中被**淘汰,你可以使用git stash push -m "message"
来代替。
你可以像这样使用。
git stash push -m "message"
。
其中"message" 是你对该stash的注释。
为了检索该储藏库,你可以使用。
git stash list
.
这将会输出一个类似这样的列表,例如
stash@{0}: On develop: perf-spike
stash@{1}: On develop: node v10
然后你只需使用apply
给它一个stash@{index}
。
git stash apply stash@{1}
参考资料 [git stash man page][1]
如果你觉得它足够重要,你可以把一个藏品变成一个分支。
git stash branch <branchname> [<stash>]
来自手册页。
这将创建并检查一个名为"lt;stash>
,则应用最新的。
如果你运行 git stash save
的分支发生了足够的变化,导致 git stash apply 因冲突而失败,这就很有用。由于藏匿被应用在运行 git stash 时的 HEAD 提交之上,它恢复了最初的藏匿状态,没有冲突。
你以后可以把这个新的分支重新放置到其他地方,也就是你藏匿时的地方的后代。
在我的.zshrc
文件里有这两个函数。
function gitstash() {
git stash push -m "zsh_stash_name_$1"
}
function gitstashapply() {
git stash apply $(git stash list | grep "zsh_stash_name_$1" | cut -d: -f1)
}
这样使用它们。
gitstash nice
gitstashapply nice
sapply = "!f() { git stash apply \"$(git stash list | awk -F: --posix -vpat=\"$*\" \&quot;$ 0 ~ pat {print $ 1; exit}\")\"; }; f"
git sapply "<regex>"
。
编辑。 我坚持我最初的解决办法,但我明白为什么大多数人更喜欢Etan Reisner的版本(上文)。 所以,只是为了记录在案:。
sapply = "!f() { git stash apply \"$(git stash list | grep -E \"$*\" | awk \"{ print $ 1; }\" | sed -n \"s/://;1p\")\"; }; f"
不幸的是,"git stash apply stash^{/
这里有一些替换方法,可以通过 regex 搜索 git stash list
,找到第一个(最近的)stash@{<n>}
,然后将其传递给 git stash <command>
。
<!--language-all: lang-sh -->
# standalone (replace <stash_name> with your regex)
(n=$(git stash list --max-count=1 --grep=<stash_name> | cut -f1 -d":") ; if [[ -n "$n" ]] ; then git stash show "$n" ; else echo "Error: No stash matches" ; return 1 ; fi)
(n=$(git stash list --max-count=1 --grep=<stash_name> | cut -f1 -d":") ; if [[ -n "$n" ]] ; then git stash apply "$n" ; else echo "Error: No stash matches" ; return 1 ; fi)
<!--语言。 lang-none -->
# ~/.gitconfig
[alias]
sshow = "!f() { n=$(git stash list --max-count=1 --grep=$1 | cut -f1 -d":") ; if [[ -n "$n" ]] ; then git stash show "$n" ; else echo "Error: No stash matches $1" ; return 1 ; fi }; f"
sapply = "!f() { n=$(git stash list --max-count=1 --grep=$1 | cut -f1 -d":") ; if [[ -n "$n" ]] ; then git stash apply "$n" ; else echo "Error: No stash matches $1" ; return 1 ; fi }; f"
# usage:
$ git sshow my_stash
myfile.txt | 1 +
1 file changed, 1 insertion(+)
$ git sapply my_stash
On branch master
Your branch is up to date with 'origin/master'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: myfile.txt
no changes added to commit (use "git add" and/or "git commit -a")
请注意,正确的结果代码会被返回,所以你可以在其他脚本中使用这些命令。 这可以在运行以下命令后得到验证。
echo $?
只是要小心[变量扩展漏洞][2],因为我不确定--grep=$1
部分。
也许应该是--grep="$1"
,但我'不确定这是否会干扰到regex定界符(我'愿意接受建议)。
[1]: https://stackoverflow.com/a/11688523/539149 [2]: https://unix.stackexchange.com/questions/171346/security-implications-of-forgetting-to-quote-a-variable-in-bash-posix-shells
这个答案要感谢Klemen Slavič。 我本来只想评论一下被接受的答案,但我还没有足够的rep:(
你也可以添加一个git别名来找到stash ref,并将其用于show、apply、drop等其他别名中。
[alias]
sgrep = "!f() { ref=$(git --no-pager stash list | grep "$1" | cut -d: -f1 | head -n1); echo ${ref:-<no_match>}; }; f"
sshow = "!f() { git stash show $(git sgrep "$1") -p; }; f"
sapply = "!f() { git stash apply $(git sgrep "$1"); }; f"
sdrop = "!f() { git stash drop $(git sgrep "$1"); }; f"
请注意,ref=$( ... ...)的原因。 ); echo ${ref:-<no_match>};
模式是为了避免返回一个空白字符串,这样会导致sshow、sapply和sdrop以最新的储藏为目标,而不是像人们期望的那样失败。
阿利亚斯 对于类似 Unix 的系统来说,这可能是一种更直接的语法,而不需要用函数来封装。 在 ~/.gitconfig 的 [alias] 下添加以下内容
sshow = !sh -c 'git stash show stash^{/$*} -p' -
sapply = !sh -c 'git stash apply stash^{/$*}' -
ssave = !sh -c 'git stash save "${1}"' -
使用方法: sapply regex
例如 git sshow MySecretStash
末尾的连字符说的是从标准输入中获取输入。
用git stash save NAME
来保存。
然后... 你可以使用这个脚本来选择应用(或弹出)哪个。
#!/usr/bin/env ruby
#git-stash-pick by Dan Rosenstark
# can take a command, default is apply
command = ARGV[0]
command = "apply" if !command
ARGV.clear
stashes = []
stashNames = []
`git stash list`.split("\n").each_with_index { |line, index|
lineSplit = line.split(": ");
puts "#{index+1}. #{lineSplit[2]}"
stashes[index] = lineSplit[0]
stashNames[index] = lineSplit[2]
}
print "Choose Stash or ENTER to exit: "
input = gets.chomp
if input.to_i.to_s == input
realIndex = input.to_i - 1
puts "\n\nDoing #{command} to #{stashNames[realIndex]}\n\n"
puts `git stash #{command} #{stashes[realIndex]}`
end
我喜欢能够看到储藏室的名称并进行选择。 另外,我使用Zshell,坦率地说,我不知道如何使用上面的一些Bash别名;)
注意事项。 正如Kevin所说,[你应该使用标签和cherry-picks来代替。][1]
这是用PowerShell实现的一种方法。
<#
.SYNOPSIS
Restores (applies) a previously saved stash based on full or partial stash name.
.DESCRIPTION
Restores (applies) a previously saved stash based on full or partial stash name and then optionally drops the stash. Can be used regardless of whether "git stash save" was done or just "git stash". If no stash matches a message is given. If multiple stashes match a message is given along with matching stash info.
.PARAMETER message
A full or partial stash message name (see right side output of "git stash list"). Can also be "@stash{N}" where N is 0 based stash index.
.PARAMETER drop
If -drop is specified, the matching stash is dropped after being applied.
.EXAMPLE
Restore-Stash "Readme change"
Apply-Stash MyStashName
Apply-Stash MyStashName -drop
Apply-Stash "stash@{0}"
#>
function Restore-Stash {
[CmdletBinding()]
[Alias("Apply-Stash")]
PARAM (
[Parameter(Mandatory=$true)] $message,
[switch]$drop
)
$stashId = $null
if ($message -match "stash@{") {
$stashId = $message
}
if (!$stashId) {
$matches = git stash list | Where-Object { $_ -match $message }
if (!$matches) {
Write-Warning "No stashes found with message matching '$message' - check git stash list"
return
}
if ($matches.Count -gt 1) {
Write-Warning "Found $($matches.Count) matches for '$message'. Refine message or pass 'stash{@N}' to this function or git stash apply"
return $matches
}
$parts = $matches -split ':'
$stashId = $parts[0]
}
git stash apply ''$stashId''
if ($drop) {
git stash drop ''$stashId''
}
}
[此处有更多细节][1]
[1]: https://geoffhudik.com/tech/2017/07/19/git-command-line-part-5/ "更多信息"。
git stash apply
也适用于stash@{0}
以外的其他 refs。
所以你可以使用普通的tags来获得一个持久的名字。
这也有一个好处,就是你不能意外地git stash drop
或git stash pop
它。
所以你可以定义一个别名 pstash
(又名 "persistent stash") 像这样。
git config --global alias.pstash '!f(){ git stash && git tag "$1" stash && git stash drop; }; f'
现在你可以创建一个标签式的储藏室。
git pstash x-important-stuff
和 "显示",再像往常一样 "应用"。
git stash show x-important-stuff
git stash apply x-important-stuff
对于除了创建储藏室之外的所有东西,我建议采用另一种解决方案,引入fzf作为依赖。 推荐你花5分钟时间去了解它,因为它是一个很好的生产力提升器。
总之,从他们的示例页中摘录了相关的内容,提供了匿迹搜索。 要改变sciptlet来添加额外的功能(如匿迹应用或投递)是非常容易的。
fstash() {
local out q k sha
while out=$(
git stash list --pretty="%C(yellow)%h %>(14)%Cgreen%cr %C(blue)%gs" |
fzf --ansi --no-sort --query="$q" --print-query \
--expect=ctrl-d,ctrl-b); do
mapfile -t out <<< "$out"
q="${out[0]}"
k="${out[1]}"
sha="${out[-1]}"
sha="${sha%% *}"
[[ -z "$sha" ]] && continue
if [[ "$k" == 'ctrl-d' ]]; then
git diff $sha
elif [[ "$k" == 'ctrl-b' ]]; then
git stash branch "stash-$sha" $sha
break;
else
git stash show -p $sha
fi
done
}