どうすればgit stashの名前を変更できますか?


202

名前が間違っている隠し場所があります。正確な名前に修正したいと思います。

スタッシュの名前を変更するにはどうすればよいですか?


5
ポップして別の名前でもう一度保存しますか?
Bartlomiej Lewandowski 2014

5
stashは古い状態に基づいており、pop時に競合が発生する可能性があるため、再度popしてstashすることは必ずしも選択肢ではありません。(古い状態は、もはや履歴のどこにも存在する必要はありません。)
トム

回答:


258

stashリストが次のようになっているとします。

$ git stash list
stash@{0}: WIP on master: Add some very important feature 
stash@{1}: WIP on master: Fix some silly bug

まず、名前を変更するstashエントリを削除する必要があります。

$ git stash drop stash@{1}
Dropped stash@{1} (af8fdeee49a03d1b4609f294635e7f0d622e03db)

ここで、ドロップ後に返されたコミットのshaを使用して、新しいメッセージを追加します。

$ git stash store -m "Very descriptive message" af8fdeee49a03d1b4609f294635e7f0d622e03db

以上です:

$ git stash list
stash@{0}: Very descriptive message
stash@{1}: WIP on master: Add some very important feature

このソリューションにはgit 1.8.4以降が必要です。そうです、ダーティな作業ディレクトリでも機能します。


3
git show stash@{0}その後も古い情報が表示されます。それを修正するには?(その後、スタッシュは別のSHAを取得することに注意してください。)
Tino

4
でハッシュを取得しgit show、で始める方が良いと感じていgit stash storeます。それからgit stash listあなたは古いものと新しいものを見るでしょう。最後に、古いスタッシュをでクリーンアップできますgit stash drop
hogi 2017

6
git stash dropは変更を失わないでしょうか?
Shravya Boggarapu 2017

4
@ShravyaBoggarapu、いや、git git gcは実行されるまでコミットを削除しません。後はstash dropあなたがこれを簡単に見つけることができ、通常はアクセスできない使用してコミットgit fsck | grep commitコマンドを。
qzb 2017

2
@ÐerÆndiは単に適用して保存するのが簡単なオプションですが、競合のために変更を再適用できない場合は機能しません。一方、ドロップおよび保管は、どのような状況でも機能します。私は自分のソリューションをもう一度テストしました-最新のgitバージョン(2.17.0)では問題なく動作します。
qzb 2018

62

手動で行うか、Gitの改善に貢献しない限り、エイリアスを使用できます。

git config --global alias.stash-rename '!_() { rev=$(git rev-parse $1) && git stash drop $1 || exit 1 ; git diff-index --quiet HEAD; s=$?; [ $s != 0 ] && git stash save "tmp stash from stash-rename"; git stash apply $rev && shift && git stash save "$@" && [ $s != 0 ] && git stash pop stash@{1}; }; _'

使用法: " git stash-rename <stash> [save options] [<message>]"

次の[save options]オプションがありますgit stash save[-p|--patch] [-k|--[no-]keep-index] [-q|--quiet] [-u|--include-untracked] [-a|--all]

例:

$ git stash list
stash@{0}: On master: Pep8 format
stash@{1}: On master: co other than master with local changes
stash@{2}: On master: tests with deployAtEnd

# Let's say I want to rename the stash@{2} adding an issue reference:
$ git stash-rename stash@{2} NXP-13971-deployAtEnd

$ git stash list
stash@{0}: On master: NXP-13971-deployAtEnd
stash@{1}: On master: Pep8 format
stash@{2}: On master: co other than master with local changes

ローカルのステージングされていない変更があっても機能します:)

編集2016/02/22

簡略化されたスクリプト、qzbのクレジット、https://stackoverflow.com/a/35549615/515973

git config --global alias.stash-rename '!_() { rev=$(git rev-parse $1) && git stash drop $1 || exit 1 ; git stash store -m "$2" $rev; }; _'

使用法: " git stash-rename <stash> [<message>]"


1
驚くばかり!できればさらにかっこいいgit stash-rename 'tests with deployAtEnd' 'NXP-13971-deployAtEnd'
mikemaccana 2014

3
答えは1)クリーンな作業コピー、2)名前を変更したいスタッシュを適用、3)スタッシュリストからドロップ、4)正しいメッセージで新しいスタッシュを作成します。
gcb

2
明確にするために、あなたは最後の隠し場所の名前を変更しています、そしてそのような行動の後、それは一番上の隠し場所になりますか?
onebree 2015

2
名前を変更するスタッシュを削除し、現在の変更があれば保存し、削除したスタッシュを希望の名前で再作成し、現在の変更があれば再適用します。
Julien Carsique 2015

