Как удалить субмодуль Git?
Кстати, есть ли причина, по которой я не могу просто сделать git submodule rm whatever
?
Как удалить субмодуль Git?
Кстати, есть ли причина, по которой я не могу просто сделать git submodule rm whatever
?
Начиная с версии 1.8.3 (22 апреля 2013 г.):
Не было никакого фарфорового способа сказать "я больше не заинтересован в этом подмодуле", когда вы выразили свою заинтересованность в подмодуле с помощью "
submodule init
".
"submodule deinit
" является способом сделать это.
В процессе удаления также используется git rm
(с git1.8.5 October 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
: это упоминается в ответе Даниэля Шредера и обобщается Эонилем в комментариях:
Это оставляет
.git/modules/<path-to-submodule>/
без изменений.
Поэтому, если вы однажды удалите подмодуль с помощью этого метода и снова добавите их, это будет невозможно, поскольку хранилище уже повреждено.
git rm
: см. commit 95c16418:
В настоящее время использование "
git rm
" в подмодуле удаляет рабочее дерево подмодуля из дерева суперпроекта, а gitlink - из индекса.
Но секция подмодулей в.gitmodules
оставлена нетронутой, что является остатком теперь удаленного подмодуля и может раздражать пользователей (в отличие от параметра в.git/config
, это должно напоминать, что пользователь проявил интерес к этому подмодулю поэтому он будет заполнен позже, когда будет проверен более старый коммит).Позвольте "
git rm
" помочь пользователю, не только удаляя подмодуль из рабочего дерева, но также удаляя раздел "submodule.<submodule name>
" из файла.gitmodules
и.gitmodules
оба этапа.
git submodule deinit
: Это происходит из этого патча:
С помощью "
git submodule init
" пользователь может сказать git, что он заботится об одном или нескольких подмодулях, и хочет, чтобы он был заполнен при следующем вызове "git submodule update
".
Но в настоящее время нет простого способа, которым они могут сказать git, что они больше не заботятся о подмодуле и хотят избавиться от локального рабочего дерева (если пользователь не знает много о внутренностях подмодуля и не удаляет "submodule.$name.url
"). настройка из.git/config
вместе с самим рабочим деревом).Помогите этим пользователям, предоставив команду
deinit
.
Это удаляет весьsubmodule.<name>
.git/config
submodule.<name>
из.git/config
либо для данного подмодуля (-ов) (либо для всех тех, которые были инициализированы, если задано '.
').
Ошибка, если текущее рабочее дерево содержит изменения, если не принудительно.
Пожаловаться, когда для подмодуля, заданного в командной строке, параметр URL не может быть найден в.git/config
, но, тем не менее, не происходит сбой.
Это заботится, если (де) шаги инициализации (.git/config
и .git/modules/xxx
)
Начиная с git1.8.5, git rm
также заботится о:
add
, который записывает URL-адрес подмодуля в файле .gitmodules
: его нужно удалить за вас.git rm --cached path_to_submodule
(без косой черты) Если вы забудете этот последний шаг и попытаетесь добавить субмодуль в обычный каталог, вы получите сообщение об ошибке, например:
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
- в коммите ead8dbe, 13 февраля 2018 г.)
git ${wt_prefix:+-C "$wt_prefix"} submodule--helper deinit \
${GIT_QUIET:+--quiet} \
${prefix:+--prefix "$prefix"} \
${force:+--force} \
${deinit_all:+--all} "[email protected]"
Через страницу Git Submodule Tutorial:
Для удаления подмодуля вам необходимо:
.gitmodules
..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
выполнит большую часть задания на подмодуле.
- Обновление (07/05/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 .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
в конце, если вы поместите это в script.
Также посмотрите ответ на вопрос: могу ли я отключить подмодуль Git?.
В дополнение к рекомендациям я также должен был rm -Rf .git/modules/path/to/submodule
добавить новый подмодуль с тем же именем (в моем случае я заменил вилку оригиналом)
Чтобы удалить добавленный подмодуль, используя:
git submodule add [email protected]:repos/blah.git lib/blah
Run:
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, вероятно, кто-то сделает для вас оболочку script.
Вы можете использовать псевдоним для автоматизации решений, предоставляемых другими:
[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
FWIW, я также удалил папку .git
, прежде чем делать git add
.
Я нашел, что deinit
работает хорошо для меня:
git submodule deinit <submodule-name>
git rm <submodule-name>
От git docs:
Deinit
Отмените регистрацию данных подмодулей, т.е. удалите все
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.) Commit:
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"
.
Мне пришлось занять John Douthat еще один шаг и 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+, как отмечал ответ 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.
Я просто нашел скрытый файл .submodule(забыли точное имя), у него есть список... вы можете стереть их индивидуально таким образом. У меня только один, поэтому я удалил его. Простой, но это может испортить Git, так как я не знаю, связано ли что-либо с подмодулем. Кажется, пока что, кроме обычной проблемы с выпуском libetpan, но это (надеюсь) не связано.
Заметили, что никто не опубликовал ручное удаление, поэтому добавил
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
Если вы только что добавили подмодуль, и, например, вы просто добавили неправильный субмодуль или вы добавили его в неправильное место, просто выполните 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
Сделайте следующее
cd Yoursubmodule
rm -force .git
В последнем git требуется всего 4 операции для удаления подмодуля git.
.gitmodules
git add.gitmodules
git rm --cached <path_to_submodule>
git commit -m "Removed submodule xxx"