Git -windows файлы, чувствительные к регистру, не обрабатываются должным образом
У нас есть git голый репозиторий в unix, у которого есть файлы с тем же именем, которые отличаются только в случаях.
Пример:
GRANT.sql
grant.sql
Когда мы клонируем голый репозиторий из unix в окно Windows, статус git определяет файл как измененный. Рабочее дерево загружается только с помощью grant.sql, но статус git сравнивает grant.sql и GRANT.sql и показывает файл, измененный в рабочем дереве.
Я пробовал использовать core.ignorecase false, но результат тот же.
Есть ли способ исправить эту проблему?
Ответы
Ответ 1
Windows не чувствительна к регистру (точнее, сохраняет регистр). Существует просто нет возможности для существования двух файлов, чьи имена различаются только в том случае: два имени файла, которые отличаются только в случае, имеют одинаковое имя файла. Период.
Итак, Git идет по репозиторию, проверяя один файл за другим, пока он не попадет в первый из двух проблемных файлов. Git проверяет его, затем идет дальше о своем бизнесе, пока он не попадет во второй файл. Опять же, Git проверяет его. Поскольку с точки зрения Windows, имя файла совпадает с первым, первый файл просто перезаписывается вторым. Что теперь делает Git считать, что первый файл был изменен, чтобы иметь тот же контент, что и второй.
Обратите внимание, что это не имеет ничего общего с Git: точно так же произойдет, если у вас есть tarball, zipfile или репозиторий Subversion.
Если вы хотите заниматься разработкой на нескольких разных платформах, вы должны соблюдать ограничения этих платформ, и вам нужно ограничиться самым низким общим знаменателем всех поддерживаемых вами платформ. Windows поддерживает ADS, Linux - нет. OSX поддерживает вилки ресурсов, Windows - нет. BSD поддерживает чувствительность к регистру, Windows - нет. Таким образом, вы не можете использовать ни одно из них. Это так, как есть.
core.ignorecase
не поможет вам здесь, потому что это касается совершенно противоположной проблемы.
Ответ 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.sql
и GRANT.sql
не относятся к клону Windows, вы можете добавить их имена в .git/info/sparse-checkout
, чтобы исключить эти файлы.
Ответ 3
Я не уверен, что это возможно. Git ignorecase обрабатывает несоответствия в случае одного файла. Это не будет работать в случае невозможности использования двух типов файлов в одном каталоге, которые отличаются только случаем.
FWIW, имеющий два одинаковых имени файла, но для их случая - действительно плохая идея, даже в Unix.
Ответ 4
Если вы хотите, чтобы ваш репозиторий был дружественным к файловым системам, отличным от случая, вы можете добавить крюк фиксации, который запрещает вам проверять конфликтующие файлы.
#!/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
Этот script требует git version >= 1.7.7, потому что он использует stash -u, чтобы избежать сбоев в файлах без следа.
Ответ 5
Cygwin обрабатывает чувствительность к регистру и забавные символы в именах файлов намного лучше, чем MSys.
Измените этот раздел реестра, чтобы включить чувствительность к регистру в Windows:
HKLM\System\CurrentControlSet\Control\Session Manager\Kernel\ObCaseInsensitive = 0
См. здесь для некоторых предостережений о том, как чувствительность к регистру поддерживается в Cygwin.
Ответ 6
Самый простой способ исправить проблему - переименовать один из файлов, чтобы они не конфликтуют с файловой системой, не зависящей от регистра, например Windows или OS X.
Следуя фиксации из системы Linux/Unix, где вы можете наиболее легко решить проблему, все будет хорошо в Windows после pull. Чтобы предотвратить возникновение этой проблемы, вам нужно добавить крючок фиксации, аналогичный предложенному djjeck.
Симптомы в Windows для этого очень запутывают и включают:
- Файлы, которые всегда отображаются как измененные, даже если вы их отменили, что очень затрудняет изменение ветвей или перезагрузка.
- Две копии файла с именами, отличающимися только в том случае, если оба отображают изменения в git gui
Поскольку оба файла не могут сосуществовать на платформе, нечувствительной к регистру, вы должны изменить одно из имен файлов, чтобы избежать проблем.