3
このバージョンは、両方の引数が存在することを確認して、誤って最後のスタッシュを落とさないようにします。また、stash@{0}参照全体ではなく、スタッシュ番号のみが必要です。gist.github.com/jdforsythe/f248bf6c72fc020225cc3e315a32e922 git config --global alias.stash-rename '!_() { if [ -z \"$1\" ] || [ -z \"$2\" ]; then echo \"git stash-rename 0 NewName\" && echo \"\" && git stash list && exit 1; else stash=\"stash@{$1}\"; rev=$(git rev-parse \"${stash}\"); git stash drop \"${stash}\" || exit 1; git stash store -m \"$2\" \"$rev\" || exit 1; git stash list; fi }; _'
jdforsythe

6

とても簡単です。最初に、最後の隠しを元に戻します:

git stash pop

この後、次のようにカスタマイズした名前でスタッシュを保存できます。

git stash save "your explanatory name"

お役に立てれば幸いです。:)


名前が変更されたスタッシュは最新のものではない可能性があります。
mikemaccana

最新のstashの場合、これはより単純な(ONLY)なので、高く評価しています。
カイファ

3

そうすることは不可能だと思います。stashの名前変更の提案はありましたがまだ実装されていません。

私の一般的な考えは:

  1. git reflog update特定のreflogエントリに関連付けられたメッセージを更新する新しいコマンドを実装します。これを行うには、update_reflog_ent()reflog.c内の)新しい関数が、特定のreflogエントリに関連付けられたメッセージを変更して更新します。update_reflog()関数が使用するであろうfor_each_reflog_ent()update_reflog_ent、実際に変更を行うこと。

  2. git stash renameこのコマンドは、その後にのみ呼び出す必要がありgit reflog update、適切なrefと新しいメッセージで。

または、もちろん、隠し場所をポップして、 git stash save [message]


3

読者のために、現在受け入れられている正解の拡張を以下に示します

stashメッセージを修正するだけでなく、stashのコミットメッセージも修正する場合は、次のようにします。

git stash list

そして

git log --oneline -1 stash

どちらも表示される内容に同意するため、もう少し必要です。もっと良い方法があるかもしれませんが、このレシピは理解しやすいと思います。

これを行うにgit commit --amendは、ブランチのTIPに参加する必要があります。したがって、解決策は次のとおりです。

git checkout -b scratch stash@{1}
git stash drop stash@{1}
git commit --amend -m "$MESSAGE"
git stash store -m "$MESSAGE" HEAD
git checkout master
git branch -D scratch

説明:

  • 「問題のスタッシュ」から新しい(まだ存在しない)「スクラッチ」ブランチを作成し、それに切り替えます
  • 古い隠し場所を取り外します。これはブランチにまだあるので、これは安全です。
  • git commit --amendコミットメッセージを置き換えるために使用します。これにより、「問題のスタッシュ」のSHAが変更されます
  • qzbの答えに基づいて、スタッシュを保管します
  • 元に戻して(「マスター」から来たと想定)、クリーンアップ

