Имена файлов в Git-windows не обрабатываются должным образом - PullRequest
36 голосов
/ 27 марта 2010

У нас есть репозиторий git bare в unix, в котором есть файлы с одинаковыми именами, которые отличаются только случаями.

Пример:

GRANT.sql
grant.sql

Когда мы клонируем пустой репозиторий из unix в окно Windows, git status обнаруживает, что файл был изменен. Рабочее дерево загружается только с grant.sql, но git status сравнивает grant.sql и GRANT.sql и показывает файл, измененный в рабочем дереве.

Я попытался использовать значение core.ignorecase false, но результат тот же.

Есть ли способ исправить эту проблему?

Ответы [ 6 ]

41 голосов
/ 27 марта 2010

Windows нечувствительна к регистру (точнее, сохраняет регистр). Просто не существует способа существования двух файлов, имена которых отличаются только регистром: два имени файла, отличающиеся только регистром, являются одним и тем же именем. Период.

Итак, Git просматривает хранилище, проверяя один файл за другим, пока не найдет первый из двух проблемных файлов. Git проверяет это, затем идет дальше о своих делах, пока не найдет второй файл. Опять Git проверяет это. Поскольку с точки зрения Windows имя файла совпадает с первым, первый файл просто перезаписывается вторым. Что теперь заставляет Git думать, что первый файл был изменен, чтобы иметь то же содержимое, что и второй.

Обратите внимание, что это не имеет ничего общего с Git: то же самое произошло бы, если бы у вас был архив tar, zipfile или Subversion.

Если вы хотите заниматься разработкой для нескольких разных платформ, вы должны соблюдать ограничения этих платформ и ограничиваться наименьшим общим знаменателем из всех платформ, которые вы поддерживаете. Windows поддерживает ADS, Linux - нет. OSX поддерживает ветвления ресурсов, Windows - нет. BSD поддерживает чувствительность к регистру, Windows - нет. Таким образом, вы не можете использовать ни один из них. Так оно и есть.

core.ignorecase здесь вам не поможет, потому что это решает точно противоположную проблему.

33 голосов
/ 23 июля 2010

Я только что столкнулся с подобной проблемой. В моем случае два файла с похожими именами, отличающиеся только регистром, находились в подкаталоге, который не был релевантным для клона Windows. В Git 1.7 есть функция sparse checkout , которая позволяет исключать определенные файлы из рабочей копии. Чтобы исключить этот каталог:

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, чтобы исключить эти файлы специально.

4 голосов
/ 27 марта 2010

Я не уверен, что это даже возможно. Git ignorecase обрабатывает несоответствия в случае одного файла. Это не будет работать из-за невозможности Window иметь два имени файла в одном каталоге, которые отличаются только регистром.

FWIW, имея два одинаковых имени файла, но для их случая это действительно плохая идея, даже в Unix.

2 голосов
/ 02 января 2013

Если вы хотите, чтобы ваш репозиторий был дружественным к файловым системам, не чувствительным к регистру, вы можете добавить хук фиксации, который не позволит вам проверять конфликтующие файлы.

#!/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

Для этого сценария требуется версия git> = 1.7.7, поскольку он использует stash -u, чтобы избежать сбоя в неотслеживаемых файлах.

1 голос
/ 04 августа 2015

Самый простой способ решить проблему - переименовать один из файлов, чтобы они не конфликтовали в файловой системе без учета регистра, такой как Windows или OS X.

После коммита из системы Linux / Unix, где вы можете наиболее легко решить проблему, все будет хорошо в Windows после извлечения. Чтобы предотвратить возникновение этой проблемы, вам нужно добавить зацепку фиксации, аналогичную предложенной djjeck.

Симптомы на Windows для этого очень запутанны и включают:

  • Файлы, которые всегда отображаются как измененные, даже если вы отмените их, что затрудняет изменение веток или перебазирование.
  • Две копии файла с именами, отличающимися только в том случае, если обе версии показывают изменения в git gui

Поскольку оба файла не могут сосуществовать на нечувствительной к регистру платформе, вам необходимо изменить одно из имен файлов, чтобы избежать проблемы.

1 голос
/ 16 октября 2011

Cygwin обрабатывает чувствительность к регистру и смешные символы в именах файлов намного лучше, чем MSys.

Измените этот раздел реестра, чтобы включить чувствительность к регистру в Windows:

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

См. здесь для некоторых предостережений о том, как чувствительность к регистру поддерживается в Cygwin.

...