git
によって追跡されていたファイルがありますが、現在そのファイルは.gitignore
リストにあります。
しかし、そのファイルは編集後もgit status
に表示され続けます。どうしてgit
にそれを完全に忘れるように強制するのですか?
.gitignore
は、追跡されていないファイルが(add -f
を付けずに)gitによって追跡されているファイルのセットに追加されるのを防ぎます。
ファイルの追跡を停止するには、インデックスからファイルを削除する必要があります。これはこのコマンドで実現できます。
git rm --cached <file>
最新リビジョンからのファイルの削除は次のコミットで起こります。
警告:これはあなたのローカルから物理ファイルを削除しませんが、それは次のgit pull
に他の開発者のマシンからファイルを削除します。
以下の一連のコマンドはGitインデックスから(作業ディレクトリやローカルリポジトリからではなく)すべての項目を削除し、Gitが無視することを考慮しながらGitインデックスを更新します。 PS。インデックス=キャッシュ
最初:
git rm -r --cached .
git add .
そして:
git commit -am "Remove ignored files"
git update-index 私に代わって仕事をします。
git update-index --assume-unchanged <file>
注: gitignoreは追跡されていないファイルのみを対象としているため、この解決策は実際には.gitignore
から独立しています。
edit: この回答が投稿されてから、新しいオプションが作成されました。それを推奨します。--skip-worktree
を使用してください。これはユーザーがもうコミットしたくない変更追跡ファイル用であり、gitが大きな追跡ファイルの状況をチェックするのを防ぐために--assume-unchanged
をパフォーマンス用に維持するためです。詳しくは https://stackoverflow.com/a/13631525/717372 を参照してください...
git update-index --skip-worktree <file>
git ls-files --ignored --exclude-standard -z | xargs -0 git rm --cached
git commit -am "Remove ignored files"
これは無視されたファイルのリストを取り、それらをインデックスから削除し、そして変更をコミットします。
私はいつもこのコマンドを使って、追跡されていないファイルを削除します。 1行のUnixスタイルのきれいな出力
git ls-files --ignored --exclude-standard | sed 's/.*/"&"/' | xargs git rm -r --cached
無視されたすべてのファイルを一覧表示し、スペースを含むパスを処理する代わりにすべての出力行を引用符で囲み、インデックスからパス/ファイル/ディレクトリを削除するためにすべてをgit rm -r --cached
に渡します。
他の人が必要としているために追跡ファイルをgit rm
できない場合( you git rm --cached
であっても警告、他の誰かがこの変更を受けると、それらのファイルはファイルシステムから削除されます)これらは設定ファイルの上書き、認証資格情報などが原因でよく行われます。問題を回避する方法については https://Gist.github.com/1423106 をご覧ください。
要約する:
それを外に出し、コミットしてから元に戻すこれを達成するには、おそらく「もっと上手な」方法があるでしょう。
ソースリンク: http://www.codeblocq.com/2016/01/Untrack-files-already-added-to-git-repository-based-on-gitignore/ /
あなたがすでにあなたのgitリポジトリにいくつかのファイルを追加/コミットし、それからそれらをあなたの.gitignoreに追加したとしましょう。これらのファイルはまだリポジトリインデックスに存在します。この記事では、それらを取り除く方法を説明します。
先に進む前に、.gitignoreファイルを含め、すべての変更がコミットされていることを確認してください。
レポをクリアするには、次のようにします。
git rm -r --cached .
rm
コマンドは寛容でない場合があります。事前に試してみたい場合は、-n
または--dry-run
フラグを付けてテストしてください。
git add .
git commit -m ".gitignore fix"
あなたのリポジトリはきれいです:)
変更があなたのリモコンにも適用され、変更がそこでも有効であることを確認します。
(Linuxの場合)、ここでの投稿を使用してls-files --ignored --exclude-standard | xargs git rm -r --cached
アプローチを提案しました。ただし、削除されるファイル(の一部)の名前には改行/ LF/\n
が埋め込まれていました。どちらの解決策も:
git ls-files --ignored --exclude-standard | xargs -d"\n" git rm --cached
git ls-files --ignored --exclude-standard | sed 's/.*/"&"/' | xargs git rm -r --cached
この状況に対処します(見つからないファイルに関するエラーを受け取ります)。
git ls-files -z --ignored --exclude-standard | xargs -0 git rm -r --cached
これは、 ls-files への-z
引数、および xargs への-0
引数を使用して、ファイル名の "厄介な"文字を安全に/正しく処理することができます。
マニュアルページ git-ls-files(1) には、次のように記載されています。
-zオプションを使用しない場合、パス名のTAB、LF、およびバックスラッシュ文字は、それぞれ\ t、\ n、および\\として表されます。
そのため、ファイル名にこれらの文字が含まれている場合、私の解決策が必要だと思います。
編集:私はそれを追加するように頼まれました---他のgit rm
コマンドのように---これは削除を恒久的にするために commit が続かなければなりません。 git commit -am "Remove ignored files"
。
git filter-branch を使ってこれを実現しました。私が使用した正確なコマンドはmanページから取られました:
_ warning _ :これはあなたの全履歴からファイルを削除します
git filter-branch --index-filter 'git rm --cached --ignore-unmatch filename' HEAD
このコマンドはコミット履歴全体を再作成し、各コミットの前にgit rm
を実行し、指定されたファイルを取り除きます。コマンドを実行する前に必ずバックアップしてください。{willは失われます。
.gitignore
ファイルを更新します - たとえば、追跡したくないフォルダを.gitignore
に追加します。
git rm -r --cached .
- 必要なものと不要なものを含むすべての追跡ファイルを削除します。ローカルに保存している限り、あなたのコードは安全です。
git add .
- .gitignore
内のファイルを除いて、すべてのファイルが再度追加されます。
私たちを正しい方向に向けるために@AkiraYamamotoへのハットチップ。
私は、そのgitはその概念のためにファイルについて完全に忘れることができないと思います( 「スナップショット、違いはありません」 )。
たとえば、CVSを使用している場合は、この問題はありません。 CVSは情報をファイルベースの変更のリストとして保存します。 CVSのための情報はファイルのセットと時間の経過と共に各ファイルに加えられた変更です。
しかしGitでは、プロジェクトをコミットしたり、プロジェクトの状態を保存したりするたびに、基本的にその時点でのすべてのファイルの様子を描き、そのスナップショットへの参照を保存します。 。そのため、一度ファイルを追加した場合、そのスナップショットには常に存在します。
この2記事は私にとって役に立ちました:
git想定変更なし/ skip-worktree and Gitで追跡ファイルの変更を無視する方法
それに基づいて、ファイルが既に追跡されている場合、私は次のことを行います。
git update-index --skip-worktree <file>
これ以降、このファイル内のローカルの変更はすべて無視され、リモートには反映されません。ファイルがリモートで変更された場合、git pull
のときに競合が発生します。 Stashは機能しません。これを解決するには、安全な場所にファイルの内容をコピーしてくださいそして次の手順に従ってください。
git update-index --no-skip-worktree <file>
git stash
git pull
ファイルの内容はリモートの内容に置き換えられます。変更を安全な場所からファイルに貼り付けて再度実行します。
git update-index --skip-worktree <file>
プロジェクトを扱うすべての人がgit update-index --skip-worktree <file>
を実行するのであれば、pull
に関する問題はなくなるはずです。すべての開発者が独自のプロジェクト構成を持っている場合、この解決策は構成ファイルには問題ありません。
ファイルがリモートで変更されたときに毎回これを実行することはあまり便利ではありませんが、リモートコンテンツによる上書きからファイルを保護することはできます。
次の手順を順番に実行してください、大丈夫です。
1.誤って追加されたファイル をディレクトリ/ storage から削除します。 "rm -r"(Linux用)コマンドを使用するか、ディレクトリを参照してそれらを削除できます。または、それらをあなたのPC上の別の場所に移動させてください[ moving /取り外し ]の場合はIDEを閉じる必要があります。
2.ファイル/ディレクトリをgitignore
ファイルに追加して保存します。
3.now remove それらを git cacheから これらのコマンドを使用して(複数のディレクトリがある場合は、このコマンドを繰り返し発行してそれらを順次削除する)
git rm -r --cached path-to-those-files
4.now do a commitおよびPush これらのコマンドを使用します。これは これらのファイルをgit remote から削除し、git トラッキングを停止する とする。
git add .
git commit -m "removed unnecessary files from git"
git Push Origin
コピー/貼り付けの答えはgit rm --cached -r .; git add .; git status
です
このコマンドはすでにGitリポジトリにコミットされているファイルを無視しますが、それらを.gitignore
に追加しました。
Matt Fearからの回答が最も効果的な私見でした。以下は、Windowsのユーザーが除外リストに一致するファイルをgitリポジトリから削除するためのPowerShellスクリプトです。
# Get files matching exclusionsfrom .gitignore
# Excluding comments and empty lines
$ignoreFiles = gc .gitignore | ?{$_ -notmatch "#"} | ?{$_ -match "\S"} | % {
$ignore = "*" + $_ + "*"
(gci -r -i $ignore).FullName
}
$ignoreFiles = $ignoreFiles| ?{$_ -match "\S"}
# Remove each of these file from Git
$ignoreFiles | % { git rm $_}
git add .
ファイルを安全な場所に移動またはコピーして、紛失しないようにします。それからファイルをgit rmしてコミットします。以前のコミットのいずれか、または削除されていない別のブランチに戻ってもファイルは表示されます。ただし、今後のコミットでは、ファイルは二度と表示されなくなります。ファイルがgit ignore内にある場合は、そのファイルをフォルダに戻すと、gitはそれを認識しません。
BFG は、Gitリポジトリから大きなファイルやパスワードなどの不要なデータを削除するために特別に設計されているので、大きな履歴(現在のコミットではない)ファイルを削除する単純なフラグがあります。 : '--strip-blobs-bigger-than'
$ Java -jar bfg.jar --strip-blobs-bigger-than 100M
ファイルを名前で指定したい場合は、それもできます。
$ Java -jar bfg.jar --delete-files *.mp4
BFGはgit filter-branchよりも10〜1000倍速く、一般的にずっと使いやすくなっています。詳細については 完全な使用法の説明 と 例 を参照してください。
出典: https://confluence.atlassian.com/bitbucket/reduce-repository-size-321848262.html
CLIを使用したくなく、Windowsで作業している場合、非常に簡単な解決策は TortoiseGit を使用することです。
私はJonBraveの答えを気に入っていましたが、commit -aが私を少し怖がらせるための十分な作業ディレクトリが混乱しています。
git config - グローバルエイリアス.exclude-ignored '!git ls-files -z --ignored --exclude-standard | xargs -0 git rm -r - キャッシュ&git ls-files -z --ignored --exclude-standard | xargs -0 git stage && git stage .gitignore && git commit -m "新しいgitignoreと無視されたファイルのインデックスからの削除" '
それを分解する:
git ls-files -z --ignored --exclude-standard | xargs -0 git rm -r --cached
git ls-files -z --ignored --exclude-standard | xargs -0 git stage
git stage .gitignore
git commit -m "new gitignore and remove ignored files from index"
これは最新のgitでは問題になっていません (執筆時点のv2.17.1).
.gitignore
はついに追跡されたが削除されたファイルを無視します。次のスクリプトを実行して、これを自分でテストすることができます。最後のgit status
ステートメントは、「コミットするものがない」と報告します。
# Create empty repo
mkdir gitignore-test
cd gitignore-test
git init
# Create a file and commit it
echo "hello" > file
git add file
git commit -m initial
# Add the file to gitignore and commit
echo "file" > .gitignore
git add .gitignore
git commit -m gitignore
# Remove the file and commit
git rm file
git commit -m "removed file"
# Reintroduce the file and check status.
# .gitignore is now respected - status reports "nothing to commit".
echo "hello" > file
git status
特にIDEベースのファイルのために、私はこれを使います:
例えばslnx.sqlite、私はちょうどそれを以下のように完全に取り除きました:
git rm {PATH_OF_THE_FILE}/slnx.sqlite -f
git commit -m "remove slnx.sqlite"
これらのファイルの中には、プロジェクトのローカルユーザー設定や設定(開いているファイルなど)が保存されているものもあります。そのため、IDEをナビゲートまたは変更するたびにそのファイルは変更されるため、チェックアウトされてコミットされていない変更があることが示されます。
git rm --cached
コマンドを使用しても元の質問には答えません。
どうやって
git
に[ファイル]を完全に忘れるように強制するのですか?
実際、この解決法はgit pull
!を実行すると、リポジトリの他のすべてのインスタンスでファイルを deleted にします。
Gitにファイルについて忘れるように強制する正しい方法はGitHub here で文書化されています。
ドキュメントを読むことをお勧めしますが、基本的には:
git fetch --all
git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch full/path/to/file' --Prune-empty --tag-name-filter cat -- --all
git Push Origin --force --all
git Push Origin --force --tags
git for-each-ref --format='delete %(refname)' refs/original | git update-ref --stdin
git reflog expire --expire=now --all
git gc --Prune=now
full/path/to/file
をファイルのフルパスに置き換えてください。ファイルを.gitignore
に追加したことを確認してください。
また、(一時的に) あなたのリポジトリへの早送りでないプッシュを許可する必要があります あなたのgit履歴を変更しているので.
DS_Store
が既にコミットされている場合:
find . -name .DS_Store -print0 | xargs -0 git rm --ignore-unmatch
無視してください。
echo ".DS_Store" >> ~/.gitignore_global
echo "._.DS_Store" >> ~/.gitignore_global
echo "**/.DS_Store" >> ~/.gitignore_global
echo "**/._.DS_Store" >> ~/.gitignore_global
git config --global core.excludesfile ~/.gitignore_global
最後に、コミットしましょう。
このメソッドは、gitを完全に忘れます無視されたファイル(past/ present/future )、ただし、notは作業ディレクトリから何も削除しません(リモートから再プルされた場合でも)。
この方法では、
/.git/info/exclude
(推奨)またはapre-existing.gitignore
inall無視/忘れられるファイルがあるコミット。 1Gitを強制するすべての方法は、事後の動作を事実上無視し、履歴を効果的に書き換えます。したがって、このプロセスの後にプルされる可能性のあるパブリック/共有/コラボレーションリポジトリに対して significant ramifications があります。 2
一般的なアドバイス:きれいなレポジトリで開始-コミットされたすべて、作業ディレクトリまたはインデックスで保留中のものは何もない、バックアップ!
また、コメント/ リビジョン履歴 of this answer ( and revision history of this question )は有用/啓発的かもしれません。
#commit up-to-date .gitignore (if not already existing)
#this command must be run on each branch
git add .gitignore
git commit -m "Create .gitignore"
#apply standard git ignore behavior only to current index, not working directory (--cached)
#if this command returns nothing, ensure /.git/info/exclude AND/OR .gitignore exist
#this command must be run on each branch
git ls-files -z --ignored --exclude-standard | xargs -0 git rm --cached
#Commit to prevent working directory data loss!
#this commit will be automatically deleted by the --Prune-empty flag in the following command
#this command must be run on each branch
git commit -m "ignored index"
#Apply standard git ignore behavior RETROACTIVELY to all commits from all branches (--all)
#This step WILL delete ignored files from working directory UNLESS they have been dereferenced from the index by the commit above
#This step will also delete any "empty" commits. If deliberate "empty" commits should be kept, remove --Prune-empty and instead run git reset HEAD^ immediately after this command
git filter-branch --tree-filter 'git ls-files -z --ignored --exclude-standard | xargs -0 git rm -f --ignore-unmatch' --Prune-empty --tag-name-filter cat -- --all
#List all still-existing files that are now ignored properly
#if this command returns nothing, it's time to restore from backup and start over
#this command must be run on each branch
git ls-files --other --ignored --exclude-standard
最後に、残りの this GitHubガイド (手順6以降)に従います。これには、以下のコマンドに関する重要な警告/情報が含まれます。
git Push Origin --force --all
git Push Origin --force --tags
git for-each-ref --format="delete %(refname)" refs/original | git update-ref --stdin
git reflog expire --expire=now --all
git gc --Prune=now
変更されたリモートリポジトリからプルする他の開発者は、バックアップを作成してから、次の操作を行う必要があります。
#fetch modified remote
git fetch --all
#"Pull" changes WITHOUT deleting newly-ignored files from working directory
#This will overwrite local tracked files with remote - ensure any local modifications are backed-up/stashed
#Switching branches after this procedure WILL LOOSE all newly-gitignored files in working directory because they are no longer tracked when switching branches
git reset FETCH_HEAD
1 /.git/info/exclude
は上記の手順を使用してすべての履歴コミットに適用できるため、おそらく.gitignore
ファイル into を必要とする履歴コミットの取得に関する詳細この答えの範囲を超えています。ルートコミットに適切な.gitignore
が必要でした。あたかもそれが最初にしたように。 /.git/info/exclude
がコミット履歴のどこに存在するかに関係なく.gitignore
が同じことを達成でき、明確に履歴を書き換えることはveryramifications を認識している場合でも、微妙な件名。
FWIW、潜在的なメソッドには、 への回答のように、 external git rebase
を各コミットにコピーするgit filter-branch
または.gitignore
が含まれる場合がありますこの質問
2 スタンドアロンのgit rm --cached
コマンドの結果をコミットすることによりgit ignore behaviorを強制すると、将来的にファイルが無視される可能性がありますdeletion力で押したリモコンから引っ張ります。次の--Prune-empty
コマンドのgit filter-branch
フラグは、以前の「すべての無視されたファイルを削除」インデックスのみのコミットを自動的に削除することにより、この問題を回避します。 git履歴を書き換えると、コミットハッシュも変更されます。これは、public/shared/collaborativeリポジトリからの将来のプルで wreak havoc になります。そのようなレポに対してこれを行う前に、 ramifications を完全に理解してください。 このGitHubガイド は以下を指定します。
共同編集者に、 rebase 、 not merge、古い(汚染された)リポジトリ履歴から作成したブランチを伝えます。 1回のマージコミットで、パージの問題に陥った汚染された履歴の一部またはすべてを再導入できます。
リモートリポジトリに影響しない代替ソリューションは、git update-index --assume-unchanged </path/file>
またはgit update-index --skip-worktree <file>
で、その例は にありますhere 。