Вопрос
Как удалить подмодуль Git?
Кстати, есть ли причина, по которой я не могу просто сделатьgit submodule rm whatever
?
Решение
С git1.8.3 (22 апреля 2013 г.):
В Porcelain не было способа сказать: «Меня больше не интересует этот подмодуль», как только вы выражаете свой интерес к подмодулю с помощью «
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
:Об этом упоминается в Дэниел Шредер's отвечать, и резюмировано Эонил в комментарии:
Это оставляет
.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 (второй квартал 2018 г.), подмодуль git deinit больше не является сценарием оболочки.
Это вызов функции C.
Видеть зафиксировать 2e61273, совершить 1342476 (14 января 2018 г.) автор: Пратамеш Чаван (англ.pratham-pc
).
(Объединено Джунио С. Хамано -- gitster
-- в зафиксировать ead8dbe, 13 фев 2018 г.)
git ${wt_prefix:+-C "$wt_prefix"} submodule--helper deinit \
${GIT_QUIET:+--quiet} \
${prefix:+--prefix "$prefix"} \
${force:+--force} \
${deinit_all:+--all} "$@"
Другие советы
Через страницу Учебное пособие по подмодулю Git:
Чтобы удалить субмодуль, вам необходимо:
- Удалите соответствующий раздел из
.gitmodules
файл. - Постановка
.gitmodules
изменения:git add .gitmodules
- Удалить соответствующий раздел из
.git/config
. - Удалите файлы подмодуля из рабочего дерева и проиндексируйте:
git rm --cached path_to_submodule
(без косой черты в конце). - Удалить субмодуль
.git
каталог:rm -rf .git/modules/path_to_submodule
- Зафиксируйте изменения:
git commit -m "Removed submodule <name>"
- Удалите теперь неотслеживаемые файлы подмодуля:
rm -rf path_to_submodule
Смотрите также: альтернативные шаги ниже.
Просто примечание.Начиная с 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
Большинство ответов на этот вопрос устарели, неполны или излишне сложны.
Подмодуль, клонированный с помощью 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
Простые шаги
- Удалить записи конфигурации:
git config -f .git/config --remove-section submodule.$submodulename
git config -f .gitmodules --remove-section submodule.$submodulename
- Удалить каталог из индекса:
git rm --cached $submodulepath
- Совершить
- Удалите неиспользуемые файлы:
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?.
Помимо рекомендаций мне пришлось еще rm -Rf .git/modules/path/to/submodule
чтобы можно было добавить новый субмодуль с тем же именем (в моем случае я заменял форк на оригинал)
Чтобы удалить добавленный подмодуль, используйте:
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
Вы должны удалить запись в .gitmodules
и .git/config
, и удалите каталог модуля из истории:
git rm --cached path/to/submodule
Если вы напишите в список рассылки git, вероятно, кто-нибудь напишет для вас сценарий оболочки.
Вы можете использовать псевдоним для автоматизации решений, предоставляемых другими:
[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
Подводя итог, вот что вам следует сделать:
Набор
path_to_submodule
var (без косой черты):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
Если субмодуль был случайно добавлено, потому что вы добавили, зафиксировали и отправили папку, которая уже была репозиторием Git (содержала .git
), у вас не будет .gitmodules
файл для редактирования или что-нибудь в .git/config
. В этом случае все, что вам нужно является :
git rm --cached subfolder
git add subfolder
git commit -m "Enter message here"
git push
ПВИВ, я также удалил .git
папку перед выполнением git add
.
я нашел deinit
у меня работает хорошо:
git submodule deinit <submodule-name>
git rm <submodule-name>
От git-документы:
деинит
Отмените регистрацию данных подмодулей, т.е.удалить весь
submodule.$name
раздел из .git/config вместе со своим рабочим деревом.
Поэкспериментировав со всеми разными ответами на этом сайте, я пришел к такому решению:
#!/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)
Что я сейчас делаю в декабре 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}"
Вот что я сделал:
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
Недавно я обнаружил проект git, который включает в себя множество полезных команд, связанных с git: https://github.com/visionmedia/git-extras
Установите его и введите:
git-delete-submodule submodule
Тогда дело сделано.Каталог подмодуля будет удален из вашего репозитория и все еще будет существовать в вашей файловой системе.Затем вы можете зафиксировать изменение следующим образом: git commit -am "Remove the submodule"
.
Мне пришлось пойти по стопам Джона Даутата на шаг дальше и cd
в каталог подмодуля, а затем удалите репозиторий Git:
cd submodule
rm -fr .git
Тогда я мог бы зафиксировать файлы как часть родительского репозитория Git без старой ссылки на подмодуль.
Вот 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 должен позаботиться об этом.Будем надеяться, что однажды на вторую часть вопроса ОП можно будет ответить положительно (что это можно сделать с помощью одной команды).
Но по состоянию на июль 2017 г. шаг 2 необходимо удалить данные в .git/modules/
иначе вы не сможете, например.добавьте подмодуль обратно в будущем.
Вероятно, вам удастся выполнить два вышеуказанных шага для git 1.8.5+, поскольку ответ Тилинкса отметил, как и все git submodule
команды вроде работают.
Шаг 3 удаляет раздел для the_submodule
в файле .git/config
.Это нужно сделать для полноты.(Эта запись может вызвать проблемы в старых версиях git, но у меня нет ни одной, которую можно было бы протестировать).
Для этого большинство ответов предлагают использовать git submodule deinit
.Я считаю, что это более понятно и менее запутанно в использовании. git config -f .git/config --remove-section
.Согласно документация git-подмодуля, 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.
project dir: ~/foo_project/
submodule: ~/foo_project/lib/asubmodule
- - - - - - - - - - - - - - - - - - - - - - - - -
run:
1. cd ~/foo_project
2. git rm lib/asubmodule &&
rm .git/modules/lib/asubmodule &&
git submodule lib/asubmodule deinit --recursive --force
Я только что нашел скрытый файл .submodule (забыл точное имя), у него есть список...таким образом вы можете стереть их по отдельности.У меня был только один, поэтому я его удалил.Просто, но это может испортить Git, поскольку я не знаю, прикреплено ли что-нибудь к подмодулю.Пока все в порядке, за исключением обычной проблемы с обновлением libetpan, но это (надеюсь) не связано.
Заметил, что никто не писал о ручном удалении, поэтому добавил.
Если вы только что добавили субмодуль и, например, просто добавили не тот субмодуль или добавили его не в то место, просто выполните git stash
затем удалите папку.Это предполагает, что добавление подмодуля — это единственное, что вы сделали в недавнем репозитории.
С git 2.17 и выше это просто:
git submodule deinit -f {module_name}
git add {module_name}
git commit
Я создал сценарий bash, чтобы облегчить процесс удаления.Он также проверяет, остались ли в репозитории несохраненные изменения, и запрашивает подтверждение.Он был протестирован на os x
было бы интересно узнать, работает ли это так же и в обычных дистрибутивах Linux:
https://gist.github.com/fabifrank/cdc7e67fd194333760b060835ac0172f
В последней версии git для удаления подмодуля git требуется всего 4 операции.
- Удалить соответствующую запись в
.gitmodules
- Изменения этапов
git add .gitmodules
- Удалить каталог подмодуля
git rm --cached <path_to_submodule>
- Совершить это
git commit -m "Removed submodule xxx"
В случае, если вам нужно сделать это в одна строка команды с помощью сценария 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