Gitでステージングされていない変更のみを隠しておく


229

次のワークフローを実行したいと思います。

  1. ステージに変更を追加します。
  2. ステージングされなかった他のすべての変更を隠しておきます。
  3. 段階的なもの(つまり、ビルド、テストの実行など)を実行します。
  4. 隠し場所を適用します。

ステップ2を実行する方法はありますか?

 echo "123" > foo
 git add foo # Assumes this is a git directory
 echo "456" >> foo
 git stash
 cat foo # Should yield 123

ステージング後に変更をコミットしませんか?
Shizzmo、2011年

3
IIRC --keepindexはまさにそれを実行します
sehe

4
たとえば、ビルドが失敗した場合、私はこれをコミットしたくありません。コミットを削除できることはわかっていますが、可能であればコミットせずに削除したいと思います。
Unapiedra

セヘ、ありがとう。この作品は確認できました。ああ、私はlinux.die.net/man/1/git-stashにあるマニュアルを見て、古くなっています。man git stashはるかに優れています。
Unapiedra

--keep-index、fwiwです。
jaf0 14年

回答:


288

git stash save--keep-index必要なものを正確に実行するオプションがあります。

したがって、を実行しgit stash save --keep-indexます。


9
そうだね。と使い続けてsavegit stashます。多分それはapply / popで対称性を尊重することを主張する私のプログラマーです。:)
vhallac '10 / 10/04

104
注:これでもすべての変更が隠されています。レギュラーgit stash saveとの唯一の違いは、すでにステージングされた変更が作業コピーにも残ることです。上記のワークフローでは、スタッシュの変更の半分をすでに持っているローカルコピーの上にスタッシュを適用しているだけなので、これは正常に機能します(gitは無視できるほどスマートです)。ただし、スタッシュを再適用する前にコードを編集すると、適用するときにマージの競合が発生する可能性があります。ご参考までに。
peterflynn 2014年

2
@ytpeteそれは私を何度も噛みました。私はgitがあなたが保持していないものだけを隠しておく方法があったらいいのにと思います...私はしばしばgit commit --ammend何かをコミットしてから、コミットしたことに問題がある場合にできることを知って、完全なgit stash を実行します。
rjmunro 2014

1
--amend(ではなく--ammend
Rhubbarb 2015年

19
このソリューションは、peterflynnによって説明されている問題のため、私にはうまくいきません。それはまだ段階的な変更を隠しているので、質問への良い答えではありません。誰かがより良い解決策を手に入れましたか?
user643011 2017年

43

これは3段階で行うことができます。段階的な変更の保存、その他すべての隠し場所、段階的な変更によるインデックスの復元です。基本的には次のとおりです。

git commit -m 'Save index'
git stash push -u -m 'Unstaged changes and untracked files'
git reset --soft HEAD^

これはまさにあなたが望むことをします。


3
注:-u追跡されていないファイルも隠しておきます。
ma11hew28 2018

このアプローチは、本質的にgit stash save --keep-index多くの作業で行われることを複製します。何のメリットもない。
イニゴ

1
@vasいいえ、アプローチはそれを複製しません。受け入れられた回答に対するpeterflynnのコメントを参照してください。
Alexander Klauer

28
git stash save --keep-index

また、Re:

ステージング後に変更をコミットしませんか?–シン

A:テスト済みのコードは常にチェックインする必要があるため:)つまり、コミットしようとしている変更のみを使用してテストを実行する必要があります。

もちろん、経験豊富なプログラマーとして、これらの変更だけをテストして確認するという生来の衝動がありますが、一部は冗談です


14

git version 2.7.4あなたが行うことがあります。

git stash save --patch

gitスタッシュに変更を加えるかどうかをお願いしています。
そして、あなたはただ答えるyn

常にそうするように、作業ディレクトリを復元できます。

git stash pop

または、保存した変更をstashに保持したい場合:

git stash apply

これは素晴らしいです。少し手間がかかりますが、少なくともファイル全体をスキップして追加できます。
ダスティンオプレア

5

以前の回答を拡張して、私は時々複雑な一連の変更を行いますが、最初に別の変更をコミットしたいと思います。たとえば、段階的な変更の前に修正したいバグや不正なコードを見つけた可能性があります。取るべき1つの可能なルートはこれです:

最初にすべてを隠しますが、段階的な変更はそのままにします

$ git stash save --keep-index [--include-untracked]

ステージングされた変更を個別に隠します

$ git stash save

修正のために変更を加える。そしてテスト; それらをコミットします:

$ git add [--interactive] [--patch]

$ git commit -m "fix ..."

以前にステージングされた変更を復元します。

$ git stash pop

競合を解決し、競合があった場合、gitはそのトップstashエントリを適用しましたがドロップしなかったことに注意してください。

(...次に、段階的な変更をコミットし、他のすべての変更の隠し場所を復元して、続行します...)


4

