使用するとき
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マンページ )。構成ファイルに必要な特別な処理は、書き換えから回復するときに実行する必要がある別の手順にすぎません。
使用する方法が何であれ、リポジトリ内の.gitignore
ファイルに構成ファイル名を含めて、だれも誤ってgit add foo.conf
を再度できないようにすることができます(可能ですが、-f
/--force
が必要です)。複数の構成ファイルがある場合は、すべてを単一のディレクトリに「移動」し、全体を無視することを検討するかもしれません(「移動」とは、プログラムが構成ファイルを検索する場所を変更し、ユーザーを取得することを意味します(またはファイルを新しい場所にコピー/移動するための起動/展開メカニズム;明らかにgit mvファイルをディレクトリにあなたは無視されます)。
今週私が誤ってコミットしたときにまったく同じ問題があり、共有リポジトリからビルドファイルを削除しようとしましたが、これは次のとおりです。
http://gitready.com/intermediate/2009/02/18/temporarily-ignoring-files.html
私にとってはうまくいきましたが、今のところ言及されていません。
git update-index --assume-unchanged <file>
対象のファイルをバージョン管理から削除するには、他のすべてのコマンドを通常どおり使用します。
git update-index --no-assume-unchanged <file>
あなたがそれを元に戻したいと思ったなら。
編集:クリス・ジョンセンとKPMのコメントをご覧ください。これはローカルでのみ機能し、他のユーザーがそれを行わない場合、ファイルはバージョン管理下にあります。受け入れられた答えは、これに対処するためのより完全/正しい方法を提供します。また、この方法を使用する場合のリンクからのメモ:
明らかに、これにはいくつかの注意事項があります。 gitファイルを直接追加すると、インデックスに追加されます。このフラグをオンにしてコミットをマージすると、マージが正常に失敗するため、手動で処理できます。
インデックスからファイルを削除するには、次を使用します。
git reset myfile
これは、ローカルコピーまたは他のユーザーのコピーに影響を与えません。
git rm --cached
コマンドを実行した後、myfile
を.gitignore
ファイルに追加してみてください(存在しない場合は作成します)。これはgitにmyfile
を無視するよう指示する必要があります。
.gitignore
ファイルはバージョン管理されているため、コミットしてリモートリポジトリにプッシュする必要があります。
git rm --cached remove_file
git add .gitignore
git commit -m "Excluding"
私の解決策は、他の作業コピーを引き出してから実行することです:
git log --pretty="format:" --name-only -n1 | xargs git checkout HEAD^1
これは、最新のコメントですべてのファイルパスを取得し、HEADの親からチェックアウトすることを示しています。仕事完了。
上記のソリューションは、ほとんどの場合うまく機能します。ただし、そのファイルのすべてのトレース(パスワードなどの機密データ)も削除する必要がある場合は、コミット履歴全体からも削除する必要があります。ファイルはそこから取得される可能性があるためです。
これは、コミット履歴全体からファイルのすべてのトレースを削除するソリューションです。あたかも存在しないかのように、システム上のファイルを保持します。
https://help.github.com/articles/remove-sensitive-data/
ローカルgitリポジトリにいて、ドライランを実行する必要がない場合は、実際にステップ3にスキップできます。私の場合、既に.gitignoreファイルを作成しており、作業したいリポジトリにいたため、手順3と6のみが必要でした。
変更を確認するには、リポジトリのGitHubルートに移動してページを更新する必要があります。次に、リンクをナビゲートして、以前ファイルがあった古いコミットに移動し、現在削除されていることを確認します。私にとっては、単に古いコミットページを更新しても変更は表示されませんでした。
最初は威圧的に見えましたが、本当に簡単で、魅力のように機能しました! :-)