私はあなたがgit stash save stashname
をすることによって隠し場所に名前を付けることができるという印象の下に常にありました、あなたは後でgit stash apply stashname
をすることによってそれを適用することができました。しかし、この場合に起こるのはstashname
が隠し記述として使われるということだけです。
実際に隠し場所を指定する方法はありませんか?そうでない場合は、同等の機能を実現するために何を推奨しますか?基本的に私は定期的に適用したい小さな隠し場所がありますが、実際の隠し場所番号が何であるかを常にgit stash list
で捜し出す必要はありません。
これがあなたのやり方です:
git stash save "my_stash"
"my_stash"は隠し場所の名前です。
知っておくと便利なことがいくつかあります:すべての隠し場所はスタックに格納されています。
git stash list
これはあなたのすべての隠し場所をリストします。
隠し場所を適用して隠し場所のスタックから削除するには、
git stash pop stash@{n}
隠し場所を適用して隠し場所のスタックに保存するには、次のように入力します。
git stash apply stash@{n}
隠されたインデックスのインデックス内のnが変化します。
git stash save
は 非推奨 2.15.x/2.16以降で、代わりにgit stash Push -m "message"
を使用できます
あなたはこのように訴えることができます:
git stash Push -m "message"
"message"はあなたの隠し場所の名前です。
あなたがそれが十分に重要であると感じるならば、隠し場所を枝に変えることができます:
git stash branch <branchname> [<stash>]
manページから:
これは、<stash>が最初に作成されたときのコミットから始まる<branchname>という名前の新しいブランチを作成してチェックアウトし、<stash>に記録された変更を新しい作業ツリーとインデックスに適用します。正常に完了しました。 <stash>が指定されていない場合は、最新のものが適用されます。
これは、git stash saveを実行したブランチが、衝突のためにgit stash applyが失敗するほど十分に変更されている場合に役立ちます。 git stashが実行された時点では、スタッシュはHEADであったコミットの上に適用されるため、元のスタッシュ状態に矛盾なく復元されます。
あなたは後でこの新しいブランチをあなたが隠したときの場所の子孫である他の場所にリベースすることができます。
刺し傷はあなたが望むような恒久的なものであることを意味していません。おそらくコミットのタグを使ったほうがよいでしょう。隠したいものを作ります。それをコミットしてください。そのコミット用のタグを作成します。それからブランチをHEAD^
にロールバックします。その隠し場所を再度適用したいときは、git cherry-pick -n tagname
を使用できます(-n
は--no-commit
)。
現在の作業コピーの変更の一部または全部を保存して後で自由に再適用するための軽量な方法を探しているだけの場合は、パッチファイルを検討してください。
# save your working copy changes
git diff > some.patch
# re-apply it later
git apply some.patch
時々、私はこれのために隠し場所を使うべきであるかどうかと私は上記の狂気のようなものを見ますそして私は私がしていることに満足しています:)
私は.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)
}
このようにそれらを使う:
gitstash Nice
gitstashapply Nice
sapply = "!f() { git stash apply \"$(git stash list | awk -F: --posix -vpat=\"$*\" \"$ 0 ~ pat {print $ 1; exit}\")\"; }; f"
git sapply "<regex>"
編集:私は私の最初の解決策に固執したが、大多数がEtan Reisnerのバージョン(上記)を好む理由を私は知っている。だからレコードのためだけに:
sapply = "!f() { git stash apply \"$(git stash list | grep -E \"$*\" | awk \"{ print $ 1; }\" | sed -n \"s/://;1p\")\"; }; f"
git stash apply stash^{/<regex>}
が機能しないのは残念です(実際にはstashリストを検索しません。 受け入れられた答え の下のコメントを見てください)。
これは、最初の(最新の)git stash list
を見つけるためにregexによって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)
# ~/.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")
他のスクリプト内でこれらのコマンドを使用できるように、正しい結果コードが返されることに注意してください。これは、次のようにコマンドを実行した後に確認できます。
echo $?
変数展開の悪用に注意してください--grep=$1
の部分についてはよく分からなかったので。それはおそらく--grep="$1"
であるべきですが、それが正規表現の区切り文字に干渉するかどうかはわかりません(私は提案を受け付けています)。
この答えは、KlemenSlavičに多くの責任があります。私はちょうど受け入れられた答えについてコメントしたであろうが私はまだ十分な担当者を持っていない:(
また、gitエイリアスを追加してstash refを見つけ、それを他のエイリアスで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"
ref=$( ... ); echo ${ref:-<no_match>};
パターンの理由は空白文字列が返されないため、sshow、sapply、sdropは最新のstashをターゲットにするのではなく、失敗することを想定しています。
Alias これは、Unixライクなシステムでは、関数にカプセル化する必要のない、より直接的な構文です。
sshow = !sh -c 'git stash show stash^{/$*} -p' -
sapply = !sh -c 'git stash apply stash^{/$*}' -
ssave = !sh -c 'git stash save "${1}"' -
使用法: sapply regex
例: git sshow MySecretStash
末尾のハイフンは、標準入力から入力を受け取ると言います。
隠し場所の番号を調べるには、小さなbashスクリプトを使用します。それを「gitapply」と呼びます。
NAME="$1"
if [[ -z "$NAME" ]]; then echo "usage: gitapply [name]"; exit; fi
git stash apply $(git stash list | grep "$NAME" | cut -d: -f1)
使用法:
gitapply foo
... fooはあなたが欲しい隠し場所の名前の部分文字列です。
Stashの作成以外にも、依存関係として fzf を導入することで別の解決策を提案します。生産性が大幅に向上するため、5分かけて紹介することをお勧めします。
とにかく、 examplesページ オファリングstash検索からの関連抜粋です。 sciptletを変更して追加機能(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
}
これは、PowerShellを使用してこれを実現するための1つの方法です。
<#
.SYNOPSIS
Restores (applies) a previously saved stash based on full or partial stash name.
.DESCRIPTION
Restores (applies) a previously saved stash based on full or partial stash name and then optionally drops the stash. Can be used regardless of whether "git stash save" was done or just "git stash". If no stash matches a message is given. If multiple stashes match a message is given along with matching stash info.
.PARAMETER message
A full or partial stash message name (see right side output of "git stash list"). Can also be "@stash{N}" where N is 0 based stash index.
.PARAMETER drop
If -drop is specified, the matching stash is dropped after being applied.
.EXAMPLE
Restore-Stash "Readme change"
Apply-Stash MyStashName
Apply-Stash MyStashName -drop
Apply-Stash "stash@{0}"
#>
function Restore-Stash {
[CmdletBinding()]
[Alias("Apply-Stash")]
PARAM (
[Parameter(Mandatory=$true)] $message,
[switch]$drop
)
$stashId = $null
if ($message -match "stash@{") {
$stashId = $message
}
if (!$stashId) {
$matches = git stash list | Where-Object { $_ -match $message }
if (!$matches) {
Write-Warning "No stashes found with message matching '$message' - check git stash list"
return
}
if ($matches.Count -gt 1) {
Write-Warning "Found $($matches.Count) matches for '$message'. Refine message or pass 'stash{@N}' to this function or git stash apply"
return $matches
}
$parts = $matches -split ':'
$stashId = $parts[0]
}
git stash apply ''$stashId''
if ($drop) {
git stash drop ''$stashId''
}
}
保存するにはgit stash save NAME
を使用してください。
そして、...このスクリプトを使ってどちらを適用する(またはポップする)かを選択できます。
#!/usr/bin/env Ruby
#git-stash-pick by Dan Rosenstark
# can take a command, default is apply
command = ARGV[0]
command = "apply" if !command
ARGV.clear
stashes = []
stashNames = []
`git stash list`.split("\n").each_with_index { |line, index|
lineSplit = line.split(": ");
puts "#{index+1}. #{lineSplit[2]}"
stashes[index] = lineSplit[0]
stashNames[index] = lineSplit[2]
}
print "Choose Stash or ENTER to exit: "
input = gets.chomp
if input.to_i.to_s == input
realIndex = input.to_i - 1
puts "\n\nDoing #{command} to #{stashNames[realIndex]}\n\n"
puts `git stash #{command} #{stashes[realIndex]}`
end
私は隠し場所の名前を見て選ぶことができるのが好きです。また私はZshellを使っていて、率直に言って上記のいくつかのBashエイリアスの使い方を知らなかった。
注意:Kevinが言っているように、 代わりにタグとチェリーピックを使うべきです。
これはどうですか?
git stash save stashname
git stash apply stash^{/stashname}
私の魚の殻に
function gsap
git stash list | grep ": $argv" | tr -dc '0-9' | xargs git stash apply
end
つかいます
gsap name_of_stash
ここでパーティーに遅れますが、VSCodeを使用する場合、コマンドパレット(CTRL/CMD + SHIFT + P)を開いて「Pop Stash」と入力すると簡単にできます。 git CLIを使用せずに
git stash apply
は、stash@{0}
以外の他の参照とも連携します。ですから、通常の tags を使って永続的な名前をつけることができます。これには、誤ってgit stash drop
またはgit stash pop
itすることができないという利点もあります。
そのため、エイリアスpstash
(別名 "persistent stash")を次のように定義できます。
git config --global alias.pstash '!f(){ git stash && git tag "$1" stash && git stash drop; }; f'
これで、タグ付き隠し場所を作成できます。
git pstash x-important-stuff
そしてshow
とapply
はいつものように再びそれを行います。
git stash show x-important-stuff
git stash apply x-important-stuff