使うとき
git rm --cached myfile
ローカルファイルシステムからは削除されません。これが目的です。ただし、ファイルのバージョン管理とコミットを既に行っており、それを中央リポジトリにプッシュし、コマンドを使用する前に別のリポジトリにプルした場合は、そのシステムからファイルが削除されます。
ファイルシステムから削除せずに、バージョン管理からファイルを削除する方法はありますか?
編集:明確にしたいと思います。
使うとき
git rm --cached myfile
ローカルファイルシステムからは削除されません。これが目的です。ただし、ファイルのバージョン管理とコミットを既に行っており、それを中央リポジトリにプッシュし、コマンドを使用する前に別のリポジトリにプルした場合は、そのシステムからファイルが削除されます。
ファイルシステムから削除せずに、バージョン管理からファイルを削除する方法はありますか?
編集:明確にしたいと思います。
回答:
私は、Gitコミットが「このファイルの追跡を停止するが、削除しない」などの意図を記録できるとは思わない。
このような意図を実現するには、ファイルを削除するコミットをマージ(またはリベース)するリポジトリーのGitの外部での介入が必要になります。
おそらく、最も簡単な方法は、ダウンストリームユーザーにファイルのコピーを保存し、削除をプルしてからファイルを復元するように指示することです。それらがリベースを介してプルしていて、ファイルに「変更」を行っている場合、競合が発生します。このような競合を解決するには、git rm foo.conf && git rebase --continue
(競合するコミットに削除されたファイル以外の変更があるgit rebase --skip
場合)または(競合するコミットが削除されたファイルにのみ変更された場合)を使用します。
彼らがすでに削除コミットをプルしている場合でも、git showを使用して以前のバージョンのファイルを復元できます。
git show @{1}:foo.conf >foo.conf
または、git checkoutを使用します(William Pursellによるコメントごと。ただし、インデックスから削除してください)。
git checkout @{1} -- foo.conf && git rm --cached foo.conf
削除をプルした後(または、リベースでデタッチされたHEADにプルしている場合)に他のアクションを実行した場合は、以外のものが必要になる場合があります@{1}
。彼らはgit log -g
あなたが削除をプルする直前にコミットを見つけるために使うことができます。
コメントで、「追跡を解除しますが、保持したい」ファイルは、ソフトウェアを実行するために必要なある種の構成ファイルです(リポジトリから直接)。
リポジトリ内の構成ファイルのコンテンツを維持し続けることが完全に許容できない場合は、追跡されたファイルの名前を(たとえば)foo.conf
からに変更し、名前変更コミットを適用foo.conf.default
したcp foo.conf.default foo.conf
後にユーザーに指示することができます。または、ユーザーがすでにリポジトリの既存の一部(たとえば、スクリプト(Makefile
またはリポジトリのコンテンツによって構成された他のプログラム)など)を使用してソフトウェアを起動/展開する場合、起動メカニズムにデフォルトのメカニズムを組み込むことができます。展開プロセス:
test -f foo.conf || test -f foo.conf.default &&
cp foo.conf.default foo.conf
このようなデフォルトのメカニズムを使用すると、ユーザーは、追加の作業を行うことなく、名前foo.conf
を変更するコミットをプルできるはずfoo.conf.default
です。また、将来追加のインストール/リポジトリを作成する場合、構成ファイルを手動でコピーする必要がなくなります。
リポジトリのコンテンツを維持することが許容できない場合は、のようなものを使用して、履歴から完全に根絶する必要がありますgit filter-branch --index-filter …
。これは履歴の書き換えに相当し、ブランチ/リポジトリごとに手動での介入が必要になります(git rebaseマンページの「アップストリームRebaseからの復旧」セクションを参照)。構成ファイルに必要な特別な処理は、書き換えから回復するときに実行する必要があるもう1つの手順です。
どの方法を使用する場合でも.gitignore
、リポジトリのファイルに構成ファイル名を含めて、誰かがうっかり間違ってgit add foo.conf
(これは可能ですが-f
/ が必要になる--force
)ことがないようにします。複数の構成ファイルがある場合は、それらをすべて1つのディレクトリに「移動」し、すべてを無視することを検討する場合があります(「移動」とは、プログラムが構成ファイルを検索する場所を変更し、ユーザー(または起動/展開メカニズム)を使用して、ファイルを新しい場所にコピー/移動します。無視するディレクトリにファイルをgit mvしたくないことは明らかです)。
--{,no-}assume-unchanged
は純粋にローカルです。その状態はコミットに直接記録されません。これは、リポジトリがファイルに新しい変更をコミットするのを防ぐのに役立ちますが、バージョン管理からは削除されません。すべてのあなたの関連、関連、非裸のリポジトリのためにそれを設定することができれば、それはあなたの状況を助けるかもしれないが、あなたができることを何かではありません、直接(他の関連する、非裸のリポジトリに、特にもののことを+プル/リベースを押します質問に対する元の質問者の明確なコメントに従って、あなたは制御しません:「人のシステム」/「外国のシステム」を参照してください)。
I do not think a Git commit can record an intention like “stop tracking this file, but do not delete it”.
-できるようになりましたgit rm --cached foo.conf
今週私が誤ってコミットしたときと同じ問題があり、共有リポジトリからビルドファイルを削除しようとしましたが、これは次のとおりです。
http://gitready.com/intermediate/2009/02/18/temporarily-ignoring-files.html
私にとってはうまくいき、今のところ言及していません。
git update-index --assume-unchanged <file>
必要なファイルをバージョン管理から削除するには、通常どおり他のすべてのコマンドを使用します。
git update-index --no-assume-unchanged <file>
元に戻したい場合。
編集:Chris JohnsenとKPMからのコメントを参照してください。これはローカルでのみ機能し、他のユーザーもファイルをバージョン管理しない限り、ファイルはバージョン管理されたままになります。受け入れられた答えはこれに対処するためのより完全な/正しい方法を提供します。また、この方法を使用する場合のリンクからのメモ:
明らかに、これに関係するかなりの数の警告があります。gitでファイルを直接追加すると、インデックスに追加されます。このフラグをオンにしてコミットをマージすると、マージが正常に失敗するため、手動で処理できます。
インデックスからファイルを削除するには、次を使用します。
git reset myfile
これはローカルコピーや他の人のコピーには影響しません。
reset
ファイルが現在のHEADコミットにない場合にのみ、インデックスからファイルを削除します。それ以外の場合は、インデックスバージョンを現在のHEADバージョンに戻します。
git rm --cached remove_file
git add .gitignore
git commit -m "Excluding"
上記のソリューションは、ほとんどの場合問題なく機能します。ただし、そのファイルのすべてのトレース(つまり、パスワードなどの機密データ)も削除する必要がある場合は、ファイルをまだそこから取得できるため、コミット履歴全体からも削除する必要があります。
以下は、ファイルが存在しなかったかのように、コミット履歴全体からファイルのすべてのトレースを削除し、ファイルをシステムの適切な場所に保持するソリューションです。
https://help.github.com/articles/remove-sensitive-data/
ローカルのgitリポジトリを使用していて、予行演習を実行する必要がない場合は、実際にステップ3にスキップできます。私の場合、すでに.gitignoreファイルを作成していて、作業したいリポジトリにあったため、手順3と6だけが必要でした。
変更を確認するには、リポジトリのGitHubルートに移動してページを更新する必要がある場合があります。次に、リンクをナビゲートして、以前にファイルがあった古いコミットに移動し、ファイルが削除されたことを確認します。私にとって、古いコミットページを更新するだけでは変更は表示されませんでした。
最初は威圧的に見えましたが、本当に簡単で、魅力のように機能しました。:-)