Как удалить подмодуль?

Как удалить подмодуль Git?

Кстати, по какой причине я не могу просто сделать git submodule rm whatever?


person R. Martinho Fernandes    schedule 11.08.2009    source источник
comment
Простой ответ stackoverflow.com/a/21211232/94687 теперь является правильным и должен быть отмечен соответствующим образом. Теперь это просто git rm modulename и rm -rf .git/modules/modulename   -  person imz -- Ivan Zakharyaschev    schedule 15.06.2015
comment
На самом деле это не так. Этот ответ не касается удаления записи подмодуля из .git/config. В принятом ответе показан современный способ полного удаления подмодуля. Это также более лаконично объясняется в этом ответе: stackoverflow.com/a/36593218/1562138   -  person fvgs    schedule 13.04.2016
comment
Я нашел эту статью очень полезной при удалении подмодулей. Он включает информацию об удалении записей в файлах .gitsubmodules и .git / config ссылка   -  person Ri_    schedule 15.05.2016
comment
Сэкономьте время и сразу перейдите к ответу, который работает (в 2017 г.): stackoverflow.com/a/36593218/528313   -  person Vincenzo Pii    schedule 16.01.2017
comment
Два дня боролся с проблемами подмодулей. Прорыв произошел, когда я обнаружил следующее: forum.developer.apple.com/thread/13102. По сути, Xcode и, возможно, другие приложения изо всех сил пытаются расширить URL-адрес, содержащий '~'. Как только я изменил ssh: //[email protected]/~/git/MyRepo.git на ssh: //[email protected]/home/username/git/MyRepo.git (найдите фактический путь на вашем сервере), все странности исчезли через десять минут. См. Также заголовок stackoverflow.com/questions/32833100/   -  person Elise van Looij    schedule 09.02.2018


Ответы (31)


Поскольку git1.8.3 ( 22 апреля 2013 г.):

Не было способа Porcelain сказать, что меня больше не интересует этот подмодуль, если вы выразите свой интерес к подмодулю с помощью git submodule init.
git submodule deinit - способ сделать это.

В процессе удаления также используется git rm (с git1.8.5 октября 2013 г.).

Резюме

Тогда трехэтапный процесс удаления будет выглядеть следующим образом:

0. mv a/submodule a/submodule_tmp

1. git submodule deinit -f -- a/submodule    
2. rm -rf .git/modules/a/submodule
3. git rm -f a/submodule
# Note: a/submodule (no trailing slash)

# or, if you want to leave it in your working tree and have done step 0
3.   git rm --cached a/submodule
3bis mv a/submodule_tmp a/submodule

Объяснение

rm -rf: это упоминается в Daniel Schroeder answer и резюмированы Eonil в комментарии:

Это оставляет .git/modules/<path-to-submodule>/ без изменений.
Поэтому, если вы однажды удалите подмодуль этим методом и снова добавите его, это будет невозможно, потому что репозиторий уже поврежден.


git rm: См. совершить 95c16418:

В настоящее время использование git rm в подмодуле удаляет дерево работы подмодуля из дерева суперпроекта и gitlink из индекса.
Но раздел подмодуля в .gitmodules остается нетронутым, который является остатком от теперь удаленного подмодуля и может раздражать пользователей (в отличие от настройки в .git/config, это должно оставаться напоминанием о том, что пользователь проявил интерес к этому подмодулю, поэтому он будет повторно заполнен позже, когда будет извлечена более старая фиксация).

Пусть git rm поможет пользователю, не только удалив подмодуль из рабочего дерева, но также удалив раздел submodule.<submodule name> из файла .gitmodules и подготовив и то, и другое.


git submodule deinit: Это происходит из этого патча :

С git submodule init пользователь может сказать git, что он заботится об одном или нескольких подмодулях и хочет, чтобы он был заполнен при следующем вызове git submodule update.
Но в настоящее время нет простого способа сказать git, что они не заботятся о подмодуля и хочет избавиться от локального рабочего дерева (если пользователь не знает много о внутреннем устройстве подмодуля и не удаляет параметр submodule.$name.url из .git/config вместе с деревом работ сам).

Помогите этим пользователям, предоставив команду 'deinit'.
Эта удаляет весь раздел submodule.<name> из .git/config либо для данного подмодуля (ов) (или для всех тех которые были инициализированы, если задано '.').
Ошибка, если текущее дерево работ содержит изменения, кроме принудительных.
Пожаловаться, если для подмодуля, указанного в командной строке, параметр URL не может быть найден в .git/config, но тем не менее не подводите.

Это позаботится о том, чтобы шаги (де) инициализации (.git/config и .git/modules/xxx)

Начиная с git1.8.5, git rm также заботится о:

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

git add mysubmodule/file.txt 
Path 'mysubmodule/file.txt' is in submodule 'mysubmodule'

Примечание. Начиная с Git 2.17 (второй квартал 2018 г.), подмодуль git deinit больше не является сценарием оболочки.
Это вызов функции C.

См. фиксацию 2e61273, commit 1342476 (14 января 2018 г.) Пратамеш Чаван ( pratham-pc).
(Объединено Junio ​​C Hamano - gitster - в commit ead8dbe, 13 февраля 2018 г.)

git ${wt_prefix:+-C "$wt_prefix"} submodule--helper deinit \
  ${GIT_QUIET:+--quiet} \
  ${prefix:+--prefix "$prefix"} \
  ${force:+--force} \
  ${deinit_all:+--all} "$@"
