ブランチで複数の変更されたファイルの1つだけを隠しておくにはどうすればよいですか?
git diff -- *filename* > ~/patch
その後git checkout -- *filename*
、後でパッチを再適用できますgit apply ~/patch
git stash push [--] [<pathspec>...]
ます。
ブランチで複数の変更されたファイルの1つだけを隠しておくにはどうすればよいですか?
git diff -- *filename* > ~/patch
その後git checkout -- *filename*
、後でパッチを再適用できますgit apply ~/patch
git stash push [--] [<pathspec>...]
ます。
回答:
免責事項:次の回答はgit 2.13より前のgitに関するものです。git 2.13以降については、さらに下の別の回答をご覧ください。
警告
コメントで述べたように、これにより、ステージングされたものとステージングされていないものの両方がすべてスタッシュに入れられます。--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 -k
、はい、インデックス(の緑git stat
)は保持されますが、変更セット全体(緑と赤の両方)が隠されます。これはOPの「一部の変更のみを隠す」という要求に違反します。赤の一部だけを隠しておきたい(将来の使用のため)。
git stash -p
まさに私が探していたものです。このスイッチがつい最近追加されたのだろうか。
git stash --keep-index
壊れています。さらに変更を加えた場合は、git stash pop
後で保存しようとすると、保持していないファイルだけでなく、変更したファイルがstashに含まれるため、マージの競合が発生します。たとえば、Aの変更をテストしたいので、ファイルAとBを変更してからBを隠します。Aの問題を見つけて修正します。私はAをコミットします。古いバージョンのAがマージの競合を引き起こす正当な理由がないので、私は元に戻すことができません。私は基本的にして失うB.を放棄しなければならないので、実際のAとBには、多くのファイル、おそらく二値画像か何かかもしれない
も使用できます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
stash -p
。これが最もインタラクティブ/ユーザーフレンドリーであり続けるため、私はこの回答を授与します。
git stash save -p my stash message
; 議論の順序はあまり直感的ではないので...
git log -p
、-p
フラグは「自分がやりたいことをするが、表現方法がわからない」という意味である必要があると思います。
gitは基本的にすべてのリポジトリのコンテンツとインデックス(および1つまたは複数のファイルgit stash
ではない)を管理することを目的としているため、驚くことではありませんが、すべての作業ディレクトリ。
実際、Git 2.13(2017年第2四半期)以降、次のコマンドで個々のファイルを隠しておくことができますgit stash push
。
git stash push [--] [<pathspec>...]
pathspec
'git stash push
' が指定された場合、新しいstashは、パス仕様に一致するファイルについてのみ変更された状態を記録します。詳細については、「特定のファイルへの 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
元の解決策)は素晴らしいですが、多くの場合、多くのファイルを変更したため、パッチの使用は面倒です
bukzorの回答(2011年11月に賛成)は、
git add
+git stash --keep-index
に基づいたより実用的な解決策を示唆しています。
彼の答えを見て賛成投票してください。これは(私の代わりに)公式の答えになるはずです。
そのオプションについて、chhhはコメントで代替ワークフローを指摘しています。
git reset --soft
明確なステージングを取得するには、このようなstashの後に" "を実行する必要があります。
元の状態に戻るには、ステージング領域が明確であり、ステージングされていない変更をいくつか選択するだけで、取得するインデックスをソフトにリセットできます(あなたのような何かを犯す-bukzor-しました)。
(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 reset
(混合)
git is fundamentally about managing a all repository content and index and not one or several files
-それは、解決される問題を覆す実装です。それは説明ですが、正当化ではありません。すべてのソース管理システムは、「複数のファイルの管理」に関するものです。最も賛成されているコメントを見てください。
ときに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 add -p
上記の私自身の回答で述べたIの興味深い代替案。+1。
git diff > file.diff
そしてgit apply
私のいつも部分スタッシュツールです。git stash -p
より大きなチェンジセットへの切り替えを検討する必要があるかもしれません。
patch = log --pretty=email --patch-with-stat --reverse --full-index --binary
。ただし、パッチをコミットするには変更が必要です。
../../foo/bar.txt
。パッチは問題なく生成されますが、パッチを適用するためにリポジトリルートに移動する必要があります。したがって、これで問題が発生した場合は、リポジトリのルートディレクトリから実行していることを確認してください。
次のgit stash push
ようにを使用します。
git stash push [--] [<pathspec>...]
例えば:
git stash push -- my/file.sh
これは、2017年春にリリースされたGit 2.13以降で使用できます。
git stash push
すでに5月前の昨年3月の私の回答ですでに言及しています。そして、その新しいGit 2.13コマンドをここで詳しく説明します:stackoverflow.com/a/42963606/6309。
git stash apply
、隠された変更を回復するために使用しますか?
あなたが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 stashを「どこか」として使用しました(その結果、最後に追加の手順が1つあります。スタッシュに入れたカーブを削除します。これは、これらを邪魔にならないように移動したためです)。
更新(2015年2月14日)-競合のケースをより適切に処理できるようにスクリプトを少し書き直しました。これにより、.rejファイルではなくマージされていない競合として表示されるようになりました。
@bukzorのアプローチの逆を行う方が直感的であることがよくあります。つまり、一部の変更をステージングし、それらのステージングされた変更のみを隠しておきます。
残念ながら、gitはgit stash --only-indexなどを提供していないため、これを行うためのスクリプトを作成しました。
#!/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
これでstashには、ステージングした変更のみを含む新しいエントリが含まれ、作業ツリーにはまだステージングされていない変更が含まれています。
場合によっては、作業ツリーの変更がインデックスの変更に依存することがあるため、インデックスの変更を隠しておくと、作業ツリーの変更が競合します。この場合、通常のマージされていない競合が発生し、git merge / git mergetool / etcで解決できます。
pushd
の代わりcd
とpopd
スクリプトが成功した場合、ユーザーはそれを実行する前と同じディレクトリに終わるようにスクリプトの終わりに。
Gitでブランチを作成するのは簡単なので、一時的なブランチを作成して個々のファイルをチェックインするだけで済みます。
あなたは単にこれを行うことができます:
git stash push "filename"
またはオプションのメッセージ
git stash push -m "Some message" "filename"
次のコードを、という名前のファイルに保存します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
}
}
}
VonCのGitリポジトリの外部にファイルをコピーする「中間」ソリューションの問題は、パス情報が失われることです。
コピーの代わりにtarを使用する方が簡単だと思います(類似のツールがおそらくそうでしょう)。
checkout -f
必要はありません、checkout
(なしで-f
)十分です、私は答えを更新しました。
コミットする前に、ブランチに無関係な変更を加えたことがあります。それを別のブランチに移動して、個別に(マスターのように)コミットしたい場合があります。私はこれをします:
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
をチェックアウト時にブランチに引き継ぐことができますが、競合がない場合のみです。また、部分的な変更のために新しいブランチを作成する場合は、スタッシュが必要になります。
競合や新しいブランチがないと仮定して、これを簡略化できます。
git checkout master
git add <files that you want to commit>
git commit -m 'Minor feature'
git checkout topic1
...<resume work>...
隠しておく必要さえない...
これは、SourceTreeを使用して3つのステップで簡単に実行できます。
これはSourceTreeでほんの数秒で実行でき、追加するファイル(または個々の行)をクリックするだけです。追加したら、それらを一時的なコミットにコミットします。次に、チェックボックスをクリックしてすべての変更を追加し、次にstashをクリックしてすべてを隠します。隠された変更を邪魔にならないようにして、コミットリストを見て、一時的なコミットの前にコミットのハッシュを確認します。次に、 'git reset hash_b4_temp_commit'を実行します。これは、ブランチをその直前にコミットします。これで、隠したくないものだけが残ります。
私は使用しますgit stash save --patch
。ファイル全体に目的の操作を適用するためのオプションがあるため、対話性が煩わしいとは思いません。
git stash -p
ファイル全体をすばやく隠して、後で終了できるようにすることです。
ここでのすべての答えはとても複雑です...
これを「隠しておく」とは何ですか。
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 apply
私はエラーを持っていませんが、変更はどちらも持ち帰っていないされていません
私はこれと同様のいくつかのスレッドに対する回答とコメントを確認しました。次のコマンドはいずれも、特定の追跡/追跡解除されたファイルを隠せるようにするためのものではないことに注意してください。
git stash -p (--patch)
:追跡されていないファイルを除外して、ハンクを手動で選択しますgit stash -k (--keep-index)
:すべての追跡/非追跡ファイルを隠し、作業ディレクトリに保存しますgit stash -u (--include-untracked)
:すべての追跡/非追跡ファイルを隠しますgit stash -p (--patch) -u (--include-untracked)
:無効なコマンド現在、特定の追跡/追跡されていないファイルを隠しておくための最も合理的な方法は、次のとおりです。
私は別の質問への答えに、この手順のために簡単なスクリプトを書いて、そこにあるここでSourceTreeの手順を実行するための手順が。
ローカル変更:
上の変更のみでスタッシュ「my_stash」を作成するにはfile_C:
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を使用して、何が起こっているかを確認できます。
2つのブランチ間を切り替えようとすると、この状況が発生します。
" git add filepath
" を使用してファイルを追加してください。
後でこの行を実行します
git stash --keep-index
1つのファイルを隠しておくには、を使用しますgit stash --patch [file]
。
プロンプトが表示されます:Stash this hunk [y,n,q,a,d,j,J,g,/,e,?]? ?
。入力するだけでa
、あなたしている罰金(この塊とファイル内のすべての後にハンクを隠しておきます)。
push
しているgit stash push --patch [file]
同様の状況。コミットして、問題があることに気付きました。
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
コマンドラインでそれを行う方法がわかりません。SourceTreeを使用するだけです。ファイルAを変更し、ファイルBに2つの変更ハンクがあるとします。ファイルBの2番目のハンクのみを隠しておき、他のすべてを変更しない場合は、次のようにします。
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)
複雑な方法の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 add -A
git reset HEAD fileThatYouWantToStash
git commit -m "committing all but one file"
git stash
これはちょうど1つのファイルを隠します。
gitで特定の変更されたファイルを元に戻すには、次の行を実行します。
git checkout <branch-name> -- <file-path>
これが実際の例です:
git checkout master -- battery_monitoring/msg_passing.py
git stash --keep-index
インデックスは保持されますが、インデックス内とアウトの両方ですべてが隠されます。