Git по этому поводу шизофреничен. 1 Части Git чувствительны к , поэтому ветвь HELLO
и ветвь hello
разные ветки,Другие части Git в Windows и MacOS в любом случае чувствительны к регистру в , так что ветвь HELLO
и ветвь hello
совпадают с ветвью.
Результатом является путаница.Эту ситуацию лучше всего просто полностью избежать.
Чтобы исправить проблему:
Задайте дополнительные , частные и временные, имя ветви или тега (s) что вас не смущает запоминание любых хеш-идентификаторов коммитов, которые вас действительно волнуют, в вашем локальном репозитории.Затем запустите git pack-refs --all
, чтобы все ваши ссылки были упакованы.Это удаляет все имена файлов , помещая все ваши ссылки в плоский файл .git/packed-refs
, где их имена чувствительны к регистру.Теперь ваш Git может отличить ваш Abc
от вашего abc
, если у вас есть оба.
Теперь, когда ваш репозиторий не запутан, удалите любые плохие имена веток.Ваши временные имена содержат значения, которые вы хотите запомнить.Вы можете удалить оба abc
и Abc
, если один или оба могут быть испорчены.Ваш remember-abc
содержит правильный хэш.
Перейдите на сервер Linux, на котором есть ветви, отличающиеся только вашим регистром.(Это всегда Linux-машина; эта проблема никогда не возникает на серверах Windows или MacOS, потому что они выполняют свертывание регистраций настолько рано, что вы никогда не создаете проблему в первую очередь.) Там переименуйте или удалите оскорбительного пользователяплохие имена.
У машины Linux нет проблем с регистром - ветви, имена которых отличаются только регистром, всегда разные - поэтому здесь нет ничего странного.Это может занять несколько шагов и несколько команд git branch
, чтобы перечислить все имена, но в конечном итоге у вас не останется ничего, кроме четких и отличных имен: не будет ветвей с именами Abc
и abc
оба.
Если на сервере Linux таких проблем нет, выполните шаг 2 «ничего не делать».
Используйте git fetch --prune
в локальной системе.Теперь у вас больше нет плохих имен в качестве имен для удаленного отслеживания, потому что на шаге 2 вы убедились, что сервер - система, которую ваш локальный Git называет origin
- не имеет плохих имен, и ваш локальный Git сделал ваш локальный origin/*
имена соответствуют их именам ветвей.
Теперь заново создайте любые имена веток, которые вы хотите локально, и / или переименуйте временные имена, которые вы сделали на шаге 1. Например, если вы сделали remember-abc
чтобы запомнить abc
, вы можете просто запустить git branch -m remember-abc abc
до и переместить remember-abc
в abc
.
Если abc
должен иметь origin/abc
в качестве восходящего потока, сделайте это сейчас:
git branch --set-upstream-to=origin/abc abc
(Вы можете сделать это на шаге 1, когда создаете remember-abc
, но я думаю, что это имеет больше смысла, поэтому я поместил его на шаг 4.)
Существуют различные сочетания клавиш, которые можно использовать вместо 4 шагов, описанных выше.Я перечислил все четыре способа для ясности цели: для вас должно быть очевидно, что каждый шаг предназначен для выполнения , и, если вы прочитаете остальную часть этого, почему вы делаетеэтот шаг.
Причина возникновения проблемы описана в nowox's answer : Git иногда сохраняет имя ветки в имени файла, а иногда сохраняет его в виде строки в файле данных.Поскольку Windows (и MacOS) склонны использовать сопоставление имен файлов, вариант имени файла сохраняет свой первоначальный регистр, но игнорирует попытки создать второй файл с другим именем варианта варианта, и тогда Git считает, что Abc
иabc
иначе одинаковы .Вариант data-in-a-file сохраняет различие в регистре, а также различие в значениях и считает, что Abc
и abc
- это две разные ветви, которые идентифицируют две разные фиксации.
Whru git rev-parse refs/heads/abc
или git rev-parse refs/remotes/origin/abc
получает информацию из .git/packed-refs
- файла данных, содержащего строки - он получает "правильную" информацию. Но когда он получает информацию из файловой системы, попытка открыть .git/refs/heads/abc
или .git/refs/remotes/origin/abc
фактически открывает .git/refs/heads/Abc
(если этот файл существует прямо сейчас) или вариант удаленного отслеживания с аналогичным названием (если этот файл существует) и Git получает «неправильную» информацию.
Установка core.ignorecase
(на что угодно) совсем не помогает, так как это влияет только на на то, как Git обрабатывает свертывание регистра в рабочем дереве . Файлы внутри внутренних баз данных Git никак не затрагиваются.
Вся эта проблема никогда бы не возникла, если бы, например, Git использовал реальную базу данных для хранения своей таблицы . Использование отдельных файлов прекрасно работает в Linux. Он не работает нормально на Windows и MacOS, так или иначе. Использование отдельных файлов может работать там , если Git не хранит их в файлах с читаемыми именами - например, вместо refs/heads/master
, возможно, Git может использовать файл с именем refs/heads/6d6173746572
хотя это вдвое сокращает доступную длину имени компонента. (Упражнение: как 0x6d m
, 0x61 a
и т. Д.?)
1 Технически, это неправильное слово. Это конечно описательно, хотя. Лучшее слово может быть шизоид , как оно используется в названии одного эпизода "Узник" , но оно также имеет неверное значение. Коренное слово здесь на самом деле раскол , означающее раскол и несколько противоположность, и вот к чему мы клоним.