person VonC    schedule 23.04.2013
comment
Можете ли вы привести пример использования submodule deinit? - person zakdances; 28.04.2013
comment
@yourfriendzak вот один пример того, как кто-то успешно его использует: stackoverflow.com/a/16161950/6309. Но имейте в виду, что вопреки тому, что я изначально думал, 1.8.3 еще не выпущен! В Unix вы можете скомпилировать его из исходников. - person VonC; 28.04.2013
comment
По моему опыту, git submodule deinit не удаляет соответствующий каталог из .git/config. Он все еще там, пока я не удалю его вручную. - person zakdances; 29.05.2013
comment
Итак, если я сделаю вытягивание после того, как это сделал кто-то другой, мой подмодуль будет очищен за меня, или мне все равно придется выполнять обычные действия вручную? (cf stackoverflow.com/questions/14877420/) - person Hamish Downer; 04.06.2013
comment
@HamishDowner специальная запись должна исчезнуть (каталог больше не является подмодулем), и .gitmodules должен быть в порядке, но я бы все равно перепроверил что-либо с помощью каталога .git (т.е. конфигурации local, в вашем локальном репо: это не изменяется git pull) - person VonC; 04.06.2013
comment
@VonC Я все еще застрял с файлом .gitmodules, и внутри моих .git / modules у меня тоже есть ссылка. Можем ли мы просто удалить эти вещи, игнорировать их или что-то третье? - person Warpzit; 06.06.2013
comment
@Warpzit у вас есть git1.8.3, а git submodule deinit? Но если нет, то да, вы можете вручную очистить лишние метаданные. - person VonC; 06.06.2013
comment
Что нужно делать другим пользователям, использующим репозиторий git? только 1_? - person Jayen; 02.08.2013
comment
@Jayen: да, если вы зафиксируете удаление записи .gitmodules и удаления специальной записи в индексе, а затем отправите это репо, другие могут вытащить его, и этот подмодуль исчезнет. - person VonC; 02.08.2013
comment
Раздел deinit в git-submodule(1) теперь рекомендует использовать git rm: если вы действительно хотите удалить подмодуль из репозитория и зафиксировать, используйте вместо этого git-rm (1). - person mgalgs; 08.08.2013
comment
Вот сценарий, который автоматизирует эти шаги: gist.github.com/sharplet/6289697. Добавьте его в свои PATH и git remove-submodule path/to/submodule. - person Adam Sharp; 21.08.2013
comment
@AdamSharp, разве вам не нужно использовать git-remove-submodule ... вместо git remove-submodule ....? - person kenny; 24.08.2013
comment
@kenny no: «git remove-submodule» (с пробелом) будет искать исполняемый файл «git-remove-submodule» (с тире) в любом месте вашего $PATH. - person VonC; 24.08.2013
comment
Я получил ошибку из сценария, которая, я думаю, будет происходить каждый раз: ошибка: подмодуль 'magit' (или один из его вложенных подмодулей) использует каталог .git (используйте 'rm -rf', если вы действительно хотите удалить его, включая все его истории) Не всегда ли подмодули будут иметь внутри себя каталог .git? - person pedz; 29.08.2013
comment
@pedz извините за поздний ответ. Вы воспроизвели это сообщение об ошибке? Это в случае вложенного подмодуля? (подмодуль внутри подмодуля) - person VonC; 03.09.2013
comment
@pedz @VonC определенно звучит так, будто это вызвано вложенным подмодулем. Не могли бы вы попробовать отредактировать сценарий для запуска git rm -rf "$submodule_name" (обратите внимание на флаг -r)? Если это сработает, я соответствующим образом обновлю скрипт. - person Adam Sharp; 04.09.2013
comment
@AdamSharp Я удалил magit, у которого нет подмодулей. Разве в каком-либо подмодуле не будет каталога .git? - person pedz; 08.09.2013
comment
@pedz Вы правы, в нем нет подмодулей. Да, если подмодуль инициализирован и извлечен, у него должен быть каталог .git. Какую версию Git вы используете? - person Adam Sharp; 08.09.2013
comment
@AdamSharp - извините за медленный ответ. Я не получаю электронные письма. Не знаю, какая версия. Щас у меня 1.8.3.2 и 1.7.12.4. Я недавно обновился. У меня тоже была 1.7.4.1. Я не знаю, какую версию я использовал при удалении. Подождите - я помню, что в 1.7.4 не было подмодуля git deinit. - person pedz; 16.09.2013
comment
@pedz да, git submodule deinit доступен только с 1.8.3+. Обратите внимание, что, как я упоминал в моем отредактированном ответе выше, git rm asubmodule скоро обо всем позаботится. - person VonC; 16.09.2013
comment
Запуск сценария оставил мне неработающий проект. Я попытался удалить подмодуль, а затем снова добавить его с помощью git submodule add -b master ... У меня возникла ошибка, и я больше не мог добавить подмодуль обратно: каталог git для 'asub' находится локально с помощью remote (s): origin url_asub.git Если вы хотите повторно использовать этот локальный каталог git вместо повторного клонирования из url_asub .git используйте параметр --force. Если локальный каталог git не является правильным репозиторием или вы не уверены, что это означает, выберите другое имя с параметром --name. P.S. Это с git версии 1.8.4.msysgit.0 - person tinlyx; 07.01.2014
comment
@TingL Вы могли бы преобразовать существующий подмодуль, чтобы он следовал за веткой: stackoverflow.com/a/18799234/6309. Или используйте msysgit 1.8.5.2 (code.google.com/p/msysgit/downloads/): git rm yourSubmodule теперь удаляет подмодуль из рабочего дерева и .gitmodules файлов. - person VonC; 07.01.2014
comment
@TingL Я отредактировал ответ, чтобы удалить скрипт и обновить ответ до git1.8.5, теперь доступного и для Windows с помощью msysgit 1.8.5.2. - person VonC; 07.01.2014
comment
примечание: deinit и rm, похоже, работают с путями, и у меня это хорошо сработало с завершающей косой чертой на asubmodule с обеими командами. (git v. 1.9.1) - person desseim; 27.03.2014
comment
@desseim да, и это будет верно для всех команд: stackoverflow.com/a/22130978/6309 - person VonC; 27.03.2014
comment
В текущем git (v1.9 +) простой старый git rm submodule делает именно то, что вы хотите, как уже говорили другие люди. - person Pete Peterson; 12.06.2014
comment
По моему опыту хорошо git rm -rf --cached /path/to/submodule убирает подмодуль. Тогда git commit. Если я не хотел, чтобы папка добавлялась как подмодуль, я просто удаляю .git в path/to/folder и git add /path/to/folder. - person aubreypwd; 25.09.2014
comment
Это оставляет .git/modules/<path-to-submodule>/ без изменений. Поэтому, если вы однажды удалите подмодуль этим методом и снова добавите его, это будет невозможно, потому что репозиторий уже поврежден. - person eonil; 24.10.2014
comment
@VonC Можно ли удалять такие внутренние структуры? Не влияет ли это на целостность структурных данных? Я не эксперт по Git, но я все больше и больше теряю доверие к Git, когда узнаю, насколько он хрупкий ... - person eonil; 24.10.2014
comment
@Eonil нет, в этом случае это нормально, чтобы сохранить согласованность с удалением записи gitlink (stackoverflow.com/ а / 16581096/6309). - person VonC; 24.10.2014
comment
git submodule deinit [submodule] просто выдает подсказку об использовании - неверный синтаксис? - person Nathan Hornby; 06.02.2015
comment
@NathanHornby, это зависит от вашей версии Git (git --version). Это для git 1.8.3+. Если ваша версия слишком старая, вы сможете легко ее обновить (например: stackoverflow.com/a/24847953/6309 < / а>) - person VonC; 06.02.2015
comment
вам лучше изменить порядок команд, иначе вы получите (в Windows) ошибку для Stopping at 'lib/asubmodule'; script returned non-zero status. решения: git rm lib/asubmodule && rm .git/modules/lib/asubmodule && git submodule lib/asubmodule deinit --recursive --force (если ваш модуль находится под root, вам не нужна lib /) - person ; 18.04.2015
comment
Ответы @VonC охватывают ВСЕ базы, но если вам просто нужно удалить подмодуль прямо сейчас, см. stackoverflow.com/a/21211232 / 8047 - person Dan Rosenstark; 20.04.2016
comment
@VonC Я не уверен, заботятся ли этот Q и многие ответы о сохранении истории, то есть о путешествии во времени vcs, и вместо этого просто хочу удалить эту чертову вещь. rm -rf .git/modules/a/submodule является необратимым, если все коммиты в репозитории подмодуля не были отправлены на удаленный компьютер. (Если их подтолкнули, могу ли я предположить, что проверка прошлой фиксации восстанавливает все? Я добавил stackoverflow.com/q/61963342/8910547, чтобы представить альтернативный сценарий. Или, возможно, этот вопрос и ваш ответ можно отредактировать, чтобы уточнить, и в этом случае я могу просто удалить свой новый вопрос как лишний. - person Inigo; 22.05.2020
comment
rm -rf .git / modules / a / submodule у меня не работает. кажется .git не каталог (но он существует) - person openCivilisation; 06.03.2021
comment
git rm отлично работает с косой чертой. - person nurettin; 16.05.2021
comment
@nurettin true, но в этом случае убедитесь, что вы используете без завершающей косой черты, чтобы удалить запись подмодуля вместо папки подмодуля. - person VonC; 16.05.2021

На странице Учебник по подмодулю Git:

Чтобы удалить подмодуль, вам необходимо:

  1. Удалите соответствующий раздел из файла .gitmodules.
  2. Выполните .gitmodules изменения:
    git add .gitmodules
  3. Удалите соответствующий раздел из .git/config.
  4. Удалите файлы подмодулей из рабочего дерева и проиндексируйте:
    git rm --cached path_to_submodule (без косой черты в конце).
  5. Удалите каталог .git подмодуля:
    rm -rf .git/modules/path_to_submodule
  6. Подтвердите изменения:
    git commit -m "Removed submodule <name>"
  7. Удалите файлы подмодуля, которые сейчас не отслеживаются:
    rm -rf path_to_submodule

См. также: альтернативные шаги ниже.

person Community    schedule 11.08.2009
comment
И, кстати, есть ли причина, по которой я не могу просто использовать git submodule rm? ? - person abernier; 20.01.2011
comment
@abernier Краткий ответ может быть потому, что такой команды не существует. Я предполагаю, что они пытаются сделать удаление файлов подмодулей и конфигурации подмодулей явным, чтобы избежать случайной потери данных. Возможно, кто-то подумает, что git submodule rm просто удаляет регистрацию подмодуля, и будет удивлен, если команда также удалит локальный репозиторий. Любые локальные изменения были бы безвозвратно потеряны. И, возможно, другой человек подумает, что будут удалены только файлы. - person John Douthat; 21.01.2011
comment
Честно говоря, не знаю почему. Я надеюсь, что они добавят команду. Эти 4 шага слишком сложны. - person John Douthat; 21.01.2011
comment
Я продолжал получать эту ошибку: fatal: pathspec 'blocks / submodule_folder /' не соответствует ни одному файлу. Я добавил команду -f, --force: git rm --cached -f blocks / submodule_folder и избавился от кеша. - person hellatan; 18.12.2011
comment
@dtan убедитесь, что нет завершающей косой черты - person John Douthat; 18.12.2011
comment
У меня это не сработало. Разве те папки, которые раньше были подмодулями, теперь не должны отображаться как обычные папки в родительском проекте? Потому что они не для меня, и после того, как это изменение было внесено в GitHub, он все еще считает, что это подмодули, просто они больше не ссылаются на репозитории подмодулей ... - person Matthias; 13.01.2012
comment
хорошо, мне снова пришлось git rm --cached -f submodule_name, теперь все работает. - person Matthias; 13.01.2012
comment
также необходимо очистить .git / modules, чтобы позже можно было добавить модуль с тем же путем. - person Ian Yang; 24.03.2012
comment
Вот сценарий bash, который удаляет подмодуль, просто создайте псевдоним git для submodule-rm;) gist.github.com/ 2491147 - person Capi Etheriel; 25.04.2012
comment
Каталог подмодулей тоже надо удалить, правильно? Таким образом, 1_ - person Josh Brown; 18.05.2012
comment
также нужен rm -rf .git \ modules \ имя подмодуля? - person rogerdpack; 22.05.2012
comment
Да, вы, вероятно, захотите удалить файлы подмодулей, которые сейчас не отслеживаются. - person John Douthat; 23.05.2012
comment
Вам необходимо удалить справочный каталог .git / modules, если вы хотите повторно добавить каталог как простой подмодуль (не забывая также удалить его внутреннюю папку .git). См. Ответ Марка ниже: stackoverflow.com/a/9536504/149416 - person Anton I. Sipos; 30.06.2012
comment
Вам нужно поставить .gitmodules. Перед коммитом запустите git add .gitmodules. - person luissquall; 09.07.2012
comment
git submodule rm должно быть командой. Эта установка становится более сложной, если у вас есть подмодули внутри подмодулей, потому что местоположение ваших .git/config меняется. - person Justin Force; 23.08.2012
comment
как насчет удаления всего кеша в папке типа git rm --cached path_to_sub/* - person Dzung Nguyen; 25.08.2012
comment
@sidewaysmilk, возможно, вы просто объяснили, почему этой команды не существует. Если вы даете команду, вы должны охватить все эти угловые случаи, и, возможно, они решили, что это будет слишком сложно. - person Adrian Ratnapala; 05.09.2012
comment
@AdrianRatnapala Может быть. Но это мерзость! Эти ребята великолепны. И самая сложная процедура должна быть первым кандидатом на автоматизацию. - person Justin Force; 19.09.2012
comment
Как происходит изменение каталога .git вручную при внесении изменений? Нужно ли всем, кто использует главный проект, вносить эти изменения вручную, и как они узнают, что им нужно внести эти изменения? - person James Moore; 03.10.2012
comment
@JamesMoore Измененный файл .gitmodules будет отправлен в мастер, так что все увидят изменение. Однако соответствующий раздел в .git/config не будет передан другим пользователям. Это просто локальная настройка с информацией о репозитории клонированного подмодуля. При необходимости другим людям в вашем проекте все равно придется удалить репозиторий подмодуля. Git не может точно знать, есть ли у других людей какие-либо неопубликованные изменения в этом репо, поэтому для git было бы небезопасно автоматически удалять их копию. - person John Douthat; 03.10.2012
comment
Ответ не на 100% правильный. Я обнаружил, что если я не вставлю -f в строку git rm --cached, я НЕ МОГУ заставить это исправление работать с ветвями, отличными от master. Переключение на каждую ветку и использование -f заставили его работать - я думаю, это как-то связано с тем, как редактирование файлов конфигурации ломает другие ветки, не редактируя их. Черт, подмодули плохо спроектированы в git! Никогда больше не буду их использовать! - person Adam; 23.12.2012
comment
«Должна» действительно быть команда для удаления подмодулей. как насчет этого: git submodule removeUntrackDelete ‹name›? Достаточно ли этого для вышеупомянутых вариантов использования? :) Кроме того, с моими ограниченными знаниями git мне легче испортить эти 5 (!) шагов, чем испортить один шаг tbh. - person Michael Trouw; 07.03.2013
comment
Что произойдет, если у людей будет .git/ с этим подмодулем? Предположим, вы сняли его и толкнули / потянули. Должен быть git submodule rm -f XXX, чтобы избежать потери данных. - person Wernight; 09.05.2013
comment
Если вы опустите параметр --cached для шага 4, вам не нужен шаг 7. - person Jarl; 23.06.2013
comment
Вы должны использовать git submodule deinit [-f] - person hellboy; 08.09.2015
comment
Мне пришлось добавить -r в конец удаляемой папки, чтобы удалить ее из индекса: git rm --cached path_to_submodule -r - person Peter Mark; 06.05.2016
comment
это работает для меня. Я хочу поменять подмодуль на реальные файлы без трека .gitmodules. Затем вам нужно удалить каждый подмодуль git track и очистить каталог, а затем перестроить свой каталог ... почему так сложно удалить подмодуль ... - person penny chan; 24.08.2017
comment
Классический Git .... Возьмите простую задачу и сделайте ее трудной или невозможной. - person jww; 10.02.2019
comment
deinit по-прежнему оставляет контент, лежащий без дела. Я написал быстрый скрипт, который больше похож на команды OP. github.com/mcandre/gus - person mcandre; 15.02.2020
comment
Спустя 9 лет мне все же помогли устранить неисправность неработающего подмодуля :) - person kovac; 12.04.2020
comment
rm -rf .git / modules / my_submodule не является папкой. на самом деле .git - это не каталог, а файл. Что-то изменилось? - person openCivilisation; 06.03.2021
comment
ЭТО наконец сработало. git rm --cached <subfolder> помог мне. Спасибо! - person Jack Scandall; 13.07.2021

Большинство ответов на этот вопрос устарели, неполны или излишне сложны.

Подмодуль, клонированный с использованием git 1.7.8 или новее, оставит не более четырех следов самого себя в вашем локальном репо. Процесс удаления этих четырех следов задается тремя командами ниже:

# Remove the submodule entry from .git/config
git submodule deinit -f path/to/submodule

# Remove the submodule directory from the superproject's .git/modules directory
rm -rf .git/modules/path/to/submodule

# Remove the entry in .gitmodules and remove the submodule directory located at path/to/submodule
git rm -f path/to/submodule
person fvgs    schedule 13.04.2016
comment
Почему у этого ответа так мало голосов? Все эти популярные ответы что-то упускают, это единственный, который действительно удаляет все следы подмодуля самым простым способом. И обратите внимание: порядок команд имеет значение. - person mbdevpl; 07.09.2016
comment
Откуда вы взяли -rf? Я получаю сообщение об ошибке при попытке запустить эту (вторая команда; Windows-машина) - person Thomas; 20.01.2017
comment
Чтобы ответить на мой собственный вопрос: stackoverflow.com/questions/ 97875 / rm-rf-equal-for-windows - person Thomas; 20.01.2017
comment
@mbdevpl появился через 3 года после принятого ответа, и я думаю, никому не удалось убедить OP принять этот - person Andy; 20.02.2017
comment
К сожалению, это не позволяет хранить файлы в вашем рабочем дереве (на случай, если вы захотите затем зафиксировать их в родительском репозитории), и rm -rf не будет работать в Windows. - person Simon East; 30.06.2017
comment
@Thomas rm -rf означает просто удалить всю папку, чтобы вы могли сделать это из графического интерфейса проводника в Windows. В качестве альтернативы, если вы используете git в Windows, у вас также будет доступен git bash, поэтому вы можете запускать все эти команды там, и они будут работать, как есть. - person Andy Madge; 08.12.2017
comment
ЭТО несложный ответ в 2018 году? - person Warren P; 03.02.2018
comment
файл .gitmodules все еще кажется незатронутым при выполнении этих команд - person Fractalf; 05.09.2018
comment
В 2019 году это не сработает. Последняя строка фактически пытается удалить из папки .git/modules, которую вы уже удалили в приведенной выше строке. Добавление -- в первую строку, как принятый ответ, похоже, помогает. - person Fmstrat; 28.06.2019
comment
@Fmstrat git v2.20.1 по-прежнему оставил .git/modules/submodule рядом со мной на месте, так что rm, похоже, понадобится сейчас или тогда. Если более новые gits хотят удалить его, хорошо, просто поменяйте местами последние две команды. Также обратите внимание, что git deinit и git rm относительно безопасны, но rm -rf .git/modules/submodule опасно, так как может удалить неправильный каталог. Вы можете переименовывать и перемещать подмодули, и они несут только правильный путь для удаления в файле .git.git/config). Также удаление копии модуля может быть неправильным, если вы прыгаете по истории. Все сложно .. - person Tino; 25.11.2019

Просто примечание. Начиная с git 1.8.5.2, будут работать две команды:

git rm -r the_submodule
rm -rf .git/modules/the_submodule

Как правильно указал ответ @Mark Cheverton, если вторая строка не используется, даже если вы удалили подмодуль на данный момент, папка remnant .git / modules / the_submodule предотвратит добавление или замену того же подмодуля в будущем . Кроме того, как упоминал @VonC, git rm будет выполнять большую часть работы над подмодулем.

--Обновление (05.07.2017) -

Чтобы уточнить, the_submodule - это относительный путь подмодуля внутри проекта. Например, это subdir/my_submodule, если подмодуль находится внутри подкаталога subdir.

Как правильно указано в комментариях и других ответах, две команды (хотя функционально достаточны для удаления подмодуля) оставляют след в разделе [submodule "the_submodule"] документа .git/config (по состоянию на июль 2017 г.), который можно удалить с помощью третьей команды:

git config -f .git/config --remove-section submodule.the_submodule 2> /dev/null
person tinlyx    schedule 18.01.2014
comment
Я использую git версии 2.4.9 (Apple Git-60), и все, что мне нужно было сделать, это rm the_submodule. Я нажал на нее, а затем повторно добавил папку с таким же именем, как и подмодуль, и она работала без проблем. - person David Silva Smith; 04.12.2015
comment
Я использую git версии 2.5.4 для OSX, и вам нужно выполнить вторую команду, только если вы хотите повторно добавить подмодуль из другого места. Если вы не сделаете второй шаг, вы увидите следующее: Каталог git для 'submodule' находится локально с помощью remote (s): - person Ed Sykes; 11.02.2016
comment
Это не удаляет запись подмодуля из .git/config. Полный способ удаления подмодуля см. В stackoverflow.com/a/36593218/1562138. - person fvgs; 13.04.2016
comment
@fvgs с git 2.7.4 команда git rm ДЕЙСТВИТЕЛЬНО удаляет раздел из .git / config, а также удаляет папки .git / modules / ... - person drevicko; 22.02.2017
comment
@drevicko Я только что протестировал это с помощью Git 2.11.1 и наблюдаю то же поведение, что и раньше. git init && git submodule add <repository> && git rm <name> оставляет за собой запись .git/config, каталог .git/modules/<name> и его содержимое. Возможно, вы не инициализировали подмодуль перед его удалением? - person fvgs; 22.02.2017
comment
@fvgs хорошо, я получаю то же самое здесь с git 2.7.4, когда пробую ваш эксперимент - не уверен, что произошло? Подмодуль был определенно инициализирован, некоторое время был с множеством изменений. - person drevicko; 27.02.2017
comment
Я чувствую себя безопаснее, запустив сначала это .. git submodule deinit -f the_submodule - person danday74; 10.03.2017
comment
Может ли ответ прояснить, что здесь the_submodule? Путь к подмодулю? - person Jarrod Smith; 03.07.2017
comment
@JarrodSmith Да, это путь. пожалуйста, посмотрите обновление. - person tinlyx; 06.07.2017
comment
Стоит отметить, что если у вас никогда не было этого подмодуля, инициализированного в репозитории, в котором вы запускаете эти команды (например, вы создали новый нерекурсивный клон), вам не нужно запускать вторую команду или удалять раздел из конфигурации git, поскольку этих элементов не будет. - person Adam Burley; 27.02.2018
comment
@ danday74 ваша команда действительно нужна, если подмодуль извлечен. иначе вы получите ошибку Unlink of file '...' failed - person Adam Burley; 01.03.2018
comment
Похоже, это сработало в 2020 году и, возможно, является самым простым, за исключением того, что, похоже, не удаляет фактический код. для чего потребуется git rm -f path/to/submodule, я думаю, что stackoverflow.com/a/36593218/2808203 - лучшее решение. - person Darrell Ulm; 17.06.2020
comment
хм ... на git 1.8.3.1 у меня нет .git/modules/ - person xealits; 13.11.2020

Простые шаги

  1. Удалить записи конфигурации:
    git config -f .git/config --remove-section submodule.$submodulename
    git config -f .gitmodules --remove-section submodule.$submodulename
  2. Удалить каталог из индекса:
    git rm --cached $submodulepath
  3. Совершить
  4. Удалите неиспользуемые файлы:
    rm -rf $submodulepath
    rm -rf .git/modules/$submodulename

Обратите внимание: $submodulepath не содержит косых черт в начале и в конце.

Фон

Когда вы делаете git submodule add, он только добавляет его в .gitmodules, но как только вы сделали git submodule init, он добавлялся в .git/config.

Поэтому, если вы хотите удалить модули, но можете быстро восстановить их, сделайте следующее:

git rm --cached $submodulepath
git config -f .git/config --remove-section submodule.$submodulepath

Если вы поместите это в сценарий, рекомендуется сделать сначала git rebase HEAD, а в конце git commit.

Также ознакомьтесь с ответом на Могу ли я очистить подмодуль Git?.

person Community    schedule 04.10.2011
comment
У меня было много подмодулей (и еще больший беспорядок), поэтому мне пришлось передать их через цикл for. Поскольку большинство из них находились в определенном каталоге, а вывод ls содержал завершающие косые черты. Я сделал что-то вроде for dir in directory/*; do git rm --cached $dir; done. - person Pablo Olmos de Aguilera C.; 10.10.2011
comment
Чтобы получить это, список, который можно использовать в скрипте для рекурсивного удаления - git config -f .git/config -l | cut -d'=' -f1 | grep "submodule.$MODPATH" | sed 's/^submodule\.//' | sed 's/\.url$//' - - похоже, что вам действительно нужно это сделать в случае, если что-то не так, иначе просто git submodule | grep -v '^+' | cut -d' ' -f3 - person errordeveloper; 12.10.2011
comment
получить список модулей, в которых не производились локальные изменения - git submodule | grep '^+' | cut -d' ' -f2 - person errordeveloper; 12.10.2011
comment
обратите внимание, мне пришлось включить submodulename в двойные кавычки "submodulename" .., ссылаясь на файл .git/config - person muon; 20.07.2017
comment
Простой. Эффективный. В версии 2.25.0 после шага 1 вам нужно подготовить изменения .gitmodules до шага 2. - person Michel Donais; 05.02.2020

В дополнение к рекомендациям мне также пришлось rm -Rf .git/modules/path/to/submodule, чтобы иметь возможность добавить новый подмодуль с тем же именем (в моем случае я заменял вилку оригинальной)

person Mark Cheverton    schedule 02.03.2012
comment
У меня тоже были проблемы с этим. Если вы попытаетесь переустановить подмодуль на тот же путь, он сохранит информацию о ветке в кэше в указанном вами месте, что все испортит. - person jangosteve; 06.03.2012
comment
Спасибо, мне это тоже было нужно. @Anton, я согласен, и я отредактировал получивший наибольшее количество голосов ответ, чтобы добавить эту информацию. - person William Denniss; 23.09.2012
comment
Я использовал параметр --name, чтобы замена работала ... см. stackoverflow.com/questions/14404704/ - person joseph.hainline; 18.01.2013

Чтобы удалить добавленный подмодуль, используйте:

git submodule add [email protected]:repos/blah.git lib/blah

Запустить:

git rm lib/blah

Вот и все.

Для старых версий git (около ~ 1.8.5) используйте:

git submodule deinit lib/blah
git rm lib/blah
git config -f .gitmodules --remove-section submodule.lib/blah
person Doug    schedule 12.10.2013
comment
+1 действительно. Это единственный правильный ответ начиная с git 1.8.3. Следует принять как правильный. - person Xananax; 02.07.2014
comment
git rm по-прежнему оставляет материал в .git/modules/. (2.5.4) - person Rudolf Adamkovič; 02.01.2016
comment
@RudolfAdamkovic у меня работает? Обратите внимание, что он удаляет запись подмодуля, только если совпадает точный путь; если вы переместили подмодуль, а затем использовали git rm, этого не произойдет; Быстрый тест с 2.5.4 на моем Mac обновляет файл .gitmodules, как описано в документации здесь: git-scm.com/docs/git-rm#_submodules ... но если вы нашли какую-то комбинацию платформы / версии, где этого не происходит, вам, вероятно, следует сообщить об ошибке Это. - person Doug; 02.01.2016
comment
Это не совсем правильный ответ. git rm оставляет содержимое в .git/modules/ директории и .git/config файле (ubuntu, git 2.7.4). Другой ответ работает на 100%: stackoverflow.com/a/36593218/4973698 - person mbdevpl; 07.09.2016

Вы должны удалить записи в .gitmodules и .git/config, а также удалить каталог модуля из истории:

git rm --cached path/to/submodule

Если вы напишете в список рассылки git, возможно, кто-нибудь напишет для вас сценарий оболочки.

person Carmine Paolino    schedule 11.08.2009
comment
Нет необходимости в каком-либо сценарии оболочки, в другом ответе есть команды для удаления всех следов подмодуля: stackoverflow.com/a/36593218/4973698 - person mbdevpl; 07.09.2016

Подводя итог, вот что вам следует сделать:

  1. Установите path_to_submodule var (без косой черты в конце):

    path_to_submodule=path/to/submodule

  2. Удалите соответствующую строку из файла .gitmodules:

    git config -f .gitmodules --remove-section submodule.$path_to_submodule

  3. Удалите соответствующий раздел из .git / config

    git config -f .git/config --remove-section submodule.$path_to_submodule

  4. Деактивировать и удалить $ path_to_submodule только из индекса (для предотвращения потери информации)

    git rm --cached $path_to_submodule

  5. Отслеживайте изменения, внесенные в .gitmodules

    git add .gitmodules

  6. Зафиксируйте суперпроект

    git commit -m "Remove submodule submodule_name"

  7. Удалите теперь неотслеживаемые файлы подмодулей

    rm -rf $path_to_submodule

    rm -rf .git/modules/$path_to_submodule

person luissquall    schedule 09.07.2012
comment
так что всем остальным, кто снимает мои изменения, придется запустить rm -rf $ path_to_submodule rm -rf .git / modules / $ path_to_submodule, чтобы удалить кеш подмодуля? - person j2emanue; 24.04.2015
comment
Рекомендую обновить, git submodule update. И если пути к подмодулям не обновлялись правильно (git выдает ошибку), удалите их: rm -rf .git/modules/<submodule> && rm -rf <submodule> && git submodule update - person luissquall; 29.04.2015

Вы можете использовать псевдоним для автоматизации решений, предоставляемых другими:

[alias]
  rms = "!f(){ git rm --cached \"$1\";rm -r \"$1\";git config -f .gitmodules --remove-section \"submodule.$1\";git config -f .git/config --remove-section \"submodule.$1\";git add .gitmodules; }; f"

Поместите это в свою конфигурацию git, и тогда вы можете сделать: git rms path/to/submodule

person Charles    schedule 01.11.2012
comment
-1, это слишком неправильно. ПЕРВЫЙ: предполагается, что имя и путь подмодуля идентичны , что чаще всего не так. I.E. git clone https://github.com/hilbix/empty.git; cd empty; git submodule add https://github.com/hilbix/empty.git one; git mv one two; git rms two. ВТОРОЙ: Вы должны выполнить это с правильного пути. git псевдонимы должны работать в любом месте рабочего дерева (или корректно завершаться ошибкой). ТРЕТИЙ: git config -f .git/config не работает в подмодулях, поскольку .git обычно находится там в виде файла. - person Tino; 25.11.2019

Если подмодуль был добавлен случайно из-за того, что вы добавили, зафиксировали и отправили папку, которая уже была репозиторием Git (содержащая .git), у вас не будет файла .gitmodules для редактирования или чего-либо еще в .git/config. В этом случае все, что вам нужно, это:

git rm --cached subfolder
git add subfolder
git commit -m "Enter message here"
git push

FWIW, я также удалил папку .git перед выполнением git add.

person Oli Studholme    schedule 16.05.2012
comment
именно мой случай - person zhekaus; 21.05.2017

Я обнаружил, что deinit мне подходит:

git submodule deinit <submodule-name>    
git rm <submodule-name>

Из git docs:

deinit

Отмените регистрацию данных подмодулей, т.е. удалите весь раздел submodule.$name из .git / config вместе с их рабочим деревом.

person Damjan Pavlica    schedule 09.02.2017
comment
Согласен, нашел такое же решение. Это лучший способ сегодня в 2018 году) - person woto; 11.01.2018
comment
он не удалил .git / modules / ... Вы должны удалить их, см. Ответ @fvgs - person Vilém Kurz; 01.10.2018
comment
Не знаю, почему это простое и легкое решение не номер 1 - person Marc Magon; 24.10.2019
comment
AFAICS, это кажется самым безопасным ответом для новых gits, которые знают о deinit, как другой ответ удаляет каталог .git/modules/submodule слишком рано, что, кажется, приводит к тому, что новые git время от времени выходят из строя. Также (см. Мой комментарий) удаление .git/modules/submodule может быть неправильным путем, поэтому это опасный шаг, лучше всего его предпринять позже, только когда git пожалуется (или если вы на 299% уверены, что это то, что вы хотите, это правильный путь и действительно нужен) . - person Tino; 25.11.2019
comment
Мне также понадобилось git commit для внесения поэтапных изменений в рабочий каталог: modified .gitmodules и deleted <submodule-path>. - person Yuriy Pozniak; 19.02.2020

Поэкспериментировав со всеми разными ответами на этом сайте, я пришел к следующему решению:

#!/bin/sh
path="$1"
if [ ! -f "$path/.git" ]; then
  echo "$path is no valid git submodule"
  exit 1
fi
git submodule deinit -f $path &&
git rm --cached $path &&
rm -rf .git/modules/$path &&
rm -rf $path &&
git reset HEAD .gitmodules &&
git config -f .gitmodules --remove-section submodule.$path

Это восстанавливает то же состояние, что и до добавления подмодуля. Вы можете сразу же добавить подмодуль снова, что было невозможно с большинством ответов здесь.

git submodule add $giturl test
aboveScript test

Это оставляет вас с чистой проверкой без каких-либо изменений для фиксации.

Это было проверено с помощью:

$ git --version
git version 1.9.3 (Apple Git-50)
person udondan    schedule 22.10.2014
comment
Почему вы используете git rm --cached $path, а затем rm -rf $path вместо git rm -r $path? - person bfontaine; 29.11.2014
comment
-1 Не работает, если вы попытаетесь удалить подмодуль внутри подмодуля (подмодуль может образовывать деревья!). Также это опасная ошибка из-за отсутствия цитирования! Пример git submodule add https://github.com/hilbix/empty.git 'dangerous .. submodule' - ›когда вы пытаетесь удалить« опасный .. подмодуль »своим скриптом, это будет rm -rf .., что, скорее всего, не то, что вы хотите .. - person Tino; 25.11.2019

Чем я сейчас занимаюсь, декабрь 2012 г. (объединяет большинство из этих ответов):

oldPath="vendor/example"
git config -f .git/config --remove-section "submodule.${oldPath}"
git config -f .gitmodules --remove-section "submodule.${oldPath}"
git rm --cached "${oldPath}"
rm -rf "${oldPath}"              ## remove src (optional)
rm -rf ".git/modules/${oldPath}" ## cleanup gitdir (optional housekeeping)
git add .gitmodules
git commit -m "Removed ${oldPath}"
person Lance Rushing    schedule 18.12.2012

Вот что я сделал:

1.) Удалите соответствующий раздел из файла .gitmodules. Вы можете использовать команду ниже:

git config -f .gitmodules --remove-section "submodule.submodule_name"

2.) Выполните .gitmodules изменения

git add .gitmodules

3.) Удалить соответствующий раздел из .git/config. Вы можете использовать команду ниже:

git submodule deinit -f "submodule_name"

4.) Удалите gitlink (без косой черты):

git rm --cached path_to_submodule

5.) Очистите .git/modules:

rm -rf .git/modules/path_to_submodule

6.) Зафиксировать:

git commit -m "Removed submodule <name>"

7.) Удалите теперь неотслеживаемые файлы подмодулей.

rm -rf path_to_submodule
person Ishan Liyanage    schedule 02.03.2016
comment
Спасибо за это. Мне пришлось изменить порядок первых трех шагов на 3), 1), 2). Выполнение 1) сначала дало fatal: no submodule mapping found in .gitmodules for path 'submodule_name' на шаге 3. Однако оба шага были необходимы. (git v2.8.2) - person U007D; 25.08.2016

  1. git submodule deinit <path to submodule>
  2. Удалить раздел из .gitmodules
  3. Звоните: git rm <path to submodule>
  4. Удалите файлы модуля, которые нужно удалить из вашего проекта.
  5. Добавьте удаленные файлы в git и вызовите git add .gitmodules
  6. Зафиксировать и нажать
person Black    schedule 31.01.2020
comment
Для меня достаточно было позвонить git submodule deinit <submodule_name> и git rm <path_to_submodule>. Последняя команда автоматически удаляет запись внутри .gitmodules. Git 2.17 - person Dmytro Ovdiienko; 05.05.2020
comment
Мне нужно -r с git rm: git rm -r <path_to_submodule> - person grisaitis; 15.07.2021

Недавно я обнаружил проект git, который включает множество полезных команд, связанных с git: https://github.com/visionmedia/git-extras

Установите его и введите:

git-delete-submodule submodule

Тогда дело сделано. Каталог подмодуля будет удален из вашего репо и все еще будет существовать в вашей файловой системе. Затем вы можете зафиксировать изменение, например: git commit -am "Remove the submodule".

person Chien-Wei Huang    schedule 08.10.2013
comment
Вы можете назвать это как git delete-submodule, поскольку git-extras должен находиться на пути к работе. Также обратите внимание, что я рекомендую не использовать git-extras, так как многие его части содержат очень много ошибок и опасны. I.E. git-delete-submodule, возможно, удаляет неправильный путь ниже .git/modules/*, поскольку предполагает, что модуль и путь идентичны (что довольно часто бывает не так), и это не работает правильно, если вы пытаетесь удалить подмодуль в подмодуле. git-extras может оказаться полезным на 99%, но, пожалуйста, не жалуйтесь, если при его использовании что-то пойдет не так. ВАС ПРЕДУПРЕЖДАЛИ! - person Tino; 25.11.2019

Мне пришлось сделать шаги Джона Даутата еще на один шаг и cd в каталог подмодуля, а затем удалить репозиторий Git:

cd submodule
rm -fr .git

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

person Kyle Clegg    schedule 23.11.2012
comment
Мне тоже пришлось сделать это, чтобы обойти фатальную ошибку: Not a git repository: error при попытке выполнить шаг git rm --cache. - person RickDT; 01.04.2013

Вот 4 шага, которые я нашел необходимыми или полезными (в первую очередь важные):

git rm -f the_submodule
rm -rf .git/modules/the_submodule
git config -f .git/config --remove-section submodule.the_submodule
git commit -m "..."

Теоретически git rm на шаге 1 должен позаботиться об этом. Надеюсь, что на вторую часть вопроса OP однажды можно будет ответить положительно (что это можно сделать с помощью одной команды).

Но с июля 2017 г. необходим шаг 2 для удаления данных в .git/modules/, иначе вы не сможете, например, добавить подмодуль в будущем.

Вероятно, вы можете обойтись без двух вышеуказанных шагов для git 1.8.5+, как указано в ответе tinlyx, поскольку все команды git submodule кажутся работать.

Шаг 3 удаляет раздел для the_submodule в файле .git/config. Это нужно сделать для полноты картины. (Эта запись может вызвать проблемы для более старых версий git, но у меня нет ее для тестирования).

Для этого в большинстве ответов предлагается использовать git submodule deinit. Мне кажется более явным и менее запутанным использование git config -f .git/config --remove-section. Согласно документации git-submodule, git deinit:

Отмените регистрацию данных подмодулей ... Если вы действительно хотите удалить подмодуль из репозитория и зафиксировать, используйте вместо этого git-rm [1] .

И последнее, но не менее важное: если вы не git commit, вы получите / можете получить ошибку при выполнении git submodule summary (начиная с git 2.7):

fatal: Not a git repository: 'the_submodule/.git'
* the_submodule 73f0d1d...0000000:

Это независимо от того, выполняете ли вы шаги 2 или 3.

person laser    schedule 01.07.2017

Я только что нашел скрытый файл .submodule (забыл точное имя), у него есть список ... вы можете стереть их индивидуально таким образом. У меня был только один, поэтому я удалил его. Просто, но это может испортить Git, так как я не знаю, прикреплено ли что-нибудь к подмодулю. Пока что вроде нормально, если не считать обычной проблемы с обновлением libetpan, но это (надеюсь) не связано.

Заметил, что никто не опубликовал ручное стирание, поэтому добавил

person Stephen J    schedule 16.06.2014

С git 2.17 и выше это просто:

git submodule deinit -f {module_name}
git add {module_name}
git commit
person Albert Tobac    schedule 12.04.2019
comment
Не сработало ни для git 2.17.1, ни для git 2.20.1. Однако использование git rm вместо git add работало для обоих. Примечания: -f не требуется, если все в порядке. Обязательно никогда не используйте параметры с git, если вы хотите защитить себя от непреднамеренной потери данных. Также обратите внимание, что это оставляет .git/modules/{module_name} на месте. Лучше оставить его там, потому что git выводит правильную (!) справку о том, как действовать, если что-то заблокировано из-за этого. - person Tino; 25.11.2019

Для удобства читателя здесь делается попытка подвести итог и дать пошаговое руководство о том, как это сделать, если что-то работает не так, как ожидалось. Ниже приводится проверенный и безопасный способ для git версии 2.17 и выше избавиться от подмодуля:

submodule="path/to/sub"              # no trailing slash!
git submodule deinit -- "$submodule"
git rm -- "$submodule"
  • Если это не сработает, см. Ниже.
  • Без вариантов. Ничего опасного. И даже не думайте делать больше!
  • Протестировано с Debian Buster 2.20.1 и Ubuntu 18.04 2.17.1.
  • "$submodule" просто чтобы подчеркнуть, где поставить имя, и что вы должны быть осторожны с пробелами и т.п.
  • Если в Windows проигнорируйте первую строку и замените "$submodule" на путь Windows правильно указанного пути к подмодулю. (Я не винда)

Предупреждение!

Никогда не прикасайтесь к внутренностям .git каталога сами! Редактирование внутри .git ведет к темной стороне. Держитесь подальше любой ценой!

И да, вы можете винить git в этом, так как в прошлом git не хватало многих удобных вещей. Как правильный способ снова удалить подмодули.

Я думаю, что в документации на git submodule есть очень опасная часть. Рекомендует удалить $GIT_DIR/modules/<name>/ самостоятельно. Насколько я понимаю, это не только неправильно, но и чрезвычайно опасно и может вызвать серьезные головные боли в будущем! См. ниже.

Обратите внимание, что

git module deinit

является прямым обратным к

git module init

но

git submodule deinit -- module
git rm -- module

также совершенно противоположно

git submodule add -- URL module
git submodule update --init --recursive -- module

потому что некоторые команды в основном должны делать больше, чем просто одну вещь:

  • git submodule deinit -- module
    • (1) updates .git/config
  • git rm
    • (2) removes the files of the module
    • (3) тем самым рекурсивно удаляет подмодули подмодуля
    • (4) обновления .gitmodules
  • git submodule add
    • pulls in the data to .git/modules/NAME/
    • (1) делает git submodule init, поэтому обновляет .git/config
    • (2) выполняет git submodule update, поэтому нерекурсивно проверяет модуль
    • (4) обновления .gitmodules
  • git submodule update --init --recursive -- module
    • pulls in further data if needed
    • (3) рекурсивно проверяет подмодули подмодуля

Это не может быть полностью симметричным, так как сохранять его строго симметричным не имеет особого смысла. Больше двух команд просто не нужно. Также «извлечение данных» подразумевается, потому что оно вам нужно, но удаление кэшированной информации не выполняется, потому что это вообще не нужно и может стереть ценные данные.

Это действительно озадачивает новичков, но в основном это хорошо: git просто делает то, что очевидно, и делает это правильно, и даже не пытается делать больше. git - это инструмент, который должен выполнять надежную работу, а не просто очередной «Eierlegende Wollmilchsau» («Eierlegende Wollmilchsau» переводится для меня как «злая версия швейцарского армейского ножа»).

Так что я понимаю жалобы людей, которые говорят: «Почему бы мне не сделать git очевидную вещь». Это потому, что «очевидное» здесь зависит от точки зрения. Надежность в любой ситуации гораздо важнее. Следовательно, то, что для вас очевидно, часто не является правильным во всех возможных технических ситуациях. Пожалуйста, помните: AFAICS git следует техническому, а не социальному пути. (Отсюда и хитрое название: git)

Если это не удается

Приведенные выше команды могут завершиться ошибкой по следующим причинам:

  • Ваш git слишком старый. Тогда используйте более новый git. (См. Ниже, как это сделать.)
  • У вас есть незафиксированные данные, и вы можете их потерять. Тогда лучше сначала зафиксируйте их.
  • Ваш подмодуль нечист в git clean смысле. Затем сначала очистите свой подмодуль с помощью этой команды. (См. ниже.)
  • Вы сделали что-то в прошлом, что не поддерживается git. Тогда вы перейдете на темную сторону, и все станет уродливым и сложным. (Возможно, это исправит использование другой машины.)
  • Возможно, есть другие способы потерпеть неудачу, о которых я не знаю (я просто какой-то git опытный пользователь).

Возможные исправления приведены ниже.

Используйте более новую git

Если ваша машина слишком старая, в вашем git нет submodule deinit. Если вы не хотите (или можете) обновлять свой git, просто используйте другой компьютер с более новым git! git предназначен для полного распространения, поэтому вы можете использовать другой git для выполнения работы:

  • workhorse:~/path/to/worktree$ git status --porcelain не должен ничего выводить! Если это так, сначала очистите вещи!
  • workhorse:~/path/to/worktree$ ssh account@othermachine
  • othermachine:~$ git clone --recursive me@workhorse path/to/worktree/.git TMPWORK && cd TMPWORK
  • Теперь займемся подмодулем
  • othermachine:~/TMPWORK$ git commit . -m . && exit
  • workhorse:~/path/to/worktree$ git fetch account@othermachine:TMPWORK/.git
  • workhorse:~/path/to/worktree$ git merge --ff-only FETCH_HEAD. Если это не сработает, используйте git reset --soft FETCH_HEAD
  • Теперь убирайте вещи, пока git status снова не станет чистым. Вы можете это сделать, потому что уже успели очистить его, благодаря первому шагу.

Это othermachine может быть какая-то виртуальная машина или какой-нибудь Ubuntu WSL под Windows, что угодно. Даже chroot (но я предполагаю, что вы не root, потому что если вы root, вам будет проще перейти на более новую git).

Обратите внимание: если вы не можете ssh войти, существует масса способов транспортировать git репозитории. Вы можете скопировать свое рабочее дерево на какой-нибудь USB-накопитель (включая каталог .git) и клонировать с него. Клонируйте копию, чтобы снова получить чистую информацию. Это может быть PITA, если ваши подмодули недоступны напрямую с другой машины. Но и для этого есть решение:

git config --add url.NEWURLPREFIX.insteadOf ORIGINALURLPREFIX

Вы можете использовать это умножение, и оно сохраняется в $HOME/.gitconfig. Что-то вроде

git config --add 'url./mnt/usb/repo/.insteadof' https://github.com/

перезаписывает URL-адреса, например

https://github.com/XXX/YYY.git

в

/mnt/usb/repo/XXX/YYY.git

Это легко, если вы начнете привыкать к таким мощным git функциям.

Очистите вещи в первую очередь

Очистка вручную - это хорошо, потому что таким образом вы, возможно, обнаружите некоторые вещи, о которых забыли.

  • Если git жалуется на несохраненный материал, зафиксируйте его и отправьте в безопасное место.
  • Если git жалуется на остатки, git status и git clean -ixfd ваш друг.
  • Постарайтесь как можно дольше воздерживаться от вариантов rm и deinit. Варианты (например, -f) для git хороши, если вы профессионал. Но когда вы пришли сюда, вы, вероятно, не так уж опытны в области submodule. Так что лучше перестраховаться, чем сожалеть.

Пример:

$ git status --porcelain
 M two
$ git submodule deinit two
error: the following file has local modifications:
    two
(use --cached to keep the file, or -f to force removal)
fatal: Submodule work tree 'two' contains local modifications; use '-f' to discard them
$ cd two
$ git submodule deinit --all
error: the following file has local modifications:
    md5chk
(use --cached to keep the file, or -f to force removal)
fatal: Submodule work tree 'md5chk' contains local modifications; use '-f' to discard them
$ cd md5chk
$ git submodule deinit --all
error: the following file has local modifications:
    tino
(use --cached to keep the file, or -f to force removal)
fatal: Submodule work tree 'tino' contains local modifications; use '-f' to discard them
$ cd tino
$ git status --porcelain
?? NEW
$ git clean -i -f -d
Would remove the following item:
  NEW
*** Commands ***
    1: clean                2: filter by pattern    3: select by numbers    4: ask each
    5: quit                 6: help
What now> 1
Removing NEW
$ cd ../../..
$ git status --porcelain
$ git submodule deinit two
Cleared directory 'two'
Submodule 'someunusedname' (https://github.com/hilbix/src.git) unregistered for path 'two'

Видите ли, на submodule deinit не требуется -f. Если все чисто, в git clean смысле. Также обратите внимание, что git clean -x не требуется. Это означает, что git submodule deinit безоговорочно удаляет неотслеживаемые файлы, которые игнорируются. Обычно это именно то, что вам нужно, но не забывайте об этом. Иногда игнорируемые файлы могут быть ценными, например, кэшированные данные, на повторный расчет которых уходит от нескольких часов до дней.

Почему никогда не удалять $GIT_DIR/modules/<name>/?

Вероятно, люди хотят удалить кешированный репозиторий, потому что боятся столкнуться с проблемой позже. Это правда, но столкновение с этой «проблемой» - правильный способ ее решить! Поскольку исправить это легко и сделать правильно, вы сможете жить долго и счастливо. Это позволяет избежать более громоздких проблем, чем когда вы удаляете данные самостоятельно.

Пример:

mkdir tmptest &&
cd tmptest &&
git init &&
git submodule add https://github.com/hilbix/empty.git two &&
git commit -m . &&
git submodule deinit two &&
git rm two &&
git commit -m . &&
git submodule add https://github.com/hilbix/src.git two

Последняя строка выводит следующую ошибку:

A git directory for 'two' is found locally with remote(s):
  origin    https://github.com/hilbix/empty.git
If you want to reuse this local git directory instead of cloning again from
  https://github.com/hilbix/src.git
use the '--force' option. If the local git directory is not the correct repo
or you are unsure what this means choose another name with the '--name' option.

Почему эта ошибка? Поскольку .git/modules/two/ ранее заполнялся из https://github.com/hilbix/empty.git, а теперь должен быть повторно заполнен чем-то еще, а именно https://github.com/hilbix/src.git. Вы не увидите этого, если повторно заполните его с https://github.com/hilbix/empty.git

Что делать сейчас? Что ж, делай в точности как сказали! Используйте --name someunusedname

git submodule add --name someunusedname https://github.com/hilbix/src.git two

.gitmodules тогда выглядит как

[submodule "someunusedname"]
    path = two
    url = https://github.com/hilbix/src.git

ls -1p .git/modules/ дает

someunusedname/
two/

Таким образом, в будущем вы можете переключать ветки / коммит вперед и назад и никогда больше не столкнетесь с какими-либо проблемами из-за two/ наличия двух разных (и, возможно, несовместимых) исходных репозиториев. И самое лучшее: вы также храните оба кешированных локально.

  • Это верно не только для вас. Это также верно для всех остальных, использующих ваш репозиторий.
  • И вы не потеряете историю. Если вы забыли установить самую последнюю версию старого подмодуля, вы можете ввести локальную копию и сделать это позже. Обратите внимание, что довольно часто кто-то забывает подтолкнуть некоторые подмодули (потому что это PITA для новичков, пока они не привыкнут к git).

Однако, если вы удалите кэшированный каталог, обе разные проверки будут сталкиваться друг с другом, потому что вы не будете использовать параметры --name, верно? Поэтому каждый раз, когда вы выполняете оформление заказа, вам, возможно, придется снова и снова удалять каталог .git/modules/<module>/. Это чрезвычайно громоздко и затрудняет использование чего-то вроде git bisect.

Таким образом, существует очень техническая причина сохранить этот каталог модуля в качестве заполнителя. Люди, которые рекомендуют удалить что-то ниже .git/modules/, либо не знают, либо забывают сказать вам, что это делает практически невозможным использование таких мощных функций, как git bisect, если это пересекает несовместимость таких подмодулей.

Еще одна причина указана выше. Посмотрите на ls. Что ты там видишь?

Ну, второй вариант модуля two/ не под .git/modules/two/, он под .git/modules/someunusedname/! Так что такие вещи, как git rm $module; rm -f .git/module/$module, совершенно неправильны! Вы должны проконсультироваться с module/.git или .gitmodules, чтобы найти то, что нужно удалить!

Так что не только большинство других ответов попадают в эту опасную ловушку, даже очень популярные расширения git имели эту ошибку < / a> (теперь там исправлено)! Так что лучше держите в руках каталог .git/, если вы не совсем то, что делаете!

А с философской точки зрения стирать историю всегда неправильно! Как обычно, кроме квантовой механики, но это совсем другое.

К вашему сведению, вы, наверное, догадались: hilbix - это моя учетная запись GitHub.

person Tino    schedule 25.11.2019
comment
Эта энциклопедия сообщения должна быть разбита на более четкие разделы с более крупными / более четкими подзаголовками, чтобы указать фактический ответ, и различные разделы по устранению неполадок и т. Д. - person Andrew; 19.01.2020

С git v2.7.4 простые 3 шага работали нормально.

git submodule deinit -f -- a/submodule    
git rm -f a/submodule
git commit
person Yuriy Pozniak    schedule 19.03.2021

Если вы только что добавили подмодуль, и, например, вы просто добавили не тот подмодуль или добавили его не в то место, просто выполните git stash, а затем удалите папку. Предполагается, что добавление подмодуля - единственное, что вы сделали в недавнем репо.

person botbot    schedule 01.06.2016

Подводя итог, вот что вам следует сделать:

Установите переменную path_to_submodule (без косой черты в конце):

path_to_submodule=path/to/submodule

Удалите соответствующую строку из файла .gitmodules:

git config -f .gitmodules --remove-section submodule.$path_to_submodule

Удалите соответствующий раздел из .git / config

git config -f .git/config --remove-section submodule.$path_to_submodule

Деактивировать и удалить $ path_to_submodule только из индекса (для предотвращения потери информации)

git rm --cached $path_to_submodule

Отслеживайте изменения, внесенные в .gitmodules

git add .gitmodules

Зафиксируйте суперпроект

git commit -m "Remove submodule submodule_name"

Удалите теперь неотслеживаемые файлы подмодулей

rm -rf $path_to_submodule

rm -rf .git/modules/$path_to_submodule

См. Также: Альтернативные рекомендации

person Rahul Dapke    schedule 19.12.2019
comment
Не могли бы вы расширить это, указав, как удалить подмодуль после 'git submodule add', но еще не зафиксировав его? Я предполагаю, что в этом случае для удаления подмодуля не требуется фиксации, верно? - person Carlo Wood; 03.01.2020
comment
Думаю нужно поменять местами git rm --cached $path_to_submodule и git add .gitmodules нет? Я получил ошибку при выполнении первой команды: fatal: Please stage your changes to .gitmodules or stash them to proceed, потому что у меня были неустановленные изменения в .gitmodules. Выполнение git add .gitmodules первым решает эту проблему. - person Carlo Wood; 03.01.2020

Я создал сценарий bash, чтобы упростить процесс удаления. Он также проверяет, есть ли изменения в репо, оставшиеся несохраненными, и запрашивает подтверждение. Он был протестирован на os x. Было бы интересно узнать, работает ли он так же, как и в обычных дистрибутивах Linux:

https://gist.github.com/fabifrank/cdc7e67fd194333760b060835ac0172f

person Techradar    schedule 22.05.2019

В последнем git требуется всего 4 операции для удаления подмодуля git.

  • Удалить соответствующую запись в .gitmodules
  • Изменения стадии git add .gitmodules
  • Удалите каталог подмодуля git rm --cached <path_to_submodule>
  • Зафиксировать git commit -m "Removed submodule xxx"
person rashok    schedule 01.03.2019

Если вам нужно сделать это с помощью однострочной команды с помощью сценария bash, как показано ниже:

$ cd /path/to/your/repo && /bin/bash $HOME/remove_submodule.sh /path/to/the/submodule

Создайте файл сценария bash в каталоге $HOME с именем, например, remove_submodule.sh:

#!/bin/bash

git config -f .gitmodules --remove-section submodule.$1
git config -f .git/config --remove-section submodule.$1
git rm --cached $1
git add .gitmodules
git commit -m "Remove submodule in $1"
rm -rf $1
rm -rf .git/modules/$1
git push origin $(git rev-parse --abbrev-ref HEAD) --force --quiet

person Chetabahana    schedule 11.09.2019

  • A submodule can be deleted by running git rm <submodule path> && git commit. This can be undone using git revert.
    • The deletion removes the superproject's tracking data, which are both the gitlink entry and the section in the .gitmodules file.
    • Рабочий каталог подмодуля удаляется из файловой системы, но каталог Git сохраняется, чтобы можно было проверять прошлые коммиты, не требуя выборки из другого репозитория.
  • Чтобы полностью удалить подмодуль, дополнительно удалите $GIT_DIR/modules/<name>/.

Источник: git help submodules

person Porcupine    schedule 24.11.2019

Это сработало для меня. Вышеупомянутые ответы показали это в терминале, и больше ничего не происходило

'fatal: not removing 'demolibapp' recursively without -r'
  1. demolibapp - это имя моего подмодуля, который я хочу удалить
  2. Подмодуль git deinit demolibapp
  3. git rm --cached demolibapp -r
  4. rm -rf .git / модули / demolibapp
  5. git add --all
  6. git commit -m удаление лишних подмодулей
  7. git push
  8. rm -rf demolibapp
person Pooja    schedule 19.07.2021

Удаление подмодуля git

Чтобы удалить подмодуль git, необходимо выполнить ниже 4 шага.

  1. Удалите соответствующую запись в .gitmodules файле. Запись может быть такой, как указано ниже
[submodule "path_to_submodule"]
    path = path_to_submodule
    url = url_path_to_submodule
  1. Изменения стадии git add .gitmodules
  2. Удалите каталог подмодулей git rm --cached <path_to_submodule>.
  3. Зафиксируйте git commit -m "Removed submodule xxx" и нажмите.

Дополнительные 2 шага, упомянутые ниже, необходимы для полной очистки подмодуля в локальной клонированной копии.

  1. Удалите соответствующую запись в .git/config файле. Запись может быть такой, как указано ниже
[submodule "path_to_submodule"]
    url = url_path_to_submodule
  1. Do rm -rf .git/modules/path_to_submodule

Эти 5-й и 6-й шаги не создают никаких изменений, требующих фиксации.

person rashok    schedule 22.11.2019
comment
Было бы намного проще, если бы вы использовали git submodule deinit git-scm.com/docs/git-submodule#Documentation/ - person Black; 31.01.2020