我总是觉得你可以通过做git stash save stashname
给一个藏匿名称,你可以稍后通过做git stash apply stashname
申请。但似乎在这种情况下,所有发生的事情都是stashname
将被用作藏匿描述。
有没有办法真正命名藏匿?如果没有,你会建议什么实现相同的功能?基本上我有一个小的藏匿,我会定期申请,但不想总是在git stash list
寻找它的实际藏匿号是什么。
这是你如何做到的:
git stash save "my_stash"
其中"my_stash"
是藏匿名称。
一些更有用的知识:所有的存储都存储在一个堆栈中。类型:
git stash list
这将列出你的所有藏匿处。
要应用存储并将其从存储堆栈中删除,请键入:
git stash pop stash@{n}
要应用存储并将其保存在存储堆栈中,请键入:
git stash apply stash@{n}
其中n
是隐藏变化的指标。
别名这可能是类Unix系统的更直接的语法,无需封装在函数中。将以下内容添加到[alias]下的〜/ .gitconfig
NAME="$1"
if [[ -z "$NAME" ]]; then echo "usage: gitapply [name]"; exit; fi
git stash apply $(git stash list | grep "$NAME" | cut -d: -f1)
用法:sapply正则表达式
示例:git show My Secret Stash
最后的连字符表示从标准输入中获取输入。
使用小的bash脚本来查找存储的数量。称之为“gitapply”:
gitapply foo
用法:
<#
.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''
}
}
...其中foo是您想要的藏匿名称的子字符串。
使用#!/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
保存。
然后......您可以使用此脚本选择要应用(或弹出)的内容:
you should use tags and cherry-picks instead.
我喜欢能够看到藏匿处的名字并选择。我也使用Zshell,坦率地说不知道如何使用上面的一些Bash别名;)
注意:凯文说,function gsap
git stash list | grep ": $argv" | tr -dc '0-9' | xargs git stash apply
end
这里的聚会晚了,但是如果使用VSCode,一个快速的方法是打开命令调色板(CTRL / CMD + SHIFT + P)并输入“Pop Stash”,你将能够按名称检索你的藏匿无需使用git CLI
在我的鱼壳里
git stash apply
使用
gsap name_of_stash
stash@{0}
也与git stash drop
的其他裁判合作。因此,您可以使用普通标记来获取持久性名称。这也有一个优点,你不能意外git stash pop
或pstash
它。
所以你可以像这样定义别名git config --global alias.pstash '!f(){ git stash && git tag "$1" stash && git stash drop; }; f'
(又名“持久存储”):
git pstash x-important-stuff
现在您可以创建一个标记的存储:
show
和apply
和git stash show x-important-stuff
git stash apply x-important-stuff
一样,它像往常一样:
git stash save stashname
git stash apply stash^{/stashname}
那这个呢?
fzf
对于除了藏匿创建之外的所有内容,我将通过引入examples page作为依赖项来提出另一种解决方案。建议花5分钟的时间来介绍它,因为它总体上提高了生产力。
无论如何,他们的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
}
提供藏匿搜索的相关摘录。更改sciptlet以添加其他功能(如存储应用程序或删除)非常容易:
qazxswpoi
git stash save
自2.15.x / 2.16起已弃用,您可以使用git stash push -m "message"
你可以像这样使用它:
git stash push -m "message"
其中“消息”是您存储的注释。
为了检索藏匿,您可以使用: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 branch <branchname> [<stash>]
从手册页:
这将创建并检出一个名为<branchname>
的新分支,从最初创建<stash>
的提交开始,将<stash>
中记录的更改应用于新的工作树和索引,然后在成功完成时删除<stash>
。如果没有给出<stash>
,则应用最新的git stash save
。
如果运行# save your working copy changes
git diff > some.patch
# re-apply it later
git apply some.patch
的分支已经发生了足够的变化,git stash apply因冲突而失败,那么这很有用。由于存储是在运行git stash时的HEAD提交之上应用的,因此它会恢复原始存储状态而不会发生冲突。
你可以稍后将这个新分支重新定位到其他地方,这个地方是你藏匿时所处的位置。
如果您只是想要一种轻量级的方法来保存当前的部分或全部工作副本更改,然后随意重新应用它们,请考虑一个补丁文件:
HEAD^
我时不时地想知道我是否应该使用stashes然后我看到上面的疯狂之类的东西,我对我正在做的事情感到满意:)
被困不是你想要的永久性东西。在提交时使用标签可能会更好。构建你想藏匿的东西。做出承诺。为该提交创建标记。然后将你的分支回滚到git cherry-pick -n tagname
。现在,当你想重新申请那个藏匿时,你可以使用-n
(--no-commit
是.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=\"$*\" \"$ 0 ~ pat {print $ 1; exit}\")\"; }; f"
git sapply "<regex>"
sapply = "!f() { git stash apply \"$(git stash list | grep -E \"$*\" | awk \"{ print $ 1; }\" | sed -n \"s/://;1p\")\"; }; f"
编辑:我坚持我的原始解决方案,但我明白为什么大多数人会更喜欢Etan Reisner的版本(上图)。所以只是为了记录:
git stash apply stash^{/<regex>}
令人遗憾的是accepted answer不起作用(它实际上并没有搜索存储列表,请参阅git stash list
下的评论)。
以下是通过正则表达式搜索stash@{<n>}
以找到第一个(最近的)git stash <command>
然后将其传递给# 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)
的替代品:
# ~/.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 $?
请注意,返回正确的结果代码,以便您可以在其他脚本中使用这些命令。这可以在运行命令后验证:
variable expansion exploits
请注意--grep=$1
,因为我不确定--grep="$1"
部分。它应该是[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"
但我不确定这是否会干扰正则表达式分隔符(我愿意接受建议)。
这个答案很大程度上归功于KlemenSlavič。我会对已接受的答案发表评论,但我还没有足够的代表:(
您还可以添加一个git别名来查找存储引用,并将其用于show,apply,drop等其他别名。
ref=$( ... ); echo ${ref:-<no_match>};
请注意,sshow = !sh -c 'git stash show stash^{/$*} -p' -
sapply = !sh -c 'git stash apply stash^{/$*}' -
ssave = !sh -c 'git stash save "${1}"' -
模式的原因是没有返回空白字符串,这会导致sshow,sapply和sdrop以最新的存储为目标,而不是像人们期望的那样失败。