Git Mv и только изменить регистр каталога


259

Хотя я нашел похожий вопрос, я не нашел ответа на свою проблему

Когда я пытаюсь переименовать каталог из FOO в Foo через git mv FOO fooя получаю

fatal: renaming 'FOO' failed: Invalid argument

ХОРОШО. Так что я стараюсьgit mv FOO foo2 && git mv foo2 foo

Но когда я пытаюсь совершить через, git commit .я получаю

# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
# foo
nothing added to commit but untracked files present (use "git add" to track)

Когда я добавляю каталог через git add fooничего не меняется и git commit .снова выдает мне то же сообщение.

Что я делаю не так? Я думал, что использую систему с учетом регистра (OSX), почему я не могу просто переименовать каталог?


10
Файловая система OS X не чувствительна к регистру.
Мипади

2
@mipadi Может работать в чувствительном к регистру режиме, но обычно по умолчанию отключено.
ГордонМ

1
Этот вопрос и его ответы также полезны в Windows. Подумайте о том, чтобы пометить «osx»
Баретт

1
См. Stackoverflow.com/a/24979063/6309 : начиная с git 2.0.1, все работает просто git mv.
VonC

На Windows вы можете использовать обычный, git mv foo Fooесли вы используете оболочку Cygwin.
Эндрю Скотт

Ответы:


410

Вы находитесь в нечувствительной среде. Кроме того, добавление без -Aне позаботится об удалении, mvкак Git это понимает. Предупреждение! Убедитесь, что никаких других изменений или неотслеживаемых файлов нет, когда вы это сделаете, иначе они будут зафиксированы как часть этого изменения! git stash -uсначала сделай это, а потом git stash popуже. Продолжение: Чтобы обойти это, сделайте следующее:

mv foo foo2
git add -A
git commit -m "renaming"
mv foo2 FOO
git add -A
git commit --amend -m "renamed foo to FOO"

Это протяженный способ изменения рабочего каталога, фиксации, а затем свертывания двух коммитов. Вы можете просто переместить файл в индексе, но для кого-то, кто новичок в git, это может быть недостаточно ясно, что происходит. Более короткая версия

git mv foo foo2
git mv foo2 FOO
git commit -m "changed case of dir"

Как предложено в одном из комментариев, вы также можете сделать интерактивную перебазировку ( git rebase -i HEAD~5если 5 коммитов назад был введен неправильный случай), чтобы исправить случай и избежать появления неправильного случая вообще в истории. Вам следует быть осторожным, если вы сделаете это, поскольку хэши коммитов с этого момента будут другими, а другим придется перебазировать или заново объединить свою работу с недавним прошлым ветви.

Это связано с исправлением имени файла: git не чувствителен к регистру?


1
Спасибо. Это сводило меня с ума. Я не знал о параметре -A или --amend.
Ощренк

7
Осторожнее с -A, так как он будет рекурсивно добавлять весь контент в вашем текущем каталоге, включая неотслеживаемые. Может быть, лучше просто git add foo2.
rich.e 22.12.12

2
Это верно. Однако вам нужно будет поэтапно удалить как foo2, так и добавить FOO отдельно. -Aзаботится о обоих. Наоборот для первого шага. Я добавлю предупреждение. Спасибо!
Адам Димитрук

Вы также можете очистить свою историю с помощью интерактивной перебазировки git rebase -i HEAD~2. Примечание. Чтобы упростить это, установите последнее сообщение в первом коммите и исправьте второе.
Алекс Б.

5
У меня был успех с git mv foo foo2; git mv foo2 FOO; git commit
Крис

146

Вы хотите установить опцию core.ignorecaseв false, что заставит Git обращать внимание на регистр в файловых системах, которые изначально не поддерживают его. Чтобы включить в своем репо:

$ git config core.ignorecase false

Затем вы можете переименовать файл, git mvи он будет работать как положено.


1
Я думаю, что это может иметь нежелательные последствия в других местах. Системы, нечувствительные к регистру, должны позволить Git думать, что это тот же каталог.
Адам Димитрук

2
Я добавил опцию в свой глобальный конфиг, но это не помогло
oschrenk

3
Я вижу странное поведение, используя это с OSX. хрм I modified a file that doesn't exist... хм, error: The following untracked working tree files would be overwritten by checkout:но ... эти файлы не существуют.
Skylar Saveland

Это было именно то, что я искал. Я использую CentOS 5.6, и он не подхватил изменение дела.
crmpicco

5
Это не работает! На Git 1.8.3, Git будет обрабатывать переименованный файл как новый файл, вместо удаления + добавления. В результате такого хранения в хранилище останется два одинаковых файла, например, foo и FOO оба существуют! Но при оформлении заказа появляется только один файл (но один случай может преобладать над другим)
Джонни Вонг

68

Я смог решить эту проблему, используя git 1.7.7, используя временное имя файла:

$ git mv improper_Case improve_case2
$ git mv improve_case2 improve_case
$ git commit -m "<your message>"

Интересный. Может быть, GIT улучшил что-то с тех пор. Когда я снова наткнусь на эту проблему, я попробую это снова.
Ощренк

гораздо проще сделать это таким образом
Олора

Работал для меня на macOS.
Mr_Pouet

14

(без git mvварианта)

Я столкнулся с этой проблемой в Git на Mac OS X 10.9. Я решил это следующим образом:

