gitでスタッシュに名前を付けて名前で取得する方法は?


1421

あなたはスタッシュに名前git stash save stashnameを付けることができ、後でそれを適用することができるという印象を常に持っていましたgit stash apply stashname。しかし、この場合、発生するのはstashname、隠し場所の説明として使用されることだけです。

実際に隠し場所に名前を付ける方法はありませんか?そうでない場合、同等の機能を実現するために何をお勧めしますか?基本的に、私は定期的に適用したい小さな隠し場所を持っていますがgit stash list、実際の隠し場所の番号を常に探さなければならないわけではありません。


68
git stash push -m stashname現在の構文です。 git stash save stashname廃止されました。
SherylHohman

1
git stash push -m stashnameが2.8.0.windows.1で機能しません。
Jac

Git for Windows 2.26.0は数日前にリリースされました。多分それは今修正されています。github.com/git-for-windows/git/releases/tag/v2.26.0.windows.1
tom_mai78101

回答:


817

これがあなたのやり方です:

git stash save "my_stash"

"my_stash"隠し場所の名前はどこですか。

知っておくと便利なこと:すべてのスタッシュはスタックに格納されます。タイプ:

git stash list

これにより、すべての隠し場所が一覧表示されます。

stashを適用してstashスタックから削除するには、次のように入力します。

git stash pop stash@{n}

stashを適用してstashスタックに保持するには、次のように入力します。

git stash apply stash@{n}

n隠された変更のインデックスはどこにありますか。


88
これは質問の答えにはなりません。デフォルトでは、スタッシュの番号がたくさんなりますが、簡単に識別できるように名前を付ける方法には対応していません。
GoodSp33d 2014

16
OPは、カスタム名のぎこちない名前のstash @ {n}名を明示的に回避しようとしています。git stash apply <custom-name>
stewSquared 2017年

10
名前で隠し場所を取得することについての質問には答えません。
nullsteph 2017

47
git stash push -m my_stash現在の構文です。 git stash save my_stash廃止されました。
SherylHohman

21
それは無関係ではありません。それは便利です。
Gayan Weerakutti、2018年

444

git stash saveされる非推奨 2.15.x / 2.16のように、代わりにあなたが使用することができますgit stash push -m "message"

次のように使用できます。

git stash push -m "message"

ここで、「メッセージ」はその隠し場所に対するメモです。

隠し場所を取得するには、次を使用できますgit stash list。たとえば、次のようなリストが出力されます。

stash@{0}: On develop: perf-spike
stash@{1}: On develop: node v10

次に、単にそれをapply与えることを使用しますstash@{index}

git stash apply stash@{1}

リファレンス git stashのmanページ


9
構文でpushはなくドキュメントを示すドキュメントsavegit stash push
SherylHohman '25

30
これが本当の答えです。残念ながら、その上には古い答えがたくさんあります。
マラン

1
新しいものの詳細git stash pushstackoverflow.com/a/47231547/6309
VonC '28

廃止通知について(最新の現在のドキュメントの)ソース:git-scm.com/docs/git-stash/2.24.0#Documentation/...
ガブリエルDevillers

