当前位置:  开发笔记 > 编程语言 > 正文

Git stash只有在成功隐藏之前才会弹出

如何解决《Gitstash只有在成功隐藏之前才会弹出》经验,为你挑选了1个好方法。

我的工作流程的一部分涉及做很多这样的事情:

git stash的变化

git pull

流行隐藏的变化

启动mergetool以解决冲突

我正在尝试编写一个脚本来同时执行所有这些操作,所以我可以从终端调用它.

#!/bin/bash

# First stash our local changes
git stash

# Then git pull to update our repo
git pull

# Pop the stash
git stash pop

# Launch mergetool if necessary
git mergetool

我遇到的问题是,如果我意外地运行,并且没有对藏匿的更改,则git stash pop应用一些(通常超级旧的)存储.我想要做的git stash pop只是在我之前实际存在的东西之前运行.有没有办法做到这一点?



1> torek..:

正如XavierÁlvarez 所说,codeWizard写道,git stash完全避免这里可能更明智.例如,我会考虑使用单独的git fetchgit rebase步骤(参见Xavier的答案),并注意到rebase现在--autostash基本上只是你想要的东西,它只是不能通过git pull便利脚本直接获得.1

这就是说,有一种方法可以做到你问什么.这有点棘手.如果git stash save有一个类似的"强制"选项会更容易git commit --allow-empty,但它没有这样的选择.2 相反,你可以做的是检测是否git stash save推了一个新的藏匿处.如果git stash save退出状态指示是否推送存储,这也会更容易,但同样不会.这意味着我们必须完全依赖不同的技巧.我们从两个事实开始:git rev-parse从"引用"中查找SHA-1,并git stash使用一个特定的引用.

git rev-parse命令会将任何引用转换为SHA-1:

$ git rev-parse refs/remotes/origin/master
2635c2b8bfc9aec07b7f023d8e3b3d02df715344

引用只是一个名称,通常以refs命名某些SHA-1 ID开头.最常见的是分支:.你可能也使用过标签:,你可能已经使用了远程跟踪分支,比如全名的缩写.refs/heads/branchrefs/tags/tagorigin/masterrefs/remotes/origin/master

stash脚本使用refs/stash,所以我们可以简单地运行git rev-parse refs/stash.3 我们希望之前运行它git stash save,然后再运行它git stash save.如果输出发生更改,则该git stash save步骤必须将新存储推送到存储堆栈.

我们必须要小心一点,因为如果存储堆栈是空的(因为最后一个存储被先前弹出或删除,或者还没有创建过存储器),git rev-parse则会给出错误消息并且不生成SHA-1:

$ git rev-parse refs/stash
fatal: ambiguous argument 'refs/stash': unknown revision or path not in
the working tree.
Use '--' to separate paths from revisions, like this:
'git  [...] -- [...]'

因此我们实际上需要git rev-parse -q --verify refs/stash,如果引用不存在则默默地产生任何内容,然后我们只需要在任何使用结果的shell脚本中小心一点:

oldsha=$(git rev-parse -q --verify refs/stash)
git stash -q save  # add options as desired here
newsha=$(git rev-parse -q --verify refs/stash)
if [ "$oldsha" = "$newsha" ]; then
    made_stash_entry=false
else
    made_stash_entry=true
fi
... all of your other code goes here ...
if $made_stash_entry; then git stash pop; fi

1git pull命令基本上是一个简写,git fetch后面跟着git merge,或者,如果你告诉它,运行git fetch后跟通常更合适的命令git rebase.但是,如果将其分解为两个单独的步骤,则可以获得更多控制权,以及在合并或重新定位之前检查传入更改的能力.

2您可以使用较新的有效的强制藏匿创作createstore子命令:创建一个存储,然后存储所产生的SHA-1,你已经被迫即使没有什么藏匿藏匿保存.但并不是每个人都对最新的git有所了解,所以对于脚本来说,依旧的方式可能更明智(或者如前所述,根本不使用藏匿,特别是因为它有各种各样的小但烦人的bug,各种版本git).

3拼出全名是明智的,因为它git rev-parse stash会先找一个名为的分支stash.在编写别名或脚本时,所有引用都是正确的:拼写全名(并--根据需要使用语法)以确保git不会在奇怪的角落情况下执行它认为您的意思.

推荐阅读
罗文彬2502852027
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有