1. ホーム
  2. ギット

[解決済み] git status は変更を表示するが、git checkout -- <file> は変更を削除しない。

2022-04-01 06:01:40

質問

作業コピーの変更をすべて削除したいのですが、どうすればいいですか?

実行中 git status は、変更されたファイルを表示します。

何をやってもこれらの変更が削除されないようです。



rbellamy@PROMETHEUS /d/Development/rhino-etl (master)
$ git status
# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   Rhino.Etl.Core/Enumerables/CachingEnumerable.cs
#       modified:   Rhino.Etl.Core/Pipelines/SingleThreadedPipelineExecuter.cs
#       modified:   Rhino.Etl.Tests/Rhino.Etl.Tests.csproj
#       modified:   Rhino.Etl.Tests/SingleThreadedPipelineExecuterTest.cs
#
no changes added to commit (use "git add" and/or "git commit -a")

rbellamy@PROMETHEUS /d/Development/rhino-etl (master)
$ git checkout -- Rhino.Etl.Core/Enumerables/CachingEnumerable.cs

rbellamy@PROMETHEUS /d/Development/rhino-etl (master)
$ git status
# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   Rhino.Etl.Core/Enumerables/CachingEnumerable.cs
#       modified:   Rhino.Etl.Core/Pipelines/SingleThreadedPipelineExecuter.cs
#       modified:   Rhino.Etl.Tests/Rhino.Etl.Tests.csproj
#       modified:   Rhino.Etl.Tests/SingleThreadedPipelineExecuterTest.cs
#
no changes added to commit (use "git add" and/or "git commit -a")

rbellamy@PROMETHEUS /d/Development/rhino-etl (master)
$ git checkout `git ls-files -m`

rbellamy@PROMETHEUS /d/Development/rhino-etl (master)
$ git status
# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   Rhino.Etl.Core/Enumerables/CachingEnumerable.cs
#       modified:   Rhino.Etl.Core/Pipelines/SingleThreadedPipelineExecuter.cs
#       modified:   Rhino.Etl.Tests/Rhino.Etl.Tests.csproj
#       modified:   Rhino.Etl.Tests/SingleThreadedPipelineExecuterTest.cs
#
no changes added to commit (use "git add" and/or "git commit -a")

rbellamy@PROMETHEUS /d/Development/rhino-etl (master)
$ git reset --hard HEAD
HEAD is now at 6c857e7 boo libraries updated to 2.0.9.2 and rhino.dsl.dll updated.

rbellamy@PROMETHEUS /d/Development/rhino-etl (master)
$ git status
# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   Rhino.Etl.Core/Enumerables/CachingEnumerable.cs
#       modified:   Rhino.Etl.Core/Pipelines/SingleThreadedPipelineExecuter.cs
#       modified:   Rhino.Etl.Tests/Rhino.Etl.Tests.csproj
#       modified:   Rhino.Etl.Tests/SingleThreadedPipelineExecuterTest.cs
#
no changes added to commit (use "git add" and/or "git commit -a")

解決方法は?

このような動作が発生する原因は、複数あります。

行末の正規化

私もこの手の問題が発生したことがあります。それは、gitが自動的にcrlfをlfに変換してしまうことに起因しています。これは典型的な例で、一つのファイルの中で改行が混在している場合に起こります。インデックスでは正規化されているのに、git が作業ツリーのファイルと差分を取るために再度正規化し直すと、結果が違ってしまうのです。

しかし、これを解決したいのであれば、以下のように コア.autocrlf に変更し、すべての行末をlfに変更してから、再度有効にしてください。あるいは、こうすることで完全に無効化することもできます。

git config --global core.autocrlf false

の代わりに core.autocrlf を使用することもできます。 .gitattribute ファイルを作成します。こうすることで、そのリポジトリを使用するすべての人が同じ正規化規則を使用するようにでき、改行コードがリポジトリに混入するのを防ぐことができます。

また コア.safecrlf 非可逆的な正規化が行われる際に git に警告させたい場合は、warn に設定します。

ギットの マンページ はこう言っています。

CRLF変換は、わずかな確率で を使用すると、データが破損する可能性があります。 コミット時にCRLFをLFに変換し、コミット時に チェックアウト時にLFをCRLFに変更します。ファイル LFとCRLFが混在している場合 コミット前に再作成することはできません。 を使用します。テキストファイルの場合、これは 行を修正します。 のみとなるようにします。 の末尾がリポジトリに表示されます。しかし バイナリファイルが誤って テキストに分類されることがあります。 はデータを破損してしまいます。

大文字・小文字を区別しないファイルシステム

大文字小文字を区別しないファイルシステムでは、同じファイル名で大文字小文字を区別したものがリポジトリにある場合、git は両方をチェックアウトしようとしますが、ファイルシステム上に残るのは片方だけです。git が2つ目のファイルを比較しようとすると、間違ったファイルと比較してしまうのです。

解決策としては、大文字小文字を区別しないファイルシステムに変更するか、片方のファイルを別のファイルシステムにリネームしてコミットするかですが、ほとんどの場合、これは実行不可能です。