команда git для переміщення папки всередині іншої


194

Я створив папку commonз купою вихідних файлів і папок.

Тепер я хочу перемістити commonпапку в includeпапку, щоб вона виглядала такinclude/common

Я спробував такі:

  1. git add include

  2. git mv common/ include/

    але ця помилка не вдається

    фатальний: поганий джерело, джерело = myrepo / загальний, призначення = myrepo / включати

  3. Я намагався, git mv common/ include/commonале я отримую ту ж помилку

Будь-яка ідея, як цього досягти?

Відповіді:


177

Однією з найприємніших речей щодо git є те, що вам не потрібно чітко відстежувати перейменування файлів. Git визначить це, порівнявши вміст файлів.

Тож у вашому випадку не працюйте так сильно:

$ mkdir include
$ mv common include
$ git rm -r common
$ git add include/common

Біг git statusповинен показати вам щось подібне:

$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   renamed:    common/file.txt -> include/common/file.txt
#

44
Це не працює для мене (використовуючи Windows 7, 1.7.6.msysgit.0). Git вважає, що старі файли було видалено, а нові файли додано.
Барт

Хм, можливо, git використовує якусь зовнішню утиліту, щоб визначити, що однаковість файлів не працює в Windows? Це була основна частина реалізації git.
Андрес Яан Так

13
@OliverF. Корекція: git mvрівнозначна.
Андрес Яан Так

25
"Одна з найприємніших речей про git" - один із недоліків цієї приємної функції полягає в тому, що вона починає виходити з ладу, коли ви також змінюєте файл, який був перейменований у значній мірі, через що бачити видалення та додавання нового файлу , відверто кажучи, я б віддав перевагу явну підтримку перейменування.
Ерік Каплун

2
Якщо git перетворює закінчення рядків, це призводить до проблеми, описаної @Bart. Для цього вам потрібно зробити наступне: git config --global core.autocrlf false
Mariano Dupont

164
 git mv common include

повинен працювати.

Із git mvчоловічої сторінки :

git mv [-f] [-n] [-k] <source> ... <destination directory>

У другій формі останнім аргументом має бути існуючий каталог; дані джерела будуть переміщені в цей каталог .
Індекс оновлюється після успішного завершення, але зміна все ж має бути здійснена.

Ні " git add" не слід робити перед переміщенням.


Примітка: " git mv A B/", коли Bвона не існує як каталог, повинна помилитися, але вона не стала.

Див здійснюють c57f628 по Матьє (Moy moy) для Git 1.9 / 2.0 (Q1 2014 року):

Git використовується для обрізання косої косої риси і робить команду еквівалентною ' git mv file no-such-dir', яка створила файл no-such-dir(в той час як кінцевий косої риски прямо заявив, що це може бути лише каталог).

Цей патч пропускає видалення косої косої риски для шляху призначення.
Шлях з його останньою косою рисою передається для перейменування (2), яке помиляється з відповідним повідомленням:

$ git mv file no-such-dir/
fatal: renaming 'file' failed: Not a directory

2
Працювали чудово - і використання git mvвиглядає як набагато кращий підхід!
Томаш Петричек

23

Команда:

$ git mv oldFolderName newFolderName

Зазвичай це прекрасно працює.

Помилка "поганий джерело ..." зазвичай вказує на те, що після останнього фіксації в каталозі джерела були деякі перейменування, а значить, git mvне можна знайти очікуваний файл.

Рішення просте - просто покладіть зобов'язання перед застосуванням git mv.


15

Переконайтеся, що ви додали всі зміни до місця постановки перед запуском

git mv oldFolderName newFoldername

git не вдається з помилкою

fatal: bad source, source=oldFolderName/somepath/somefile.foo, destination=newFolderName/somepath/somefile.foo

якщо є якісь неадаптовані файли, тому я щойно дізнався.


"якщо є неадаптовані файли, тому я щойно з'ясував." - Дякую!
какодер

3

Ще один спосіб переміщення всіх файлів у каталозі до підкаталогу (зберігає історію git):

$ for file in $(ls | grep -v 'subDir'); do git mv $file subDir; done;


Обережно: якщо у вашій папці / імені є пробіл, це спричинить проблеми!
dejoma

3

