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

Sua*_*uan 1276 git git-stash

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

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

Sri*_*ula 665

这是你如何做到的:

git stash save "my_stash"
Run Code Online (Sandbox Code Playgroud)

其中"my_stash"是藏匿名称...

一些更有用的知识:所有的存储都存储在一个堆栈中.输入 :

git stash list
Run Code Online (Sandbox Code Playgroud)

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

要应用存储并将其从存储堆栈中删除,您可以给,

git stash pop stash@{n}
Run Code Online (Sandbox Code Playgroud)

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

git stash apply stash@{n}
Run Code Online (Sandbox Code Playgroud)

其中n在隐藏的索引中发生变化.

  • 这不回答这个问题.默认情况下,您最终会获得一堆数字用于存储,但这并不能解答您如何轻松识别名称. (68认同)
  • `git stash push -m my_stash`是[当前语法](https://git-scm.com/docs/git-stash#git-stash-save-p--patch-k--no-keep-index -u - 包括-未跟踪-A - 所有-q - quietltmessagegt).`git stash save my_stash`已被弃用. (33认同)
  • 这不是无关紧要的.它是有益的. (14认同)
  • OP明确地试图避免用于自定义名称的难以命名的存储@ {n}名称.`git stash apply <custom-name>` (8认同)
  • 我使用 `git stash push -m my_stash` 创建了一个存储,然后执行了 `git stash apply my_stash` 并给出了错误。`git stash apply stash^{/my_stash}` 完成了这项工作。这是从@Cameron McKenzie 的另一个答案中得到的。 (6认同)
  • 不回答有关按名称检索藏匿的问题. (5认同)
  • 由于它是简单的命令,我添加了一些更有用的信息.但你是对的,我现在已经编辑了我的答案.希望现在相关:) (4认同)
  • 该答案应被删除为无关紧要的。 (4认同)
  • 当我执行“git stash pop stash^{/edit_cell}”时,我得到:“错误:'stash^{/edit_cell}'不是存储引用”。这是为什么?另外,我找不到任何有关语法“stash^{}”的文档。我可以得到它的链接吗?好吧,我尝试用 apply 而不是 pop 并且它有效...... (3认同)
  • 这很令人困惑。只有@AdamB回答了这个问题 (2认同)
  • 如果您使用 Windows power-shell,stash apply 可能会抛出错误。所以请将其放在引号中。`git stash 应用“stash@{n}”` (2认同)

Ess*_*diM 320

git stash save弃用作为2.15.x/2.16,而不是你可以使用git stash push -m "message"

你可以这样说:

git stash push -m "message"

