考えられる原因#1-行末の正規化
これが発生する可能性のある状況の1つは、問題のファイルが行末の正しい構成(1)なしでリポジトリにチェックインされ、その結果、ファイルがリポジトリ内に不正な行末または行末混合である場合です。確認するにgit diff
は、行末の変更のみが表示されることを確認します(これらはデフォルトでは表示されない場合があります。git diff | cat -v
改行をリテラル^M
文字として表示してみてください)。
その後、誰かがおそらく行末を正規化.gitattributes
するためにcore.autocrlf
設定を追加または変更しました(2)。.gitattributes
またはグローバル構成に基づいて、Gitはリクエストされた行末の正規化を適用するローカル変更を作業コピーに適用しました。残念ながら、何らかの理由でgit reset --hard
これらの行の正規化の変更は元に戻せません。
解決
ローカルの行末がリセットされる回避策は問題を解決しません。ファイルがgitによって「認識」されるたびに、正規化が再試行され、同じ問題が発生します。
最適なオプションは、リポジトリにあるすべての行末を正規化してに一致させる正規化をgitに適用させ.gitattributes
、それらの変更をコミットすることです-git filter-branchで行末を修正しようとしていますが、運がありません。
ファイルへの変更を手動で元に戻したい場合、最も簡単な解決策は、変更されたファイルを消去してgitにそれらを復元するように指示することですが、この解決策は一貫して100%機能しないようです時間(警告:変更したファイルに行末以外の変更がある場合は、これを実行しないでください!!):
git status --porcelain | grep "^ M" | cut -c4- | xargs rm
git checkout -- .
ある時点でリポジトリの行末を正規化しない限り、この問題が発生し続けることに注意してください。
考えられる原因#2-大文字と小文字の区別がない
2番目に考えられる原因は、WindowsまたはMac OS / Xでの大文字と小文字の区別です。たとえば、次のようなパスがリポジトリに存在するとします。
/foo/bar
Linuxの誰かがファイルを/foo/Bar
(おそらく、ビルドツールまたはそのディレクトリを作成した何かが原因で)コミットしてプッシュします。Linuxでは、これは実際には2つの別個のディレクトリです。
/foo/bar/fileA
/foo/Bar/fileA
WindowsまたはMacでこのリポジトリをチェックアウトすると、変更fileA
がリセットされない可能性があります。リセットのたびに、Windowsのgitがチェックアウトし/foo/bar/fileA
、Windowsは大文字と小文字を区別しないため、fileA
with の内容を上書きし/foo/Bar/fileA
、結果として「変更」されます。
別のケースは、リポジトリに存在する個々のファイルであり、大文字と小文字を区別しないファイルシステムでチェックアウトすると、重複します。例えば:
/foo/bar/fileA
/foo/bar/filea
このような問題を引き起こす可能性のある他の同様の状況がある可能性があります。
大文字小文字を区別しないファイルシステム上のgitのは本当にこのような状況を検出し、有用な警告メッセージを表示し、それが現在(これは将来変更される可能性-を参照していないはずです。この議論をしてgit.gitメーリングリストで提案したパッチを関連します)。
解決
解決策は、gitインデックスのファイルのケースとWindowsファイルシステムのケースを一致させることです。これは、実際の状態を表示するLinuxで実行するか、非常に便利なオープンソースユーティリティGit-Uniteを使用するWindowsで実行できます。Git-Uniteは必要なケースの変更をgitインデックスに適用し、リポジトリにコミットすることができます。
(1)これは.gitattributes
、問題のファイルの定義なしでWindows を使用し、デフォルトのグローバル設定を使用しcore.autocrlf
ているfalse
((2)を参照)誰かが行った可能性が高いです。
(2)http://adaptivepatchwork.com/2012/03/01/mind-the-end-of-your-line/
.
ルートディレクトリではなく、現在のディレクトリを示していることに注意してください