タグ付けされていない(コミットには追加されない)ファイルをstashに追加するには、次のコマンドを実行します。

git stash -k

次に、ステージングされたファイルをコミットできます。その後、次のコマンドを使用して、最後に隠されたファイルを取得できます。

git stash pop

4

Gitで作業ツリー(ステージングされていない変更)だけを隠しておくことは、本来あるべきことよりも困難です。受け入れられた回答は、ステージングされていない変更を隠しますが、ステージングされた変更も隠します(そしてそれらもステージングされたままにします)。

このエイリアスはうまく機能します:

stash-working = "!f() { \
  git commit --quiet -m \"temp for stash-working\" && \
  git stash push \"$@\" && \
  git reset --quiet --soft HEAD~1; }; f"

これは、残りの変化からスタッシュを作成する(とよう追加の引数は、このようなことができ、一時的に変更を上演コミット--include-untrackedし、--message別名引数として渡される)、その後、一時的な段階的な変化を取り戻すためにコミットリセットされます。

これは@Simon Knappの回答に似ていますが、いくつかの小さな違いがあります- --quiet実行される一時的なアクションで使用され、をpushハードコーディングするの-mではなく、stashの任意の数のパラメーターを受け入れ--soft、最終的に追加します開始時にインデックスが残るようにリセットします。

ステージングされた変更だけを隠しておくという反対の問題(エイリアス stash-indexこの回答を参照してください。


2

質問に関連する別のヒント:

ステージングされていない変更を効果的に隠しておくとき

$ git stash save --keep-index

あなたはstashにメッセージを与えたいと思うかもしれません。そうすることで、git stash listあなたが以前にstash したことをより明確にすることができます。例えば

$ git stash save --keep-index "変更はまだステージングされていません"

(実際には、他の回答に記載されているすべての変更が含まれています)。

たとえば、上記の直後に以下が続く場合があります。

$ git stash save "機能Xの段階的な変更"

ただし、その後は使用できないことに注意してください

$ git stash apply "stash @ {1}" ###✘期待どおりに動作しない

ステージングされていない変更のみを復元します。


2

Gitには、ステージングされていない変更のみを隠しておくコマンドはありません。

ただし、Gitでは、隠しておくファイルを指定できます。

git stash push --message 'Unstaged changes' -- app/controllers/products_controller.rb test/controllers/products_controller_test.rb

これらのファイルの特定の変更のみを隠したい場合は、--patchオプションを追加します。

git stash push --patch --message 'Unstaged changes' -- app/controllers/products_controller.rb test/controllers/products_controller_test.rb

この--include-untrackedオプションを使用すると、追跡されていないファイルを隠しておくことができます。

git stash push --include-untracked --message 'Untracked files' -- app/controllers/widgets_controller.rb test/controllers/widgets_controller_test.rb

詳細については、実行git help stash(またはman git-stash)してください。

注:ステージングされていない変更がかなりまとまりのないものである場合、@ alesguzikの答えはおそらく簡単です。


0

そのコマンドの最新の形式はgit stash push [--] [<pathspec>...]、Git 2.16以降(git stash save非推奨)です。

これをワイルドカード形式と組み合わせることができます。次に例を示します。

git stash push --all --keep-index ':(glob)**/*.testextension' 

ただし、Git 2.22(2019年第2四半期)までは、Git for Windowsではうまく機能しません。問題2037を参照してください。Cに再実装されていることを考慮しください。git stash(シェルスクリプトの代わりに)

Thomas Gummerer()によるcommit 7db9302(2019年3月11日)を参照してください。Johannes Schindelin()によるcommit 1366c78commit 7b556aa(2019年3月7日)を 参照してください。(合併によりJunio C浜野- -0ba1ba4コミット 2019年4月22日)tgummerer
dscho
gitster

組み込みstash:(glob)pathspecsを再度処理する

たとえば、pathspecsのリストを渡す場合、pathspecs git addの解析された形式ではなく、元の形式を使用するように注意する必要があります。

これにより、たとえば呼び出し時に違いが生じます

git stash -- ':(glob)**/*.txt'

元のフォームには:(glob)接頭辞が含まれますが、解析されたフォームには含まれません。

ただし、組み込みではgit stash、解析済み(つまり、正しくない)フォームを渡したためgit add、エラーメッセージが表示されて失敗しました。

fatal: pathspec '**/*.txt' did not match any files

実際に正常に更新されていgit stashても、変更をワークツリーから削除する段階refs/stash


0

stashエントリへのメッセージとして使用する文字列を受け入れるエイリアスを使用します。

mystash = "!f() { git commit -m hold && git stash push -m \"$1\" && git reset HEAD^; }; f"

どれ:

  • インデックス内のすべてをコミットし、
  • 作業ツリーで変更されたものを隠します(もちろん追加-uまたは-a
  • 最後のコミットを作業中の試行にリセットします(--softインデックスに保持するために使用する場合があります)。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.