我该如何保存/应用一个有名字的git储藏(stash)? 我不想在 git stash list
中查找它的索引号。我尝试了 git stash save "my_stash_name"
,但这只会更改储藏的描述,对应的 git apply "my_stash_name"
是无效的。
git add
、git diff
、git rm
和git reset
结合成一个自定义的git命令,我们可以快速将更改聚合成一个补丁文件,稍后可以通过名称轻松引用它。
以下是上述自定义git命令(也可在gist中获得)中使用的命令 - 请注意使用--hard
标志的情况,它将重置您当前的分支并删除本地文件的所有更改:#!/usr/bin/env bash
if [ $# -eq 1 ] ; then
NAME=$1
else
echo "Please pass exactly one argument, which is the name of the patch file"
exit 1
fi
git add .
# if previous patch file with the same name exists untrack it
if [ -f "$NAME.patch" ] ; then
git rm --cached $NAME.patch
fi
# warning: this will diff all changes into a file called NAME.patch and do a hard reset of the current branch
git diff --staged > $NAME.patch
git reset --hard $HEAD
git bottle hello
来创建一个hello.patch
文件,然后使用git apply hello.patch
来应用它。诀窍是首先跟踪所有文件,以便我们可以利用diff命令的暂存选项。通过一些调整,您可以扩展自定义命令,将补丁文件输出到工作目录之外的某个地方,例如硬盘上的某个补丁文件夹,或者您可以更新.gitignore
文件来忽略它。值得一提的是:这个答案启发了我自己的答案,其中描述了补丁方法,但忽略了新文件中的更改将被排除在diff显示之外的问题。注意:由于该命令依赖于git add
,因此它将无法捕捉git已经忽略的任何文件的更改。git rm
安全地取消跟踪和删除该文件。现在已添加此内容,以确保我们不会意外跟踪和暂存补丁文件,然后立即使用硬重置命令将其删除。 - GrayedFox在我的Fish Shell中
function gsap
git stash list | grep ": $argv" | tr -dc '0-9' | xargs git stash apply
end
use
gsap name_of_stash
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
}
zstyle ':completion:*' completer _expand_alias _complete _ignored
alias gs="git stash push -u -m "
alias gsp='git stash pop'
我认为没有办法按名称git pop一个stash。
我创建了一个bash函数来完成这个任务。
#!/bin/bash
function gstashpop {
IFS="
"
[ -z "$1" ] && { echo "provide a stash name"; return; }
index=$(git stash list | grep -e ': '"$1"'$' | cut -f1 -d:)
[ "" == "$index" ] && { echo "stash name $1 not found"; return; }
git stash apply "$index"
}
使用示例:
[~/code/site] on master*
$ git stash push -m"here the stash name"
Saved working directory and index state On master: here the stash name
[~/code/site] on master
$ git stash list
stash@{0}: On master: here the stash name
[~/code/site] on master
$ gstashpop "here the stash name"
希望它有帮助!
我怀疑如果您使用太多的stash(比如超过三个),那么您可能做错了些什么:
通常,Stash是用于工作中断而不是实现功能(您可以使用功能分支来实现)。
假设您正在开发某个功能A,然后发现必须修复一些问题B才能实现该功能A。您可能会这样做:
git add --interactive
来 patch
部分功能A,并忽略解决问题B的更改。git commit
交互式选择到当前分支。git stash
git stash pop
解决问题B的更改并进行提交。如果stash需要手动合并,则可能需要git stash drop
。这是我快速设置的一个例子,对我有效,希望对你也有用:
假设我在我的 package.json 项目文件中有一个自定义/本地脚本,我不想推送到远程仓库。
{
// ... package.json stuff
"scripts": {
"custom": "ts-node a_ts_test_file.ts"
}
}
所以我决定在想要推送我的分支或类似情况时将此更改存储,并弹出存储,直到下一次“git push”。
所以...
# dev is the "stash tag"
# To stash current working directory
git config --global alias.sh "stash -m 'dev'"
~.bashrz
或~.zshrc
文件,并添加以下别名:# Apply stash "tagged" $(X) where X is substring of "git stash list" output filtered by output that contains "dev".
# I didn't use git stash apply because "dev" tag isn't unique, so it's a need to pop the stash and ensure to create a new one alias set on first step
alias gitsh="git stash pop $(git stash list | grep 'dev' | cut -d ':' -f 1) || echo 'nope'"
将您的工作目录推送到标记为“dev”的标签:git sh
从标记为“dev”的存储中拉取已存储的更改:sitsh
(这是我在五分钟内制作的一个小脚本,适用于我,如果失败了...请修复它!)
git stash push -m stashname
是当前语法。git stash save stashname
已被弃用。 - SherylHohmangit bottle name
,然后稍后使用git apply name.patch
,如果您想要更详细的解释和使用示例,请参见我的答案。 - GrayedFox