如何在git中通过名字命名和检索存储?

我总是有这样的印象,你可以通过做git stash save stashname一个名字,你可以通过做git stash apply stashname 。 但是,在这种情况下,似乎所有情况都是使用stashname作为存储描述。

有没有办法实际上命名藏匿? 如果不是,你会推荐什么来实现相同的function? 基本上我有一个小的暗藏,我会定期喜欢应用,但不希望总是不得不在git stash list它的实际隐藏号码是什么。

你实际上可以使用git的正则expression式语法来寻找名称,用于寻址对象:

 stash^{/<regex>} :/<regex> 

例如,当用保存名称保存你的藏品时:

 git stash save "guacamole sauce WIP" 

…你可以使用一个正则expression式来解决这个问题:

 git stash apply stash^{/guacamo} 

这将应用与正则expression式guacamo相匹配的最年轻的存储。 这样,你不必知道堆栈里藏着什么数字,你只需要知道它的名字。 这里没有比较清晰的语法,但是你可以在你的.gitconfig文件中创build一个别名:

 [alias] sshow = "!f() { git stash show stash^{/$*} -p; }; f" sapply = "!f() { git stash apply stash^{/$*}; }; f" 

然后你可以使用git sapply <regex>来应用这个存储(不丢弃)。
然后你可以使用git sshow <regex>显示:文件已更改,插入和删除

编辑:道具到这个StackOverflow答案如何在git别名中使用bash参数。

编辑2:这个答案用于包含droplist别名,但我已经删除它们,因为drop需要stash@{n}语法,而list根本没有过滤stash@{n} 。 如果有人知道如何解决隐藏的SHA-1哈希到存储引用,那么我也可以实现其他命令。

编辑3:每伊西的build议我已经添加了一个补丁标志来显示什么时候显示一个藏匿的内容。

这是你如何做到的:

 git stash save "my_stash" 

“my_stash”是存储名称…

一些更有用的东西要知道:所有的窗口都存储在一个堆栈中。 input :

 git stash list 

这将列出你的所有窗口。

要申请一个藏匿处并将其从藏匿处移走,你可以给,

 git stash pop stash@{n} 

要应用存储并将其保存在存储堆栈中,请键入:

 git stash apply stash@{n} 

藏在指数中的n变化。

如果你觉得它足够重要,你可以把一个藏匿处变成一个分支:

 git stash branch <branchname> [<stash>] 

从手册页:

这将创build并签出一个名为<branchname>的新分支,从最初创build<stash>的提交开始,将logging在<stash>中的更改应用到新的工作树和索引,然后删除<stash>成功完成。 当没有<stash>时,应用最新的一个。

如果您运行git stash save的分支已经发生了足够的变化,那么git stash apply会因为冲突而失败。 由于在git存储运行时HEAD的提交之上应用了存储,因此它将恢复原始存储的状态而不产生冲突。

你以后可以把这个新的分支重新分配到其他地方,这个地方就是你藏身的地方的后代。

绦带并不意味着像你想要的永久性东西。 在提交时使用标签可能会更好。 构build你想存储的东西。 做一个承诺吧。 为该提交创build一个标签。 然后将您的分支回滚到HEAD^ 。 现在,当你想重新申请,你可以使用git cherry-pick -n tagname-n--no-commit )。

别号

sapply = "!f() { git stash apply \"$(git stash list | awk -F: --posix -vpat=\"$*\" \"$ 0 ~ pat {print $ 1; exit}\")\"; }; f"

用法

git sapply "<regex>"

  • 兼容Windows的Git

编辑:我坚持我的原始解决scheme,但我明白为什么大多数人会更喜欢Etan Reisner的版本(上图)。 所以只是为了logging:

 sapply = "!f() { git stash apply \"$(git stash list | grep -E \"$*\" | awk \"{ print $ 1; }\" | sed -n \"s/://;1p\")\"; }; f" 

别名对于类Unix系统,这可能是更直接的语法,不需要封装在函数中。 将以下内容添加到[alias]下的〜/ .gitconfig

 sshow = !sh -c 'git stash show stash^{/$*} -p' - sapply = !sh -c 'git stash apply stash^{/$*}' - ssave = !sh -c 'git stash save "${1}"' - 

用法:sapply 正则expression式

例如:git sshow MySecretStash

末尾的连字符表示从标准input中input。

使用git stash save NAME来保存。

然后…你可以使用这个脚本来select应用(或popup):

 #!/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 

我喜欢能够看到窗口的名称,并select。 另外我用Zshell,坦率地说,不知道如何使用上面的一些Bash别名;)

注意:正如凯文所说, 你应该使用标签和樱桃select。

对于除了存储创build之外的所有东西,我会通过引入fzf作为依赖来提出另一个解决scheme。 build议花5分钟的时间,并介绍给它,因为它是一个伟大的生产力的助推器。

无论如何,从他们的例子页面提供存储search的相关摘录。 更改sciptlet以添加附加function(如隐藏应用程序或删除)非常简单:

 fstash() { local out qk 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 } 

这是使用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'' } } 

更多细节在这里

如果您只是寻找一种轻量级的方式来保存当前工作副本的部分或全部更改,然后在以后再重新应用它们,请考虑一个补丁文件:

 # save your working copy changes git diff > some.patch # re-apply it later git apply some.patch 

我时不时地想知道是不是应该用这种方法来保存这些东西,然后我就会看到上面的那些疯狂的事情,而且我很满意我在做什么:)