有没有办法重新订购Git stashes?

时间:2017-05-23 18:35:19

标签: git git-stash

在Git中,可以制作多个藏匿处:

git stash save "quick temp stash"
git stash save "another quick temp stash"
git stash save "This is important but I need to put it on the back burner"
git stash save "This is almost certainly garbage, but just in case ..."

现在,我知道我可以按任何顺序取回这些藏匿处:

git stash pop stash@{3} # recover quick temp stash
git stash pop stash@{2} # recover another quick temp stash

但显然更方便的语法更可取:

git stash pop

这不仅仅是因为打字的次数较少,而且因为需要的思维较少:如果我有几个藏匿处,我必须仔细查看它们,也许git stash show一对,直到找到我想要的那个。但是,如果我只是将最近的“临时”藏匿在最顶层(接着是下一个临时藏匿等),我根本不需要思考;我只是pop

所以,我的问题是,有什么方法可以重新订购我的藏匿处,以便我可以考虑在我保存它们时应该“弹出”它们,而不是在我“流行”的时候他们。这将允许我仍然保存“这几乎肯定是垃圾,但以防万一......”和“这很重要,但我需要把它放在后面烧”,但是在藏匿列表的后面,他们不要复杂访问更简单的快速存储。

2 个答案:

答案 0 :(得分:3)

没有开箱即用 - 我认为藏匿不是真正意义上的工作流程。

也就是说,如果你切换到临时提交,你可以按照你认为合适的方式重新排序这些提交并cherry-pick提交(例如git cherry-pick $tempbranch替代git stash pop)。

如果你真的想继续使用stashes并重新排序,你可以在工作时调整refs/stash(通过一些脚本)。来自git-stash documentation

  

您创建的最新存储存储在refs/stash;在此引用的reflog中可以找到旧的stashes,并且可以使用通常的reflog语法命名(例如stash@{0}是最近创建的存储,stash@{1}是之前的存储,stash@{2.hours.ago}是也有可能)。也可以通过仅指定存储索引来引用Stashes(例如,整数n等同于stash@{n})。

如果您决定为工作流程编写脚本,则还可以使用git stash creategit stash store

  

创建

     

创建一个存储(它是一个常规提交对象)并返回其对象名,而不将其存储在ref命名空间中的任何位置。这对脚本非常有用。它可能不是你想要使用的命令;见上面的“保存”。

     

商品

     

在stash ref中存储通过 git stash create (这是一个悬空的合并提交)创建的给定存储,更新存储reflog。这对脚本非常有用。它可能不是你想要使用的命令;见上面的“保存”。

答案 1 :(得分:3)

Whymarrh's answerDonnie's comment一样,我认为你提交时可能会更好。不过,我会注意到:

  

如果您真的想继续使用藏匿并重新排序,可以在工作时调整refs/stash ...

可以在不使用git stash pop的情况下执行此操作。这很棘手。 (编辑:我在重新阅读时看到这是Whymarrh的答案中的想法。)

reflog 文件.git/logs/refs/stash包含reflog条目1到 N (但存在许多条件)。 stash引用本身保留条目零。

drop操作包括删除特定的reflog条目(git reflog delete知道如何处理特殊的零情况):

drop_stash () {
        assert_stash_ref "$@"

        git reflog delete --updateref --rewrite "${REV}" &&
                say "$(eval_gettext "Dropped \${REV} (\$s)")" ||
                die "$(eval_gettext "\${REV}: Could not drop stash entry")"

        # clear_stash if we just dropped the last stash entry
        git rev-parse --verify --quiet "$ref_stash@{0}" >/dev/null ||
        clear_stash
}

clear_stash删除refs/stash本身)。 $REV参数为refs/stash@{N},如果您未指定特定参数,则为refs/stash

store操作使用git update-ref

将条目插入零
[snip]
        w_commit="$1"
        if test -z "$stash_msg"
        then
                stash_msg="Created via \"git stash store\"."
        fi

        git update-ref --create-reflog -m "$stash_msg" $ref_stash $w_commit
        ret=$?
        test $ret != 0 && test -z "$quiet" &&
        die "$(eval_gettext "Cannot update \$ref_stash with \$w_commit")"
        return $ret

因此,实现“滚动”操作(如果您熟悉Forth或Postscript)是可能的,尽管有点棘手。要将最后三个条目向上滚动一步,例如,更改:

E  stash@{4}
D  stash@{3}
C  stash@{2}
B  stash@{1}
A  stash@{0}

成:

E  stash@{4}
D  stash@{3}
B  stash@{2}
A  stash@{1}
C  stash@{0}

您只需将C复制到底部,就像通过新的store一样,然后删除stash@{3}(由于插入为零而向上移动)。

事实上,您可以通过使用适当的参数运行git stash -q storegit stash -q drop来执行此操作。