ブランチ上の複数の変更されたファイルのうち1つだけを隠すにはどうすればいいですか?
警告
コメントで述べたように、これは段階的でも段階的でもなくすべてを隠し場所に入れます。 --keep-indexはスタッシュが完了した後にインデックスをそのままにします。後でスタッシュをポップすると、マージの競合が発生する可能性があります。
これはあなたが以前に追加していなかったすべてを隠します。保持したいものをgit add
してから実行してください。
git stash --keep-index
たとえば、古いコミットを複数のチェンジセットに分割したい場合は、この手順を使用できます。
git rebase -i <last good commit>
edit
としてマークします。git reset HEAD^
git add <files you want to keep in this change>
git stash --keep-index
git add
に変更を忘れないでください。git commit
git stash pop
git rebase --continue
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
Gitは基本的にすべてのリポジトリcontentとインデックス(そして1つまたは複数のファイルではない)を管理することを目的としているので、git stash
は驚くことではありませんが対処します、 全作業ディレクトリ。
実際、Git 2.13(2017年第2四半期)以降、 git stash Push
を使用して個々のファイルを隠蔽することができます。
git stash Push [--] [<pathspec>...]
pathspec
が 'git stash Push
'に与えられると、新しいスタッシュはパス指定と一致するファイルについてのみ変更された状態を記録します
詳しくは " 特定のファイルへの変更を隠す "をご覧ください。
テストケース 自明です:
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 comments:
これ(
stash --patch
オリジナルの解決策)はいいですが、私は多くのファイルを修正したので、patchを使うのは面倒です。
bukzor 's answer (2011年11月に支持されました)は、git add
+ git stash --keep-index
。
彼の答えを見て、支持してください。それは公式のものであるべきです(私の代わりに)。
そのオプションについて、 chhh はコメント内の代替ワークフローを指摘しています。
明確なステージングを取り戻すには、このようなスタッシュの後に "
git reset --soft
"を入力する必要があります。
明確なステージング領域で、一部の選択されたステージングされていない変更のみを含む元の状態に到達するために、インデックスをソフトにリセットして取得することができます。
(元の回答2010年6月:手動隠し場所)
それでも、git stash save --patch
を使用すると、自分がしている部分的な隠蔽を実現できます。
--patch
を使うと、HEADと隠される作業ツリーの間の差分からハンクを対話的に選択することができます。
stashエントリは、そのインデックス状態がリポジトリのインデックス状態と同じになるように作成されており、そのワークツリーには対話的に選択した変更のみが含まれています。選択した変更はワークツリーからロールバックされます。
ただし、完全なインデックス(既にインデックスが作成されている他のファイルが含まれている可能性があるため、必要なものではない可能性があります)と部分的なワークツリー(隠したいもののように見える)が保存されます。
git stash --patch --no-keep-index
より良いフィットかもしれません。
--patch
が機能しない場合は、手動プロセスで可能性があります。
1つまたは複数のファイルの場合、中間的な解決策は次のようになります。
git stash
git stash
#今回は、欲しいファイルだけが隠されていますgit stash pop stash@{1}
#すべてのファイル修正を再適用しますgit checkout -- afile
#ローカルの修正の前に、ファイルをHEADコンテンツにリセットしますやや面倒なプロセスの終わりには、1つか複数のファイルが隠されることになります。
git stash -p
(またはgit add -p
と一緒のstash --keep-index
)が面倒すぎる場合は、diff
、checkout
およびapply
を使用する方が簡単であることがわかりました。
特定のファイル/ディレクトリのみを「隠蔽」するには
git diff path/to/dir > stashed.diff
git checkout path/to/dir
その後
git apply stashed.diff
このようにgit stash Push
を使用してください。
git stash Push [--] [<pathspec>...]
例えば:
git stash Push -- my/file.sh
2017年春にリリースされたGit 2.13以降で利用可能です。
3つのファイルがあるとしましょう
a.rb
b.rb
c.rb
そして、あなたはb.rbとc.rbだけを隠したいがa.rbは隠したくない
あなたはこのようなことをすることができます
# commit the files temporarily you don't want to stash
git add a.rb
git commit -m "temp"
# then stash the other files
git stash save "stash message"
# then undo the previous temp commit
git reset --soft HEAD^
git reset
そして、これで終わりです! HTH。
これを行う別の方法:
# Save everything
git stash
# Re-apply everything, but keep the stash
git stash apply
git checkout <"files you don't want in your stash">
# Save only the things you wanted saved
git stash
# Re-apply the original state and drop it from your stash
git stash apply stash@{1}
git stash drop stash@{1}
git checkout <"files you put in your stash">
私が(もう一度)このページに来た後、私はこれを思いつきました、そして、最初の2つの答えが好きではありませんでした(最初の答えはただ質問に答えないし、私は-p
インタラクティブモードで作業するのがあまり好きではありません).
考え方は@VonCがリポジトリの外でファイルを使うことを提案したのと同じです、あなたがどこかに欲しい変更を保存し、あなたの隠し場所に望まない変更を削除し、そして邪魔にならなかった変更を再適用します。しかし、私はgitスタッシュを「どこか」として使用しました(そして結果として、最後にもう1つステップがあります。スタッシュに入れた変更を削除するのは、邪魔にならないためです。
アップデート(2/14/2015) - 私は衝突のケースをよりよく扱うためにスクリプトを少し書き直しました。これは.rejファイルではなくマージされていない衝突として提示されるべきです。
@ bukzorのアプローチの逆を実行する方が直感的にわかります。つまり、いくつかの変更をステージングしてから、ステージングされた変更のみを隠します。
残念なことに、gitはgit stashを提供していません - インデックスのみ、またはそれに類似しているので、私はこれを行うためのスクリプトを作成しました。
#!/bin/sh
# first, go to the root of the git repo
cd `git rev-parse --show-toplevel`
# create a commit with only the stuff in staging
INDEXTREE=`git write-tree`
INDEXCOMMIT=`echo "" | git commit-tree $INDEXTREE -p HEAD`
# create a child commit with the changes in the working tree
git add -A
WORKINGTREE=`git write-tree`
WORKINGCOMMIT=`echo "" | git commit-tree $WORKINGTREE -p $INDEXCOMMIT`
# get back to a clean state with no changes, staged or otherwise
git reset -q --hard
# Cherry-pick the index changes back to the index, and stash.
# This cherry-pick is guaranteed to succeed
git cherry-pick -n $INDEXCOMMIT
git stash
# Now cherry-pick the working tree changes. This cherry-pick may fail
# due to conflicts
git cherry-pick -n $WORKINGCOMMIT
CONFLICTS=`git ls-files -u`
if test -z "$CONFLICTS"; then
# If there are no conflicts, it's safe to reset, so that
# any previously unstaged changes remain unstaged
#
# However, if there are conflicts, then we don't want to reset the files
# and lose the merge/conflict info.
git reset -q
fi
上記のスクリプトをパスのどこかにgit-stash-index
として保存してから、git stash-indexとして呼び出すことができます
# <hack hack hack>
git add <files that you want to stash>
git stash-index
これで、隠し場所には、ステージングした変更のみを含む新しいエントリが含まれ、作業ツリーにはまだステージングされていない変更がすべて含まれます。
場合によっては、作業ツリーの変更がインデックスの変更に依存することがあるため、インデックスの変更を隠しておくと、作業ツリーの変更に矛盾が生じます。この場合、git merge/git mergetool/etcで解決できる通常のマージされていない競合が発生します。
Gitでブランチを作成するのは簡単なので、一時的なブランチを作成して個々のファイルをチェックインするだけで済みます。
念のために、実際に 変更を破棄 git stash
を使用するときはいつでも(そして一時的にそれを隠すためにgit stashを使用しないでください)
git checkout -- <file>
[注意]
そのgit stash
は、分岐してものを実行するための、より速くて単純な代替手段にすぎません。
次のコードをstash
などのファイルに保存します。使い方はstash <filename_regex>
です。引数はファイルのフルパスの正規表現です。たとえば、/ b/c.txt、stash a/b/c.txt
、stash .*/c.txt
などを隠します。
$ chmod +x stash
$ stash .*.xml
$ stash xyz.xml
ファイルにコピーするコード:
#! /usr/bin/expect --
log_user 0
set filename_regexp [lindex $argv 0]
spawn git stash -p
for {} 1 {} {
expect {
-re "diff --git a/($filename_regexp) " {
set filename $expect_out(1,string)
}
"diff --git a/" {
set filename ""
}
"Stash this hunk " {
if {$filename == ""} {
send "n\n"
} else {
send "a\n"
send_user "$filename\n"
}
}
"Stash deletion " {
send "n\n"
}
eof {
exit
}
}
}
Gitリポジトリの外部にファイルをコピーするVonCの「中間的な」解決方法の問題は、パス情報を失うことです。
コピーではなくtarを使用するほうが簡単です(似たようなツールでもおそらく可能です)。
これはSourceTreeを使用して3つのステップで簡単に行うことができます。
SourceTreeでは、これをすべて数秒で実行できます。追加したいファイル(または個々の行)をクリックするだけです。追加したら、それらを一時的なコミットにコミットします。次に、チェックボックスをクリックしてすべての変更を追加し、次にstashをクリックしてすべてを変更します。変更が邪魔にならないようにして、コミットリストを見て、一時的なコミットの前にコミットのハッシュを書き留めてから、 'git reset hash_b4_temp_commit'を実行します。その直前にコミットします。今、あなたはあなたが隠したくないものだけを残しています。
私はgit stash save --patch
を使います。必要な操作をファイル全体に適用するためのオプションがあるため、対話性が面倒なことはわかりません。
コミットする前に自分のブランチに無関係な変更を加えたことがあるので、それを別のブランチに移動して別々にコミットしたい(masterのように)。私はこれをします:
git stash
git checkout master
git stash pop
git add <files that you want to commit>
git commit -m 'Minor feature'
git stash
git checkout topic1
git stash pop
...<resume work>...
最初のstash
とstash pop
は削除することができます、あなたがチェックアウトするとき、あなたはすべての変更をmaster
ブランチに引き継ぐことができますが、それは衝突がない場合に限ります。また、部分的な変更のために新しいブランチを作成しているのであれば、stashが必要になります。
競合も新しいブランチもないと仮定すると、単純化できます。
git checkout master
git add <files that you want to commit>
git commit -m 'Minor feature'
git checkout topic1
...<resume work>...
スタッシュも必要ありません...
これを簡単に行うことができます:
git stash Push "filename"
またはオプションのメッセージ付き
git stash Push -m "Some message" "filename"
ここでのすべての答えはとても複雑です...
これを「隠蔽」するのはどうでしょうか。
git diff /dir/to/file/file_to_stash > /tmp/stash.patch
git checkout -- /dir/to/file/file_to_stash
これはファイル変更をポップバックするものです。
git apply /tmp/stash.patch
1つのファイルを隠してそれを元に戻すのと同じ動作.
私はこれに関する答えとコメント、そして同様のスレッドをいくつか見直しました。 特定の追跡/未追跡ファイル を隠すことができるという目的には、次のコマンドはどれも正しくないことに注意してください。
git stash -p (--patch)
:追跡されていないファイルを除いて、手動でハンクを選択git stash -k (--keep-index)
:全ての追跡された/追跡されていないファイルを隠して作業ディレクトリに保存するgit stash -u (--include-untracked)
:全ての追跡された/追跡されていないファイルを隠しますgit stash -p (--patch) -u (--include-untracked)
:無効なコマンド現在、追跡されている/追跡されていない特定のファイルを隠すことができる最も合理的な方法は、次のとおりです。
私は別の質問に対する答えとしてこの手順のための簡単なスクリプトを書きました そしてここでSourceTreeで手順を実行するための ステップがあります 。
ローカルの変更点
file_C の変更のみを含む隠し場所「my_stash」を作成するには、次のようにします。
1. git add file_C
2. git stash save --keep-index temp_stash
3. git stash save my_stash
4. git stash pop stash@#{1}
完了しました。
何が起こっているのかを見るために、ステップの間に git status を使うことができます。
隠しておいた変更を含むメッセージを指定したくない場合は、ファイル名を二重ダッシュの後に渡してください。
$ git stash -- filename.ext
追跡されていない/新しいファイルの場合は、最初にステージングする必要があります。
このメソッドはgitバージョン2.13以降で動作します
git add . //stage all the files
git reset <pathToFileWillBeStashed> //unstage file which will be stashed
git stash //stash the file(s)
git reset . // unstage all staged files
git stash pop // unstash file(s)
単一のファイルを隠すにはgit stash --patch [file]
を使います。
これはプロンプトに行きます:Stash this hunk [y,n,q,a,d,j,J,g,/,e,?]? ?
。 a
とタイプするだけで(このハンクを隠して、後でファイル内のすべてのハンクを隠します)、大丈夫です。
このような状況では、私はgit add -p
(interactive)、git commit -m blah
、そして必要なら残ったものを隠します。
似たような状況。コミットし、それが問題ではないことに気付きました。
git commit -a -m "message"
git log -p
答えに基づいてこれは私を助けた。
# revert to previous state, keeping the files changed
git reset HEAD~
#make sure it's ok
git diff
git status
#revert the file we don't want to be within the commit
git checkout specs/nagios/nagios.spec
#make sure it's ok
git status
git diff
#now go ahead with commit
git commit -a -m "same|new message"
#eventually Push tu remote
git Push
2つのブランチを切り替えようとすると、この状況が発生します。
"git add filepath
"を使用してファイルを追加してみてください。
後でこの行を実行
git stash --keep-index
SourceTreeのみを使用して、コマンドラインで実行する方法がわかりません。ファイルAを変更し、ファイルBに2つの変更ハンクがあるとしましょう。ファイルBの2番目のハンクだけを隠して他のすべてをそのままにしたい場合は、次のようにします。
私が必要としているものであるという答えが見つからず、それは次のように簡単です。
git add -A
git reset HEAD fileThatYouWantToStash
git commit -m "committing all but one file"
git stash
これはちょうど1つのファイルを隠します。
1つの複雑な方法は、最初にすべてをコミットすることです。
git add -u
git commit // creates commit with sha-1 A
元のコミットにリセットしますが、新しいコミットからthe_one_fileをチェックアウトします。
git reset --hard HEAD^
git checkout A path/to/the_one_file
これでthe_one_fileを隠すことができます。
git stash
コミットした内容をファイルシステムに保存し、元のコミットに戻してクリーンアップします。
git reset --hard A
git reset --soft HEAD^
ええ、やや厄介な...
Gitで特定の変更されたファイルを元に戻すには、次の行を実行できます。
git checkout <branch-name> -- <file-path>
これが実際の例です。
git checkout master -- battery_monitoring/msg_passing.py