1
FWIW:Powershellで実行git stash apply stash@{1}しているときは、error: unknown switch 'e'戻ってきます。代わりにgit stash apply --index 1or git stash apply 'stash@{1}'またはescape }を使用{し、バックティック `を付けます。
LosManos

104

あなたがそれが十分に重要だと思うなら、あなたはスタッシュをブランチに変えることができます:

git stash branch <branchname> [<stash>]

manページから:

これは<branchname><stash>が最初に作成されたコミットから始まるという名前の新しいブランチを作成してチェックアウト<stash>し、新しい作業ツリーとインデックスに記録された変更を適用し、それが<stash>正常に完了した場合はをドロップします。指定しない場合<stash>は最新のものを適用します。

これは、実行したブランチgit stash saveが変更され、競合のためにgit stash applyが失敗した場合に便利です。stashはgit stashが実行されたときにHEADだったコミットの上に適用されるため、競合が発生することなく、元のstash状態が復元されます。

後でこの新しいブランチを別の場所にリベースして、隠していた場所の子孫になることができます。


1
gitのブランチはかなり安価なので、この提案は私にとって最も有用です。
Jayan

5
もちろん、これは、OPが要求しているように、後で別のブランチにこのスタッシュを再適用し続けたい場合には役に立ちません。あなたはその頭をチェリーピックする必要があります。
stewSquared 2017年

@AdamDymitruk飛び出さずに隠し場所を維持しながらこれを実行する方法はありますか?(のようにgit stash apply
Kasun Siyambalapitiya

不思議なことに、これを試したところ、チェックアウト時にファイルの1つが上書きされ、変更をコミットまたは隠しておく(!)べきというエラーメッセージが表示されました。git stash push -m 'name'働いた。
ワートワート

@AdamDymmitruk素晴らしい答え。私の心を吹き飛ばしました。
ダン

76

現在の作業コピーの変更の一部またはすべてを保存して、後で自由に再適用するための軽量な方法を探しているだけの場合は、パッチファイルを検討してください。

# save your working copy changes
git diff > some.patch

# re-apply it later
git apply some.patch

時々私はこれにスタッシュを使用する必要があるかどうか疑問に思い、その後、上記の狂気のようなものを見て、私がやっていることに満足しています:)


2
これだよ!ありがとうございました。.patchファイルを無視するように.gitignoreも更新しました。すべてのパッチを必要なだけインストールするように設定しました。
LINGS

私は質問の背後にある意図を見ることができます。つまり、マスターからブランチを取り出すたびにローカルの変更を適用し、それらをコミットしないことです。したがって、おそらく質問は修正され、この回答は解決策として受け入れられるはずでした。シンプルにも。
ANK

46

シュテーはあなたが望むような永久的なものであることを意味していません。おそらく、コミット時にタグを使用するほうがよいでしょう。あなたが隠したいものを構築します。それからコミットします。そのコミットのタグを作成します。次に、ブランチをにロールバックしますHEAD^。ここで、そのスタッシュを再適用したいときに使用できますgit cherry-pick -n tagname-nis --no-commit)。


1
確かにこのアプローチのように、named commitどこかでたむろするだけで少しクリーンに感じます。チェリーピック時にコミットされず、差分に留まるというわずかな不快な点があります。つまり、次のコミット時に手動でチェックインしないようにする必要があります。
Aditya MP

1
これが一番近いです。私はこれのためにいくつかのエイリアスを作成すると思います。説明を「名前」として使うのは好きではありません。
stewSquared 2017年

それがインデックスに追加するのは恥であり、リセットする必要があり--no-stageます。誰かがオプションにパッチを当てるべきです!関連:stackoverflow.com/questions/32333383/...
チロSantilli冠状病毒审查六四事件法轮功

41

git stash push -m aNameForYourStashそれを保存するために使用します。次に、を使用git stash listして、適用する隠し場所インデックスを学習します。次に、を使っgit stash pop --index 0て隠し場所をポップし、適用します。

注:私はgitバージョン2.21.0.windows.1を使用しています


1
現在の構文に関するこのコメントを考慮に入れて、あなたの答えは名目上最高の答えになるでしょうgit stash {push,save}
Michael-Where's Clay Shirky

32

私の.zshrcファイルには次の2つの関数があります。

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

「zsh_stash_name_」とは何ですか?
Sam Hasler

1
@SamHaslerはランダムな一意の文字列です。あなたはスタッシュを知りたい場合には、通常のgitスタッシュまたはこれらの機能を使用して作成された
iWheelBuy

エイリアスファンのためのエレガントなソリューション
suarsenegger

22

これはどうですか?

git stash save stashname
git stash apply stash^{/stashname}

1
それはのように聞こえるようなものにするために使用受け入れ答えを、しかし以降に削除されました。
マイケル-1915年

えーと、なぜそれが削除されたのですか?
AdamB

私は答えを投稿していないと万評判を持っていないので、私は、知りませんが、私はそれが仕事をしないと言ったコメントとは何かを持っていると推測:それはその不幸だgit stash apply stash^{/<regex>}仕事をしません(それはありません実際にスタッシュリストを検索します。承認された回答の下のコメントを参照してください)。
マイケル-1915年

これがあなたが探している答えです!
kiedysktos

1
取得するために私は行く1. git stash listことを示してくれ、私はその後、2行くそれらに関連するインデックス番号と一緒にスタッシュgit stash apply 0- 0私は最初のコマンドから見上げていたインデックス番号である
両手用

8

エイリアス

sapply = "!f() { git stash apply \"$(git stash list | awk -F: --posix -vpat=\"$*\" \"$ 0 ~ pat {print $ 1; exit}\")\"; }; f"

使用法

git sapply "<regex>"

  • Git for Windowsとの互換性

編集:私は元の解決策に固執しましたが、大多数がEtan Reisnerのバージョン(上記)を好む理由がわかります。だから、記録のためだけに:

sapply = "!f() { git stash apply \"$(git stash list | grep -E \"$*\" | awk \"{ print $ 1; }\" | sed -n \"s/://;1p\")\"; }; f"

を使用awk -F: '{print $1}'すると、sedの必要性が完全になくなります。また、なぜこれを関数でラップするのですか?また、使用awk -F: -vpat="$*" '$0 ~ pat {print $1}'すると、grepもドロップできるようになります。ただし、パターンには少し異なる見積もりが必要になる場合があります。
Etan Reisner、2013年

@EtanReisner:スニペットは複数の行を出力します。
VlastimilOvčáčík2013年

{print $1; exit}最初に一致した行の後で終了するアクションを作成します。
Etan Reisner、2013年

@EtanReisner:いくつかのテストの後、sedを取り除くことができましたが、ラッパーとgrepは残ります。
VlastimilOvčáčík2013年

あなたがgrepを必要としないのは、私が言ったように、それがなければパターンの引用が異なるかもしれないからです。ラッパーとはシェル関数を意味すると思いますか?あなたはなぜそれが必要だと思うのか説明しなかったので、あなたが実際にそうするかどうかについてコメントすることはできませんが、おそらくあなたはそうしないと思います。(直接git stashの代わりに手動でシェルを呼び出す必要があるかもしれませんが、それもできないかもしれません。)
Etan Reisner '28

8

git stash apply stash^{/<regex>}動作しないのは残念です(実際にはスタッシュリストが検索されません。承認された回答の下のコメントを参照してください)。

以下はgit stash list、正規表現で検索して最初の(最新)を見つけ、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"ですが、それが正規表現の区切り文字に干渉するかどうかはわかりません(私は提案を受け入れます)。


6

この答えは、クレメン・スラビッチのおかげです。私は受け入れられた答えについてコメントしただけですが、まだ十分な担当者がいません:(

gitエイリアスを追加してstash参照を検索し、それを表示、適用、ドロップなどの他のエイリアスで使用することもできます。

[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が期待どおりに失敗するのではなく、最新のスタッシュをターゲットにすることに注意してください。


1
承認された回答が機能していないように見えますが、これは私にとっては機能します(承認された回答に対する私の賞賛を参照してください)
JanRüeggJan

4

エイリアス これは、関数にカプセル化する必要のないUnixライクなシステムのより直接的な構文かもしれません。以下を[alias]の下の〜/ .gitconfigに追加します

sshow = !sh -c 'git stash show stash^{/$*} -p' -
sapply = !sh -c 'git stash apply stash^{/$*}' -
ssave = !sh -c 'git stash save "${1}"' -

使用法:正規表現を適用

例:git sshow MySecretStash

末尾のハイフンは、標準入力から入力を取ることを示しています。


4

小さな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は、必要なスタッシュの名前のサブストリングです。


3

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の代わりに非推奨ですgit stash push
wranvaud

2

これは、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''
    }
}

詳細はこちら


2

私の魚の殻で

function gsap
  git stash list | grep ": $argv" | tr -dc '0-9' | xargs git stash apply
end

使用する

gsap name_of_stash


はい!ありがとうございました!!!
クロザック

1

ここではパーティーに遅れますが、VSCodeを使用している場合は、コマンドパレット(CTRL / CMD + SHIFT + P)を開いて「Pop Stash」と入力すると、名前でスタッシュを取得できます。 git CLIを使用する必要なし


1

git stash apply以外の参照でも動作しstash@{0}ます。したがって、通常のタグを使用して永続的な名前を取得できます。これには、偶然にgit stash dropgit stash popそれもできないという利点もあります。

したがって、次のようにエイリアスpstash(別名「永続的スタッシュ」)を定義できます。

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

0

名前でスタッシュをgit popする方法はないと思います。

それを行う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"

お役に立てば幸いです。


0

stashの作成以外のすべてについて、依存関係としてfzfを導入することで別の解決策を提案します。全体的に生産性が大幅に向上するため、5分の時間をかけて紹介することをお勧めします。

とにかく、彼らからの関連の抜粋例ページはスタッシュ検索を提供しています。スクリプトレットを変更して、追加機能(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
}

0

だから、なぜこのトピックに多くの驚きがあるのか​​はわかりません。プッシュと非推奨の保存の両方でスタッシュに名前を付けることができます。また、正規表現を使用して、適用によってそれを元に戻すことができます。

適用する名前を使用するGit stashメソッド

$ git stash push -m "john-hancock"

$ git stash apply stash^{/john-hancock}

前述したように、saveコマンドは廃止されましたが、引き続き機能するため、push呼び出しで更新できない古いシステムでこれを使用できます。pushコマンドとは異なり、-mスイッチはsaveでは必要ありません。

// save is deprecated but still functional  
$ git stash save john-hancock

ポップアンドドロップの問題

私はそれがポップで機能するとは信じていませんが、それはポップが適用後にド​​ロップを実行し、正規表現がドロップフレンドリーではないためだと思います。それはただの直感です。私はそれをテストしていません。

これはGit 2.2とWindows 10です。

視覚的証拠

これは、プロセスを示す美しいアニメーションGIFです。

識別可能な名前を使用したgit stashの適用を示すアニメーションGIF。

イベントのシーケンス

GIFはすぐに実行されますが、見ればプロセスは次のとおりです。

  1. lsコマンドは、ディレクトリに4つのファイルを表示します
  2. touch example.htmlは5番目のファイルを追加します
  3. git stash push -m "john-hancock" -a(-aには追跡されていないファイルが含まれます)
  4. lsコマンドはstashの後に4つのファイルを表示します。これは、stashと暗黙的なハードリセットが機能したことを意味します
  5. git stash stashを適用^ {/ john-hancock}実行
  6. lsコマンドは5つのファイルをリストし、example.htmlファイルが戻されたことを示します。これは、git stash applyコマンドが機能したことを意味します。

これは理にかなっていますか?

正直なところ、このアプローチの利点は何なのかわかりません。stashに名前を付けることには意味がありますが、検索には意味がありません。プロセスをスクリプト化すると役立つかもしれませんが、名前で隠し場所をポップするだけの方が簡単です。

$ git stash pop 3
$ git stash apply 3

これは正規表現よりもずっと簡単に見えます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.