其中"消息"是你的藏匿名称......

  • 这才是真正的答案.不幸的是,它上面有很多旧的答案. (20认同)
  • docs显示`push`而不是`save`语法:[git stash push](https://git-scm.com/docs/git-stash#git-stash-save-p--patch-k--no-保持指数-U - 包括-未跟踪-A - 所有-q - quietltmessagegt) (7认同)
  • FWIW:在 Powershell 中运行“git stash apply stash@{1}”时,您将收到“错误:未知开关‘e’”。而是使用 `git stash apply --index 1` 或 `git stash apply 'stash@{1}'` 或使用反引号 ` 转义 `}` 和 `{`。 (3认同)
  • 为什么 git 选择像“stash@{1}”这样尴尬的命名风格?在命令行上输入确实很难。如果我们可以输入类似“git stash show -p @1”之类的内容就会容易得多...... (3认同)

Ada*_*ruk 94

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

git stash branch <branchname> [<stash>]
Run Code Online (Sandbox Code Playgroud)

从手册页:

这将创建并检出一个名为<branchname>的新分支,从最初创建<stash>的提交开始,将<stash>中记录的更改应用于新的工作树和索引,然后删除<stash>成功完成.如果没有给出<stash>,则应用最新的.

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

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

  • 当然,但是如果你想继续在不同的分支中重新应用这个存储,这就像OP所要求的那样,这无济于事.你不得不挑选自己的头脑. (4认同)
  • 由于分支在 git 中相当便宜,这个建议对我来说最有用。 (3认同)

Pat*_*yer 56

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

# save your working copy changes
git diff > some.patch

# re-apply it later
git apply some.patch
Run Code Online (Sandbox Code Playgroud)

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

  • 就是这个!谢谢你。我还更新了我的 .gitignore 以忽略 .patch 文件,我已经准备好拥有尽可能多的补丁。 (6认同)
  • 这是改变游戏规则的人!我已经藏匿了。 (4认同)
  • 我可以看到问题背后的意图,即每次从 master 取出分支而不提交它们时都应用一些本地更改。因此,也许问题应该得到纠正,并且这个答案应该被接受为解决方案。也很简单。 (4认同)
  • 隐藏的好替代品 (2认同)
  • 我不相信这会产生新文件。 (2认同)

Cam*_*zie 48

所以,我不知道为什么在这个话题上有这么多惊慌失措。我可以使用 a和 deprecated来命名 agit stash,我可以使用正则表达式将其拉回:pushsaveapply

Git stash 方法使用名称来申请

$ git stash push -m "john-hancock"

$ git stash apply stash^{/john-hancock}
Run Code Online (Sandbox Code Playgroud)

正如之前提到的,该save命令已被弃用,但它仍然有效,因此您可以在无法通过push调用更新它们的旧系统上使用它。与push命令不同,-m开关不需要与save.

// save is deprecated but still functional  
$ git stash save john-hancock
Run Code Online (Sandbox Code Playgroud)

这是 Git 2.2 和 Windows 10。

视觉证明

这是一个演示该过程的精美动画 GIF。

使用可识别名称显示 git stash apply 的动画 GIF。

事件顺序

GIF 运行很快,但如果你看,过程是这样的:

  1. ls命令显示目录中的4个文件
  2. touch example.html 添加第 5 个文件
  3. git stash push -m "john-hancock" -a-a包括未跟踪的文件)
  4. ls命令在 stash 后显示 4 个文件,这意味着 stash 和隐式硬重置工作
  5. git stash apply stash^{/john-hancock}
  6. ls命令列出了 5 个文件,显示example.html文件被带回,这意味着该git stash apply命令有效。

这甚至有意义吗?

坦率地说,我不确定这种方法的好处是什么。给藏匿处命名是有价值的,但不是检索。也许编写搁置和取消搁置过程的脚本会有所帮助,但按名称弹出存储仍然更容易。

$ git stash pop 3
$ git stash apply 3
Run Code Online (Sandbox Code Playgroud)

对我来说,这看起来比正则表达式容易得多。

  • 给出最好、最全面的答案。 (4认同)
  • 您的答案是(更全面)[这个](/sf/answers/3921381551/)的重复,它本身就是对现已删除的最初接受答案的重述。(看评论) (2认同)
  • 如果我发布了不正确的内容,我会感到尴尬。我看不到已删除的最初接受的答案,可能是因为它已被删除。最大的问题是我可以让它一致地工作,正如你可以通过动画 GIF 看到的那样。我会回到绘图板,看看我是否能弄清楚为什么它不应该起作用。 (2认同)

Lil*_*ard 42

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


小智 28

保存带有名称的 git stash

$ git stash push -m "say-my-name"
Run Code Online (Sandbox Code Playgroud)

按名称执行 git stash apply

$ git stash apply stash^{/say-my-name}
Run Code Online (Sandbox Code Playgroud)


iWh*_*Buy 23

我的.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)
}
Run Code Online (Sandbox Code Playgroud)

以这种方式使用它们:

gitstash nice

gitstashapply nice
Run Code Online (Sandbox Code Playgroud)

  • @SamHasler 只是一些随机的唯一字符串。如果您想知道存储是使用常规 git stash 或使用这些函数创建的 (3认同)
  • 这个答案应该置顶!!!这是最好的答案!! (3认同)
  • 我会执行`grep -m 1 "zsh_stash_name_$1"`,这样如果多次使用相同的名称,它会返回第一个结果:/sf/answers/350923891/ (2认同)

can*_*bax 15

use git stash push -m aNameForYourStash to save it. Then use git stash list to learn the index of the stash that you want to apply. Then use git stash pop --index 0 to pop the stash and apply it.

note: I'm using git version 2.21.0.windows.1


Saf*_*fry 12

可以使用以下命令对存储进行自定义注释

PS D:\git-example> git stash -m "your comment"
Run Code Online (Sandbox Code Playgroud)

列出藏匿处

PS D:\git-exapmle> git stash list

stash@{0}: On master: first stash
stash@{1}: On master: second stash
Run Code Online (Sandbox Code Playgroud)

我们可以选择任何存储,我们必须传递 stash@{x},下面我选择第二个存储,即 1。

PS D:\git-example> git stash pop 1
Run Code Online (Sandbox Code Playgroud)


Vla*_*čík 8

别号

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

用法

git sapply "<regex>"

  • 兼容Git for Windows

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

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


Zac*_*ris 8

不幸的是,git stash apply stash^{/<regex>}它不起作用(它实际上并不搜索存储列表,请参阅接受的答案下的评论).

以下是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)
Run Code Online (Sandbox Code Playgroud)
# ~/.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")
Run Code Online (Sandbox Code Playgroud)

请注意,返回正确的结果代码,以便您可以在其他脚本中使用这些命令.这可以在运行命令后验证:

echo $?
Run Code Online (Sandbox Code Playgroud)

请注意变量扩展漏洞,因为我不确定该--grep=$1部分.应该是,--grep="$1"但我不确定这是否会干扰正则表达式分隔符(我愿意接受建议).


Ada*_*amB 7

那这个呢?

git stash save stashname
git stash apply stash^{/stashname}
Run Code Online (Sandbox Code Playgroud)

  • 它[听起来像](/sf/answers/3624297071/)类似_曾经是_接受的答案,但后来已被删除。 (2认同)

Nat*_*ael 6

这个答案很大程度上归功于KlemenSlavič.我会对已接受的答案发表评论,但我还没有足够的代表:(

您还可以添加一个git别名来查找存储引用,并将其用于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"
Run Code Online (Sandbox Code Playgroud)

请注意,ref=$( ... ); echo ${ref:-<no_match>};模式的原因是没有返回空白字符串,这将导致sshow,sapply和sdrop定位最新的存储而不是像人们预期的那样失败.


Roh*_*wiz 5

别名 对于类 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}"' -
Run Code Online (Sandbox Code Playgroud)

用法:应用正则表达式

示例:git sshow MySecretStash

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


Ale*_*shi 5

这是我的社区别名:wipwip-apply。当您git wip还存储未跟踪的文件并返回到之前的提交状态时。

git config --global alias.wip '!f() { git stash save $1 -u ; }; f'       

git config --global alias.wip-apply '!f() { temp=$(git stash list | cut -d ':' -f 3 | grep -n -w $1 | cut -d ':' -f 1) ; stashnum=$((temp-1)) ; stashname=$(echo stash@{$stashnum}) ; git stash apply $stashname ; }; f'
Run Code Online (Sandbox Code Playgroud)

用法:

git wip "featureA"
git wip-apply "featureA"
Run Code Online (Sandbox Code Playgroud)