web-dev-qa-db-ja.com

Gitで名前で隠し場所に名前を付けて取得するにはどうすればいいですか?

私はあなたがgit stash save stashnameをすることによって隠し場所に名前を付けることができるという印象の下に常にありました、あなたは後でgit stash apply stashnameをすることによってそれを適用することができました。しかし、この場合に起こるのはstashnameが隠し記述として使われるということだけです。

実際に隠し場所を指定する方法はありませんか?そうでない場合は、同等の機能を実現するために何を推奨しますか?基本的に私は定期的に適用したい小さな隠し場所がありますが、実際の隠し場所番号が何であるかを常にgit stash listで捜し出す必要はありません。

1131
Suan

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

git stash save "my_stash"

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

知っておくと便利なことがいくつかあります:すべての隠し場所はスタックに格納されています。

git stash list

これはあなたのすべての隠し場所をリストします。

隠し場所を適用して隠し場所のスタックから削除するには、

git stash pop stash@{n}

隠し場所を適用して隠し場所のスタックに保存するには、次のように入力します。

git stash apply stash@{n}

隠されたインデックスのインデックス内のnが変化します。

430

git stash save 非推奨 2.15.x/2.16以降で、代わりにgit stash Push -m "message"を使用できます 

あなたはこのように訴えることができます:

git stash Push -m "message" 

"message"はあなたの隠し場所の名前です。

89
EssaidiM

あなたがそれが十分に重要であると感じるならば、隠し場所を枝に変えることができます:

git stash branch <branchname> [<stash>]

manページから:

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

これは、git stash saveを実行したブランチが、衝突のためにgit stash applyが失敗するほど十分に変更されている場合に役立ちます。 git stashが実行された時点では、スタッシュはHEADであったコミットの上に適用されるため、元のスタッシュ状態に矛盾なく復元されます。

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

76
Adam Dymitruk

刺し傷はあなたが望むような恒久的なものであることを意味していません。おそらくコミットのタグを使ったほうがよいでしょう。隠したいものを作ります。それをコミットしてください。そのコミット用のタグを作成します。それからブランチをHEAD^にロールバックします。その隠し場所を再度適用したいときは、git cherry-pick -n tagnameを使用できます(-n--no-commit)。

35
Lily Ballard

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

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

# re-apply it later
git apply some.patch

時々、私はこれのために隠し場所を使うべきであるかどうかと私は上記の狂気のようなものを見ますそして私は私がしていることに満足しています:) 

29
Pat Niemeyer

私は.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
12
iWheelBuy

エイリアス

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"

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"であるべきですが、それが正規表現の区切り文字に干渉するかどうかはわかりません(私は提案を受け付けています)。

6
Zack Morris

この答えは、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をターゲットにするのではなく、失敗することを想定しています。

5
Nathanael

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

末尾のハイフンは、標準入力から入力を受け取ると言います。

3
Rohanthewiz

隠し場所の番号を調べるには、小さな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
Will Sheppard

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
}
1
laur

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

詳細はこちら

1
Geoffrey Hudik

保存するには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が言っているように、 代わりにタグとチェリーピックを使うべきです。

1
Dan Rosenstark

これはどうですか?

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

私の魚の殻に

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

つかいます

gsap name_of_stash

0

ここでパーティーに遅れますが、VSCodeを使用する場合、コマンドパレット(CTRL/CMD + SHIFT + P)を開いて「Pop Stash」と入力すると簡単にできます。 git CLIを使用せずに

0
Alexandre Gomes

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

そしてshowapplyはいつものように再びそれを行います。

git stash show x-important-stuff
git stash apply x-important-stuff
0
A.H.