web-dev-qa-db-ja.com

Git-Windowsの大文字と小文字を区別するファイル名が適切に処理されない

UNIXには、大文字と小文字のみが異なる同じ名前のファイルを持つgitbareリポジトリがあります。

例:

GRANT.sql
grant.sql

UNIXからWindowsボックスにベアリポジトリのクローンを作成すると、gitstatusはファイルが変更されたことを検出します。作業ツリーにはgrant.sqlのみがロードされますが、git statusはgrant.sqlとGRANT.sqlを比較し、作業ツリーで変更されたファイルを表示します。

Core.ignorecase falseを使用してみましたが、結果は同じです。

この問題を修正する方法はありますか?

36
user298800

Windowsでは大文字と小文字が区別されません(より正確には、大文字と小文字が区別されます)。名前が大文字と小文字のみが異なる2つのファイルが存在する可能性はありません。大文字と小文字のみが異なる2つのファイル名は同じファイル名です。限目。

そのため、Gitはリポジトリをウォークアウトし、2つの問題のあるファイルの最初の1つに到達するまで、次々にファイルをチェックアウトします。 Gitはそれをチェックアウトし、2番目のファイルに到達するまでビジネスをさらに進めます。繰り返しますが、Gitはそれをチェックします。 Windowsの観点からは、ファイル名は最初のファイルと同じであるため、最初のファイルは単に2番目のファイルで上書きされます。これにより、Gitは、最初のファイルが2番目のファイルと同じ内容になるように変更されたと見なします。

これはGitとは何の関係もないことに注意してください。tarball、zipファイル、またはSubversionリポジトリがある場合もまったく同じことが起こります。

複数の異なるプラットフォームで開発を行う場合は、それらのプラットフォームの制限を尊重し、サポートするすべてのプラットフォームの最小公分母に限定する必要があります。 WindowsはADSをサポートしていますが、Linuxはサポートしていません。 OSXはリソースフォークをサポートしていますが、Windowsはサポートしていません。 BSDは大文字と小文字の区別をサポートしていますが、Windowsはサポートしていません。したがって、それらのいずれも使用できません。仕方ないよ。

core.ignorecaseは、ここでは役に立ちません。これは、反対の問題を正確に処理するためです。

41
Jörg W Mittag

同様の問題が発生しました。私の場合、大文字と小文字だけが異なる類似した名前の2つのファイルは、Windowsクローンに関係のないサブディレクトリにありました。 Git 1.7には スパースチェックアウト 機能があり、作業コピーから特定のファイルを除外できます。このディレクトリを除外するには:

git config core.sparsecheckout true
echo '*' >.git/info/sparse-checkout
echo '!unwanted_dir/' >>.git/info/sparse-checkout
git read-tree --reset -u HEAD

この後、unwanted_dir/サブディレクトリは作業コピーから完全に削除され、Gitは残りのファイルを通常どおり処理し続けます。

GRANT.sqlgrant.sqlがWindowsクローンに関連していない場合は、それらの名前を.git/info/sparse-checkoutに追加して、これらのファイルを具体的に除外できます。

33
Greg Hewgill

これが可能かどうかはわかりません。 Gitのignorecaseは、1つのファイルの場合の不一致を処理します。大文字と小文字だけが異なる2つのファイル名を1つのディレクトリに含めることができないというWindowの機能は回避できません。

FWIW、2つの同一のファイル名を持っていますが、それらの場合、Unix上でさえ本当に悪い考えです。

4
Marcelo Cantos

大文字と小文字を区別しないファイルシステムに対してリポジトリを使いやすくしたい場合は、競合するファイルをチェックインできないようにするコミットフックを追加できます。

#!/bin/bash

# Save current state
git stash -u -q --keep-index || exit 1

# Get the list of clashing files in the whole repository
CLASHING=`find "$(git rev-parse --show-toplevel)" | sort | uniq -d -i`

# Restore previous state
git stash pop -q

if [[ $CLASHING ]]; then
  echo "Found clashing files on case-insensitive file systems"
  echo "$CLASHING"
  exit 1
fi

exit 0

このスクリプトは、追跡されていないファイルでの失敗を回避するためにstash -uを使用するため、git version> = 1.7.7が必要です。

3
djjeck

Cygwinは、ファイル名の大文字と小文字の区別と面白い文字をMSysよりもはるかにうまく処理します。

このレジストリキーを変更して、Windowsで大文字と小文字を区別できるようにします。

HKLM\System\CurrentControlSet\Control\Session Manager\Kernel\ObCaseInsensitive = 0

Cygwinで大文字と小文字の区別がどのようにサポートされるかについてのいくつかの警告については、 ここ を参照してください。

1
gordy

この問題を実際に修正する最も簡単な方法は、ファイルの名前を変更して、WindowsやOSXなどの大文字と小文字を区別しないファイルシステムで競合しないようにすることです。

Linux/Unixシステムからのコミットに続いて、問題に最も簡単に対処できます。プルした後、Windowsではすべてが正常になります。この問題の発生を防ぐには、djjeckが提案したのと同様のコミットフックを追加する必要があります。

このためのWindowsの症状は非常に紛らわしく、次のようなものがあります。

  • 元に戻しても常に変更済みとして表示されるファイル。これにより、ブランチの変更やリベースが非常に困難になります。
  • 両方がgitguiの変更を示している場合にのみ、名前が異なるファイルの2つのコピー

大文字と小文字を区別しないプラットフォームでは両方のファイルを共存させることができないため、問題を回避するためにファイル名の1つを変更する必要があります。

1
Naylor