git rm -r --cached /path/to/directory

Это устанавливает каталог для удаления в Git, но фактически не удаляет физические файлы ( --cached). Это также делает каталог, теперь с правильным регистром, показанным в неотслеживаемых файлах.

Так что вы можете сделать это:

mv /path/to/directory /path/to/DIRECTORY
git add -A /path/to/DIRECTORY

Git распознает, что вы переименовали файлы, и когда вы это сделаете, git statusвы увидите несколько renamed:строк. Осмотрите их и убедитесь, что они выглядят правильно, и если это так, вы можете зафиксировать изменения в обычном режиме.


Я обнаружил, что mvкоманда не работает, чтобы фактически переименовать каталог; Я должен был переименовать его в Finder. Помимо этого это исправление работает отлично.
Адам С.

9

Это быстрое и безопасное решение:

git mv -f path/to/foo/* path/to/FOO/

Предупреждение! Всегда переименовывайте все файлы в переименованной папке (используйте /*).

Не переименовывайте отдельные файлы. Это приводит к ошибке, описанной в этом ответе .

Если вы сначала хотите увидеть результат, используйте -n:

git mv -f -n path/to/foo/* path/to/FOO/

После того как вы сделали mv:

  1. Зафиксируйте изменения
  2. Оформить заказ на любую другую ревизию
  3. Оформить заказ обратно.

Теперь Git должен был переименовать папку ОБА во внутренних файлах и в файловой системе.


Это только для Git 2.0.1, как я упоминал в комментариях к вопросу выше? (имеется в виду stackoverflow.com/a/24979063/6309 )
VonC

8

Принудительно с опцией -f:

git mv -f FOO foo

Не работа для меня. Моя настройка: .git / config "ignorecase = true". Таким образом, переименование не может быть организовано в области подготовки. (Git version 1.8.3.msysgit.0) Решение Адама Димитрука - единственный правильный ответ.
Джонни Вонг

@JohnnyWong измените настройку на false, это сработало для меня
Inder Kumar Rathore

Будет ли это обновляться на всех компьютерах других пользователей, если они будут работать, даже если их компьютер настроен на игнорирование регистра?
Брайс

@ Брайс Нет, вам нужно будет зафиксировать изменения и отправить их в центральный репозиторий, прежде чем другие пользователи смогут получить изменения.
Коняк

3

У меня была одна связанная проблема.

Одна папка с именем «Pro» (созданная первой) и другая «pro» (созданная по ошибке). В Mac это одно и то же, но в зависимости от git.

$ git config core.ignorecase false

Конфигурация git переименовывает файлы в нужную папку (спасибо), а также создает файлы-призраки в 'pro' (Нет !!). Я не мог добавить изменения файла-призрака на дорожку, и я не мог извлекать другие ветки, если только не носить эти файлы со мной, и я также не мог каким-то образом сбросить их.

Вместо этого я сделал

$ git rm -r --cached pro
$ git status // => pro files removed, new Pro files untracked
$ git add Pro

Чтобы сделать его более безопасным, я сделал это в отдельной ветке исправлений, а затем слился с основной веткой

Может ли какой-нибудь гуру объяснить, как и почему? Заранее спасибо.


2

Вы не используете чувствительную к регистру файловую систему в OS X, если вы явно не выберете такую. HFS + может быть чувствительным к регистру, но по умолчанию регистр не учитывается.


4
Использование чувствительной к регистру файловой системы в OS X не очень хорошая идея. Многие приложения работают неправильно, я научился пробовать это. Одна конкретная проблема заключается в том, что Adobe Photoshop откажется от установки, заявив, что файловая система с учетом регистра не поддерживается.
jpswain

1

Вот действительно простое решение для всего gitfoo на этой странице.

  1. Скопируйте файлы из вашего проекта вручную.
  2. git rm все файлы.
  3. мерзавец, как обычно.
  4. добавьте файлы обратно вручную.
  5. Git добавить все файлы.
  6. мерзавец, как обычно.
  7. прибыль.

1
Это работает локально, но если кто-то другой сделает тягу, это не изменит их дела.
Джейсон

Спасибо за это, помогая мне исправить двойные записи в git в разных случаях. Я использовал вариант этого. Просто переименовал родительскую папку. Сделал коммит. Затем переименуйте родительскую папку обратно в оригинальную. И сделал второй коммит. Теперь старые записи с другим регистром исчезли.
dreamerkumar

0

Улучшая ответ Адама Димитрука (глупо, что ТАК не позволяет мне комментировать его ответ), использование «git mv» автоматически ставит точно перемещенные файлы. Нет необходимости в скрытии, и можно избежать рискованного «git add -A»:

old="abc";    new="ABC";
tmp="$old-renamed";
git mv "$old" "$tmp";
git commit -m "Renamed '$old' to '$tmp'.";
git mv "$tmp" "$new";
git commit --amend -m "Renamed '$old' to '$new'.";

0

Это отлично сработало для меня на Windows. Используется powershell со следующим:

  1. mv .\Folder-With-Wrong-Casing .\temp
  2. git add -A
  3. git commit -m "renamed folder with wrong casing to temp"
  4. mv .\temp .\Folder-with-Correct-Casing
  5. git add -A
  6. git commit --amend -m "Renamed to proper casing"
  7. (по желанию) git push

Благодаря ответу Адама выше.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.