欠点:

  • これは一時的にブランチを切り替えます。したがって、このレシピgit status --porcelainはクリーンな場合にのみ適用できます(読み取り:何も出力しません)。

  • スタッシュの番号が付け直されるので、変更されたスタッシュは stash@{0}

  • あなたは入力する必要が$MESSAGE二回のか(例:いくつかの環境変数を使用しますMESSAGE

  • 未使用のブランチ名を見つける必要があります

ブランチを切り替えずにこれを行う方法がありますが、これはこの回答の範囲を超えています。

git init scratch
cd scratch
for a in A B C D; do date >$a; git add $a; git commit -m $a; done
for a in X Y; do echo $a > Z; git stash save --all; done
git log --oneline --graph --decorate --all; git stash list

出力

*-.   e0e281b (refs/stash) WIP on master: 8bdcc32 D
|\ \  
| | * 4d62f52 untracked files on master: 8bdcc32 D
| * 096f158 index on master: 8bdcc32 D
|/  
* 8bdcc32 (HEAD, master) D
* c84c659 C
* 49bb2da B
* b1852c6 A
stash@{0}: WIP on master: 8bdcc32 D
stash@{1}: WIP on master: 8bdcc32 D

コミットを変更せずに(注:以下のSHAはあなたの側で異なります):

git stash drop stash@{1}
git stash store -m ...changed... 2fbf9007dfdfb95ae269a19e13b8b9ca3e24181c
git log --oneline --graph --decorate --all; git stash list

出力

*-.   2fbf900 (refs/stash) WIP on master: 8bdcc32 D
|\ \  
| | * 246dc5c untracked files on master: 8bdcc32 D
| * 80c5ea0 index on master: 8bdcc32 D
|/  
* 8bdcc32 (HEAD, master) D
* c84c659 C
* 49bb2da B
* b1852c6 A
stash@{0}: ...changed...
stash@{1}: WIP on master: 8bdcc32 D

ご覧のとおり、stash@{0}まだのように表示さ2fbf900 (refs/stash) WIP on master: 8bdcc32 Dれていgit logます。注意深く見ると、いくつかのコミットによってSHAが変更されていることがわかります。これは、スタッシュの処理方法が原因です(親はSHAに含まれ、スタッシュは親としてスタッシュを持っています)。

修正してください:

git checkout -b scratch stash
git stash drop
git commit --amend -m ...changed...
git stash store -m ...changed... HEAD
git checkout master
git branch -D scratch
git log --oneline --graph --decorate --all; git stash list

出力

*-.   4d55186 (refs/stash) ...changed...
|\ \  
| | * 246dc5c untracked files on master: 8bdcc32 D
| * 80c5ea0 index on master: 8bdcc32 D
|/  
* 8bdcc32 (HEAD, master) D
* c84c659 C
* 49bb2da B
* b1852c6 A
stash@{0}: ...changed...
stash@{1}: WIP on master: 8bdcc32 D

ご覧のとおり、refs/stashSHAも変更されています。


注目に値する:これは、元のスタッシュで保存されたインデックスを破棄し、元のスタッシュの親コミットと一致する新しいインデックスに置き換えます。保存された元のインデックスを使用する予定がなかった場合(または、元のstashの親と既に一致していた場合)、これは問題ではありません。
トレック

1

以下は、名前を隠しておくために通常付加される接頭辞を適切に処理できるようにする、Julienのエイリアスの修正バージョンですOn <branch>

git config --global alias.stash-rename '!_() { newmsg="$1" && stash=${2:-"stash@{0}"} && newbranch="$3" && sha=$(git rev-parse "$stash") && olddesc="$(git stash list --format=%gs -1 "$stash")" && newdesc="$(if [[ "$newbranch" = "." ]]; then echo "$newmsg"; else if [[ -n "$newbranch" ]]; then echo "On $newbranch: $newmsg"; else if [[ "$olddesc" =~ ":" ]]; then echo "$(echo "$olddesc" | cut -f1 -d":"): $newmsg"; else echo "$newmsg"; fi; fi; fi)" && git stash drop "$stash" > /dev/null || exit 1; git stash store -m "$newdesc" "$sha" && git stash list; }; _'

構文:

git stash-rename <new-name> [<stash> [<new-branch-name> | .]]

使用例:

repo[master] % touch tmp && git add tmp && git stash save first
Saved working directory and index state On master: first
HEAD is now at bd62064 Initial commit
repo[master] % touch tmp && git add tmp && git stash save second
Saved working directory and index state On master: second
HEAD is now at bd62064 Initial commit
repo[master] % git stash list
stash@{0}: On master: second
stash@{1}: On master: first
repo[master] % git stash-rename renamed
stash@{0}: On master: renamed
stash@{1}: On master: first
repo[master] % git stash-rename also-renamed stash@{1}
stash@{0}: On master: also-renamed
stash@{1}: On master: renamed
repo[master] % git stash-rename branch-changed stash@{0} new-branch
stash@{0}: On new-branch: branch-changed
stash@{1}: On master: renamed
repo[master] % git stash-rename branch-name-persists
stash@{0}: On new-branch: branch-name-persists
stash@{1}: On master: renamed
repo[master] % git stash-rename no-branch stash@{0} .
stash@{0}: no-branch
stash@{1}: On master: renamed
repo[master] % git stash-rename renamed
stash@{0}: renamed
stash@{1}: On master: renamed
repo[master] % git stash-rename readd-branch stash@{0} develop
stash@{0}: On develop: readd-branch
stash@{1}: On master: renamed

ほとんどのコマンドは、引数を解析し、ブランチ名に対して何をするべきかを理解するためのものです。git次のように使用されるツールは以下のとおりです。

  • git rev-parse <stash> 隠し場所のSHAを見つける。
  • git stash list --format=%gs -1 <stash>隠し場所のreflogサブジェクトを見つける。これは、このコマンドで変更されないスタッシュのコミットメッセージとは異なることに注意してください。reflogサブジェクトはに表示されるものgit stash listであり、スタッシュに関連付けられているコミットのハッシュを変更せずにreflogサブジェクトを変更できます。ただし、いつでも元のコミットメッセージを見つけることができるため、git stash-rename機密情報の削除には使用しないでください。
  • git stash drop <stash>stashへの古い参照を削除します(ただし、SHAが残っているため、失われません)。
  • git stash store -m <new-message> <sha>同じコミット情報で異なるreflogサブジェクトを持つスタッシュへの新しい参照を保存します。
  • git stash list操作の終了後にスタッシュをリストする。新しいスタッシュは常にリストの先頭にプッシュされることに注意してください。元の位置に戻すには、対象の隠し場所の前にすべての隠し場所を再度押す必要があります。

0

最も簡単な方法:git stash popでstashをポップしてから、git stashでもう一度保存しますsave your-name


名前が変更されたスタッシュは最新のものではない可能性があります。
mikemaccana
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.