我的工作流程的一部分涉及做很多这样的事情:
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
只是在我之前实际存在的东西之前运行.有没有办法做到这一点?
正如XavierÁlvarez 所说,codeWizard写道,git stash
完全避免这里可能更明智.例如,我会考虑使用单独的git fetch
和git 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/branch
refs/tags/tag
origin/master
refs/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
1该git pull
命令基本上是一个简写,git fetch
后面跟着git merge
,或者,如果你告诉它,运行git fetch
后跟通常更合适的命令git rebase
.但是,如果将其分解为两个单独的步骤,则可以获得更多控制权,以及在合并或重新定位之前检查传入更改的能力.
2您可以使用较新的有效的强制藏匿创作create
和store
子命令:创建一个存储,然后存储所产生的SHA-1,你已经被迫即使没有什么藏匿藏匿保存.但并不是每个人都对最新的git有所了解,所以对于脚本来说,依旧的方式可能更明智(或者如前所述,根本不使用藏匿,特别是因为它有各种各样的小但烦人的bug,各种版本git).
3拼出全名是明智的,因为它git rev-parse stash
会先找一个名为的分支stash
.在编写别名或脚本时,所有引用都是正确的:拼写全名(并--
根据需要使用语法)以确保git不会在奇怪的角落情况下执行它认为您的意思.