如何在git中按名称命名和检索存储?

问题描述 投票:1153回答:18

我总是觉得你可以通过做git stash save stashname给一个藏匿名称,你可以稍后通过做git stash apply stashname申请。但似乎在这种情况下,所有发生的事情都是stashname将被用作藏匿描述。

有没有办法真正命名藏匿?如果没有,你会建议什么实现相同的功能?基本上我有一个小的藏匿,我会定期申请,但不想总是在git stash list寻找它的实际藏匿号是什么。

git git-stash
18个回答
550
投票

这是你如何做到的:

git stash save "my_stash"

其中"my_stash"是藏匿名称。

一些更有用的知识:所有的存储都存储在一个堆栈中。类型:

git stash list

这将列出你的所有藏匿处。

要应用存储并将其从存储堆栈中删除,请键入:

git stash pop stash@{n}

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

git stash apply stash@{n}

其中n是隐藏变化的指标。


4
投票

别名这可能是类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

最后的连字符表示从标准输入中获取输入。


4
投票

使用小的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是您想要的藏匿名称的子字符串。


2
投票

这是使用PowerShell实现此目的的一种方法:

More details here

git stash save NAME


2
投票

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


1
投票

这里的聚会晚了,但是如果使用VSCode,一个快速的方法是打开命令调色板(CTRL / CMD + SHIFT + P)并输入“Pop Stash”,你将能够按名称检索你的藏匿无需使用git CLI


1
投票

在我的鱼壳里

git stash apply

使用

gsap name_of_stash


1
投票

stash@{0}也与git stash drop的其他裁判合作。因此,您可以使用普通标记来获取持久性名称。这也有一个优点,你不能意外git stash poppstash它。

所以你可以像这样定义别名git config --global alias.pstash '!f(){ git stash && git tag "$1" stash && git stash drop; }; f' (又名“持久存储”):

git pstash x-important-stuff

现在您可以创建一个标记的存储:

show

applygit stash show x-important-stuff git stash apply x-important-stuff 一样,它像往常一样:

git stash save stashname
git stash apply stash^{/stashname}

1
投票

那这个呢?

fzf

1
投票

对于除了藏匿创建之外的所有内容,我将通过引入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

210
投票

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 man page


84
投票

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

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提交之上应用的,因此它会恢复原始存储状态而不会发生冲突。

你可以稍后将这个新分支重新定位到其他地方,这个地方是你藏匿时所处的位置。


43
投票

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

HEAD^

我时不时地想知道我是否应该使用stashes然后我看到上面的疯狂之类的东西,我对我正在做的事情感到满意:)


40
投票

被困不是你想要的永久性东西。在提交时使用标签可能会更好。构建你想藏匿的东西。做出承诺。为该提交创建标记。然后将你的分支回滚到git cherry-pick -n tagname。现在,当你想重新申请那个藏匿时,你可以使用-n--no-commit.zshrc)。


18
投票

我在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"

8
投票

Alias

git sapply "<regex>"

Usage

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

  • 兼容Git for Windows

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

git stash apply stash^{/<regex>}

7
投票

令人遗憾的是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" 但我不确定这是否会干扰正则表达式分隔符(我愿意接受建议)。


6
投票

这个答案很大程度上归功于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以最新的存储为目标,而不是像人们期望的那样失败。

© www.soinside.com 2019 - 2024. All rights reserved.