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 не відрізняється від регістру.
mipadi

2
@mipadi Він може працювати в режимі, залежно від регістру, але це зазвичай вимкнено за замовчуванням.
GordonM

1
Це питання та його відповіді корисні і в Windows. Розгляньте розблокування "osx"
Barett

1
Дивіться stackoverflow.com/a/24979063/6309 : оскільки git 2.0.1, простий git mvтвір.
VonC

У Windows ви можете використовувати звичайний, git mv foo Fooякщо ви використовуєте оболонку cygwin.
Ендрю Скотт

Відповіді:


409

Ви знаходитесь у випадку нечутливого до випадку. Далі, додаючи з поза -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"

Ось накреслений спосіб зміни робочого каталогу, здійснення та згортання 2-х комітів. Ви можете просто перемістити файл в індексі, але для когось, що є новим у 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.
oschrenk

7
Будьте обережні з -A, оскільки він буде рекурсивно додавати весь вміст у поточний каталог, включаючи неактивні матеріали. Можливо, краще просто git add foo2.
багатий.e

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

Ви також можете очистити свою історію за допомогою інтерактивної бази даних git rebase -i HEAD~2. Примітка. Щоб спростити це, встановіть підсумкове повідомлення в першому фіксації та виправте друге.
Алекс Б.

5
Я мав успіх з git mv foo foo2; git mv foo2 FOO; git commit
Кріс

146

Ви хочете встановити параметр core.ignorecasefalse, що змусить Git звертати увагу на регістр файлових систем, які не підтримують його. Щоб увімкнути репортаж:

$ git config core.ignorecase false

Тоді ви можете перейменувати файл, git mvі він буде працювати, як очікувалося.


1
Я думаю, це може мати небажані ефекти в інших місцях. Системи, нечутливі до справи, повинні дозволити Git думати, що це той самий реж.
Адам Дімітрук

2
Я додав варіант до моєї глобальної конфігурації, але це не допомогло
oschrenk

3
Я бачу якусь дивну поведінку, використовуючи це з OSX. hrm I modified a file that doesn't exist.. hrm, 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 з тих пір щось покращив. Коли я знову наткнуся на цю проблему, я спробую це ще раз.
oschrenk

набагато простіше це зробити так
olore

Працював для мене на 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. Крім цього, це виправлення працює чудово.
Адам S

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 повинен був перейменувати папку BOTH у своїх внутрішніх файлах та у файловій системі.


Це лише для Git 2.0.1, як я вже згадував у коментарях до питання вище? ( Зі посиланням на stackoverflow.com/a/24979063/6309 )
VonC

8

Примушуйте його за допомогою -f:

git mv -f FOO foo

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

@JohnnyWong змінити налаштування на false, це працювало на мене
Inder Kumar Rathore

Чи буде це оновлення на всіх комп’ютерах інших користувачів, якщо вони перетягуються, навіть якщо їх комп'ютер налаштований на ігнорування випадку?
Брайс

@Bryce Ні, вам потрібно буде здійснити зміни та переслати їх до центрального репо, перш ніж інші користувачі зможуть змінити зміни.
konyak

3

У мене було одне пов'язане питання.

Одна папка під назвою "Pro" (створена першою) та інша "pro" (створена помилково). У Mac це одне і те ж, але по-різному відповідно до git.

$ git config core.ignorecase false

git config перейменовує файли у праву папку (спасибі), а також створює файли-привиди у «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. git фіксують як нормально.
  4. додайте файли назад вручну.
  5. git додати всі файли.
  6. git фіксують як нормально.
  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. Використовується панель повноважень із наступним:

  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.