Gitで変更した複数のファイルのうち、1つのファイルだけを保存する

git git-stash


複数の変更されたファイルのうち、1つだけをブランチに格納するにはどうすればいいですか?




Answer 1 bukzor


免責事項:次の回答はgit 2.13より前のgitに関するものです。git 2.13以降については、さらに下の別の回答をご覧ください。


Warning

コメントにも書いてあるように、これはすべてのものをstashに入れます(stagedとunstagedの両方)。keep-indexは、スタッシュが完了した後にインデックスを残すだけです。これは、後でスタッシュを開くときにマージの競合を引き起こす可能性があります。


これにより、以前に追加していないすべてが隠されます。ただ、 git add 残したいものを、それを実行します。

git stash --keep-index

例えば、古いコミットを複数のチェンジセットに分割したい場合は、この手順を使用します。

  1. git rebase -i <last good commit>
  2. 一部の変更を edit としてマークします。
  3. git reset HEAD^
  4. git add <files you want to keep in this change>
  5. git stash --keep-index
  6. 必要に応じて修正してください。 git add 変更を追加することを忘れないでください。
  7. git commit
  8. git stash pop
  9. 必要に応じて#5から繰り返します。
  10. git rebase --continue



Answer 2 konrad.kruczynski


git stash save -p "my commit message" を使用することもできます。このようにして、スタッシュに追加するハンクを選択でき、ファイル全体も選択できます。

ハンクごとにいくつかのアクションを促されます。

   y - stash this hunk
   n - do not stash this hunk
   q - quit; do not stash this hunk or any of the remaining ones
   a - stash this hunk and all later hunks in the file
   d - do not stash this hunk or any of the later hunks in the file
   g - select a hunk to go to
   / - search for a hunk matching the given regex
   j - leave this hunk undecided, see next undecided hunk
   J - leave this hunk undecided, see next hunk
   k - leave this hunk undecided, see previous undecided hunk
   K - leave this hunk undecided, see previous hunk
   s - split the current hunk into smaller hunks
   e - manually edit the current hunk
   ? - print help



Answer 3 VonC


Since git is fundamentally about managing a all repository content and index (and not one or several files), git stash deals, not surprisingly, with the all working directory.

Actually, since Git 2.13 (Q2 2017), you can stash individual files, with git stash push:

git stash push [--] [<pathspec>...]

pathspec が ' git stash push 'に指定されている場合、新しいstashは、pathspecに一致するファイルについてのみ変更された状態を記録します。詳細については、「特定のファイルへのStashの変更」を参照してください。

簡単な例です。

 git stash push path/to/file

この機能のテストケースでは、さらにいくつかのオプションがオフになっています。

test_expect_success 'stash with multiple pathspec arguments' '
    >foo &&
    >bar &&
    >extra &&
    git add foo bar extra &&

    git stash push -- foo bar &&   

    test_path_is_missing bar &&
    test_path_is_missing foo &&
    test_path_is_file extra &&

    git stash pop &&
    test_path_is_file foo &&
    test_path_is_file bar &&
    test_path_is_file extra

元々の回答(以下、2010年6月)は、隠しておきたいものを手動で選ぶというものでした。

Casebashのコメント:

これ( stash --patch 元のソリューション)は素晴らしいですが、多くの場合、多くのファイルを変更したため、patchの使用は面倒です

bukzor回答(2011年11月賛成)は、
git add + git stash --keep-index
彼の答えを見に行って、公式のものでなければならない(私のものではなく)彼の答えにアップバトしてください。

そのオプションについて、chhhはコメントで代替ワークフローを指摘しています。

そのようなstashの後に「 git reset --soft 」を実行して、明確なステージングを取り戻す必要があります。
元の状態に到達するためには-これは明確な演出領域であり、いくつかの選択された未演出の修正のみで、1つは(あなたのような何かをコミットせずに-bukzor -がした)取得するためにインデックスをソフトにリセットすることができました。


(2010年6月の元の回答:手動スタッシュ)

しかし、 git stash save --patch を使用すると、次の部分的な隠蔽を実現できます。

では --patch 、あなたが対話的にHEADとスタッシュする作業ツリー間の差分でからハンクを選択することができます。
スタッシュエントリは、そのインデックスの状態がリポジトリのインデックスの状態と同じになるように構築され、ワークツリーには対話的に選択した変更のみが含まれます。選択した変更はワークツリーからロールバックされます。

しかし、これは完全なインデックス(すでにインデックス化されている他のファイルを含むかもしれないので、あなたが望むものではないかもしれません)と、部分的なワークツリー(これはあなたが隠したいもののように見えるかもしれません)を保存することになります。

git stash --patch --no-keep-index

の方が合っているかもしれません。


--patch が機能しない場合、手動プロセスでは次のようになる可能性があります。

1つまたは複数のファイルについては、中間的な解決策は次のようになります。

  • Git レポの外にコピーします。
    (実際、eleotlecram興味深い代替案を提案しています)
  • git stash
  • 写し返す
  • git stash #今回は、必要なファイルのみが隠されます
  • git stash pop stash@{1} #すべてのファイルの変更を再適用
  • git checkout -- afile #ローカルで変更する前に、ファイルをHEADコンテンツにリセットします

その面倒な作業の最後には、1つか数個のファイルしか保存されていないことになります。




Answer 4 blueyed


ときに git stash -p (または git add -pstash --keep-index )あまりにも面倒だろう、私はそれが簡単に使用することが分かっ diffcheckout して apply

特定のファイル/ディレクトリのみを「保存」します。

git diff path/to/dir > stashed.diff
git checkout path/to/dir

その後

git apply stashed.diff



Answer 5 sandstrom


次のように git stash push を使用します。

git stash push [--] [<pathspec>...]

例えば

git stash push -- my/file.sh

これは、2017年春にリリースされたGit 2.13以降で使用できます。