Дублированный файл с разным случаем в git origin (битбакет)

Я пытаюсь переименовать файлы из foobar.php в FooBar.php, что довольно сложно в Git. До сих пор я выяснил, что мне нужно было установить значение git конфигурации ignorecase на false (почему в Mac OS X было установлено значение true?). Мне удалось успешно переименовать эти файлы в моем локальном репозитории, но после того, как я подтолкнул его к BitBucket, у меня есть FooBar.php, а также FooBar.php. Как избавиться от этих дубликатов? Спасибо.

Ответ 1

Нечувствительность к регистру, сохраняющая регистр

Вероятно, проблема заключается в том, что файловая система по умолчанию на маке нечувствительна к регистру, но сохраняет регистр; в этом случае невозможно существование в file.php и file.php одновременно - они считаются одним и тем же файлом.

Это легко продемонстрировать:

$ cd /tmp
$ mkdir example
$ cd example/
$ git init
Initialized empty Git repository in /private/tmp/so/.git/ 
$ touch readme
$ git add readme 
$ git commit -m "adding readme"
[master (root-commit) 05fdf7d] adding readme
 0 files changed
 create mode 100644 readme
$ mv readme x
$ git status 
# On branch master
# Changes not staged for commit:
#   (use "git add/rm <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#  deleted:    readme
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       x
no changes added to commit (use "git add" and/or "git commit -a")
$ mv x README
$ git status 
# On branch master
nothing to commit (working directory clean)
$ ls -l
total 0
-rw-r--r--  1 andy  wheel  0 Aug  1 19:38 README

В приведенном выше файле теперь называется README, но согласно git файл README существует и не изменен.

Используйте две коммиты

Поэтому вместо того, чтобы переименовывать файл (который нечувствителен к регистру без проблем), сделайте это как два шага:

$ mv file.php /tmp
$ git rm file.php
$ git commit -m "deleting file"
$ git push

Убедитесь, что нежелательный файл удален из репозитория. Затем переместите файл в нужное место и добавьте его.

$ mv /tmp/file.php File.php
$ git add File.php
$ git commit -m "adding File"   

Ответ 2

Применяется к каталогам

Поскольку я боролся с этой проблемой на уровне каталогов (а не на уровне файлов), вот рецепт, примененный к папке (это было в Windows, git v2.9.2).

  • Bitbucket будет показывать две подпапки, скажем Foobar и FooBar, с разными файлами/папками под ними.
  • В клиенте core.ignorecase было установлено значение true и оба дерева файлов, объединенные в один под общим корнем, скажем, Foobar.
    • Пока не устанавливайте значение core.ignorecase в false, так как оно будет внезапно покидать вас с помощью "необработанных" файлов с другого пути!
  • git mv Foobar Foobar.tmp - вы получите набор переименованных файлов, а также набор удаленных файлов и их соответствующих невосстановленных из другого пути.
  • git add . - скомпилируйте все файлы, удаленные/не проверенные.
    • Это сработало нормально для меня. Хотя они появляются как удаления/дополнения, история этих файлов не теряется (магически).
  • git commit -m"syncing Foo[Bb]ar into temp. folder" - Зафиксировать темп. папка.
  • git mv Foobar.tmp FooBar - Теперь переименуем из temp. к желаемому имени.
  • git commit -m"moving FooBar into place" - Зафиксировать имя цели.
  • git push - Теперь Bitbucket должен показать один подкаталог FooBar.
  • git config [--global] core.ignorecase false - Никогда не натыкайтесь на эту проблему снова.

Ответ 3

Клонирование/проверка в файловой системе, чувствительной к регистру (в Mac OS X вы можете просто сделать образ диска с учетом регистра), а затем git rm файл с нужной капитализацией.

Что касается того, почему ignorecase было установлено значение true, документация говорит:

core.ignorecase
           Значение по умолчанию - false, кроме git-clone(1) или git-init(1) будет проверяться и устанавливаться            core.ignorecase true, если это необходимо, когда создается репозиторий.

Так как ваш Mac, вероятно, имеет файловую систему без учета регистра (она по умолчанию), git заметила бы это и правильно установила флаг.