Как удалить субмодуль? - PullRequest
3250 голосов
/ 11 августа 2009

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

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

Ответы [ 24 ]

3295 голосов
/ 11 августа 2009

Через страницу Учебник по Git Submodule :

Для удаления подмодуля вам необходимо:

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

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

1978 голосов
/ 23 апреля 2013

С git1.8.3 (22 апреля 2013 г.) :

Не было никакого Фарфорового способа сказать «Я больше не заинтересован в этом подмодуле», когда вы выразили свою заинтересованность в подмодуле с помощью «submodule init».
«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: Это упоминается в Даниэль Шредер ответ , и суммируется 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 принимает , а также заботится о:

  • 'add' шаг, который записывает URL подмодуля в файл .gitmodules: его нужно удалить за вас.
  • подмодуль специальная запись (как показано этим вопросом ): git rm удаляет его из индекса:
    git rm --cached path_to_submodule (без косой черты)
    Это удалит этот каталог, сохраненный в индексе в специальном режиме «160000», пометив его как корневой каталог подмодуля.

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

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

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

См. коммит 2e61273 , коммит 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} "$@"
411 голосов
/ 19 января 2014

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

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

Как правильно указал ответ @Mark Cheverton, если вторая строка не используется, даже если вы удалили субмодуль на данный момент, оставшаяся папка .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
372 голосов
/ 13 апреля 2016

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

Подмодуль, клонированный с использованием 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
192 голосов
/ 04 октября 2011

Простые шаги

  1. Удалить записи конфигурации:
    git config -f .git/config --remove-section submodule.$submodulename
    git config -f .gitmodules --remove-section submodule.$submodulename
  2. Удалить каталог из индекса:
    git rm --cached $submodulepath
  3. Commit
  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? .

81 голосов
/ 02 марта 2012

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

52 голосов
/ 12 октября 2013

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

git submodule add blah@blah.com: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
48 голосов
/ 11 августа 2009

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

git rm --cached path/to/submodule

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

41 голосов
/ 02 ноября 2012

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

[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 config, и тогда вы можете сделать: git rms path/to/submodule

40 голосов
/ 09 июля 2012

Подводя итог, вот что вы должны сделать:

  1. Set 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

...