У мене була схожа проблема з тим, git mvде я хотів перемістити вміст однієї папки у існуючу папку, і в кінцевому підсумку був цей "простий" скрипт:

pushd common; for f in $(git ls-files); do newdir="../include/$(dirname $f)"; mkdir -p $newdir; git mv $f $newdir/$(basename "$f"); done; popd

Пояснення

  • git ls-files: Знайдіть усі файли (у commonпапці), позначені git
  • newdir="../include/$(dirname $f)"; mkdir -p $newdir;: Створіть нову папку всередині includeпапки з тією ж структурою каталогу, що іcommon
  • git mv $f $newdir/$(basename "$f"): Перемістіть файл у новостворену папку

Причиною цього є те, що, схоже, у git виникають проблеми з переміщенням файлів у існуючі папки, а також він вийде з ладу, якщо спробувати перемістити файл у неіснуючу папку (звідси mkdir -p).

Приємна річ у цьому підході - це те, що він торкається лише файлів, які вже зареєстровані в git. Просто використовуючи git mvдля переміщення цілу папку, а в папці містяться нестандартні зміни, git не буде знати, що робити.

Після переміщення файлів ви, можливо, захочете очистити сховище, щоб видалити залишки незмінених змін - просто не забудьте спочатку просушити його!

git clean -fd -n

Обережно: якщо у вашій папці / імені є пробіл, це спричинить проблеми!
dejoma

2

Вибачте, що мені не вистачає репутації, щоб прокоментувати "відповідь" "Andres Jaan Tack".

Я думаю, що мій мессен буде видалений ((але я просто хочу попередити "люршера" та інших, хто отримав ту саму помилку: будьте обережні.

$ mkdir include
$ mv common include
$ git rm -r common
$ git add include/common

Це може призвести до того, що ви не побачите історію git свого проекту в новій папці.

Я спробував

$ git mv oldFolderName newFolderName

здобули

fatal: bad source, source=oldFolderName/somepath/__init__.py, dest
ination=ESWProj_Base/ESWProj_DebugControlsMenu/somepath/__init__.py

я зробила

git rm -r oldFolderName

і

git add newFolderName

і я не бачу старої історії git у своєму проекті. Принаймні мій проект не загублений. Тепер я маю свій проект у newFolderName, але без історії (

Просто хочете попередити, будьте обережні, скориставшись порадою "Andres Jaan Tack", якщо ви не хочете втрачати свій гзиторій.


Переконайтеся, що всі ваші зміни додані. У Git не вдається сказати "поганий джерело", якщо є неприєднані зміни, тому я щойно з'ясував.
Кевін Плюк

0

У мене була подібна проблема, але в папці, яку я хотів перемістити, у мене були файли, які я не відстежував.

скажімо, у мене були файли

a/file1
a/untracked1
b/file2
b/untracked2

І я хотів переміщувати лише відслідковані файли до підпапки subdir, тому метою було:

subdir/a/file1
subdir/a/untracked1
subdir/b/file2
subdir/b/untracked2

що я зробив:

  • Я створив нову папку та перемістив усі файли, які мене зацікавили переміщення: mkdir tmpdir && mv a b tmpdir
  • перевірили старі файли git checkout a b
  • створив новий dir та перемістив чисті папки (без нерафікованих файлів) до нового subdir: mkdir subdir && mv a b subdir
  • додав усі файли з subdir (щоб Git міг додати лише відслідковані раніше файли - це було деяким видом git add --updateіз трюком зміни каталогів ): git add subdir(як правило, це додасть навіть непотрібні файли - для цього потрібно створити .gitignoreфайл)
  • git status показує тепер лише переміщені файли
  • решту файлів переміщено з tmpdir в subdir: mv tmpdir/* subdir
  • git statusвиглядає, як ми стратили git mv:)

-1

Я вирішив це на Windows, зробивши це:

  • Відкрийте консоль Power shell
  • запустити реж
  • Клацніть по клавіші Alt та перетягніть колонку з іменем файлу / папки, а потім скопіюйте
  • Вставити в блокнот ++
  • запустити заміну з регулярним виразом: замінити (.*)наgit mv ".\\\1" ".\\<New_Folder_Here>\"
  • скопіюйте весь текст із блокнота ++ в оболонку
  • натисніть Enter
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.