Как удалить подмодуль Git?
Кстати, по какой причине я не могу просто сделать git submodule rm whatever
?
Как удалить подмодуль Git?
Кстати, по какой причине я не могу просто сделать git submodule rm whatever
?
Поскольку 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
также заботится о:
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 (второй квартал 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} "$@"
submodule deinit
?
- person zakdances; 28.04.2013
git submodule deinit
не удаляет соответствующий каталог из .git/config
. Он все еще там, пока я не удалю его вручную.
- person zakdances; 29.05.2013
.gitmodules
должен быть в порядке, но я бы все равно перепроверил что-либо с помощью каталога .git
(т.е. конфигурации local, в вашем локальном репо: это не изменяется git pull
)
- person VonC; 04.06.2013
git submodule deinit
? Но если нет, то да, вы можете вручную очистить лишние метаданные.
- person VonC; 06.06.2013
.gitmodules
и удаления специальной записи в индексе, а затем отправите это репо, другие могут вытащить его, и этот подмодуль исчезнет.
- person VonC; 02.08.2013
deinit
в git-submodule(1)
теперь рекомендует использовать git rm
: если вы действительно хотите удалить подмодуль из репозитория и зафиксировать, используйте вместо этого git-rm (1).
- person mgalgs; 08.08.2013
PATH
и git remove-submodule path/to/submodule
.
- person Adam Sharp; 21.08.2013
git-remove-submodule ...
вместо git remove-submodule ....
?
- person kenny; 24.08.2013
git remove-submodule
» (с пробелом) будет искать исполняемый файл «git-remove-submodule
» (с тире) в любом месте вашего $PATH
.
- person VonC; 24.08.2013
git rm -rf "$submodule_name"
(обратите внимание на флаг -r
)? Если это сработает, я соответствующим образом обновлю скрипт.
- person Adam Sharp; 04.09.2013
git submodule deinit
доступен только с 1.8.3+. Обратите внимание, что, как я упоминал в моем отредактированном ответе выше, git rm asubmodule
скоро обо всем позаботится.
- person VonC; 16.09.2013
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
git rm yourSubmodule
теперь удаляет подмодуль из рабочего дерева и .gitmodules
файлов.
- person VonC; 07.01.2014
deinit
и rm
, похоже, работают с путями, и у меня это хорошо сработало с завершающей косой чертой на asubmodule
с обеими командами. (git v. 1.9.1)
- person desseim; 27.03.2014
git rm submodule
делает именно то, что вы хотите, как уже говорили другие люди.
- person Pete Peterson; 12.06.2014
git rm -rf --cached /path/to/submodule
убирает подмодуль. Тогда git commit
. Если я не хотел, чтобы папка добавлялась как подмодуль, я просто удаляю .git
в path/to/folder
и git add /path/to/folder
.
- person aubreypwd; 25.09.2014
.git/modules/<path-to-submodule>/
без изменений. Поэтому, если вы однажды удалите подмодуль этим методом и снова добавите его, это будет невозможно, потому что репозиторий уже поврежден.
- person eonil; 24.10.2014
git --version
). Это для git 1.8.3+. Если ваша версия слишком старая, вы сможете легко ее обновить (например: stackoverflow.com/a/24847953/6309 < / а>)
- person VonC; 06.02.2015
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
rm -rf .git/modules/a/submodule
является необратимым, если все коммиты в репозитории подмодуля не были отправлены на удаленный компьютер. (Если их подтолкнули, могу ли я предположить, что проверка прошлой фиксации восстанавливает все? Я добавил stackoverflow.com/q/61963342/8910547, чтобы представить альтернативный сценарий. Или, возможно, этот вопрос и ваш ответ можно отредактировать, чтобы уточнить, и в этом случае я могу просто удалить свой новый вопрос как лишний.
- person Inigo; 22.05.2020
На странице Учебник по подмодулю 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 submodule rm
просто удаляет регистрацию подмодуля, и будет удивлен, если команда также удалит локальный репозиторий. Любые локальные изменения были бы безвозвратно потеряны. И, возможно, другой человек подумает, что будут удалены только файлы.
- person John Douthat; 21.01.2011
git rm --cached -f submodule_name
, теперь все работает.
- person Matthias; 13.01.2012
git submodule rm
должно быть командой. Эта установка становится более сложной, если у вас есть подмодули внутри подмодулей, потому что местоположение ваших .git/config
меняется.
- person Justin Force; 23.08.2012
git rm --cached path_to_sub/*
- person Dzung Nguyen; 25.08.2012
.gitmodules
будет отправлен в мастер, так что все увидят изменение. Однако соответствующий раздел в .git/config
не будет передан другим пользователям. Это просто локальная настройка с информацией о репозитории клонированного подмодуля. При необходимости другим людям в вашем проекте все равно придется удалить репозиторий подмодуля. Git не может точно знать, есть ли у других людей какие-либо неопубликованные изменения в этом репо, поэтому для git было бы небезопасно автоматически удалять их копию.
- person John Douthat; 03.10.2012
.git/
с этим подмодулем? Предположим, вы сняли его и толкнули / потянули. Должен быть git submodule rm -f XXX
, чтобы избежать потери данных.
- person Wernight; 09.05.2013
--cached
для шага 4, вам не нужен шаг 7.
- person Jarl; 23.06.2013
git submodule deinit [-f]
- person hellboy; 08.09.2015
.gitmodules
. Затем вам нужно удалить каждый подмодуль git track и очистить каталог, а затем перестроить свой каталог ... почему так сложно удалить подмодуль ...
- person penny chan; 24.08.2017
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
-rf
? Я получаю сообщение об ошибке при попытке запустить эту (вторая команда; Windows-машина)
- person Thomas; 20.01.2017
rm -rf
не будет работать в Windows.
- person Simon East; 30.06.2017
rm -rf
означает просто удалить всю папку, чтобы вы могли сделать это из графического интерфейса проводника в Windows. В качестве альтернативы, если вы используете git в Windows, у вас также будет доступен git bash, поэтому вы можете запускать все эти команды там, и они будут работать, как есть.
- person Andy Madge; 08.12.2017
.git/modules
, которую вы уже удалили в приведенной выше строке. Добавление --
в первую строку, как принятый ответ, похоже, помогает.
- person Fmstrat; 28.06.2019
git v2.20.1
по-прежнему оставил .git/modules/submodule
рядом со мной на месте, так что rm
, похоже, понадобится сейчас или тогда. Если более новые git
s хотят удалить его, хорошо, просто поменяйте местами последние две команды. Также обратите внимание, что 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
.git/config
. Полный способ удаления подмодуля см. В stackoverflow.com/a/36593218/1562138.
- person fvgs; 13.04.2016
git rm
ДЕЙСТВИТЕЛЬНО удаляет раздел из .git / config, а также удаляет папки .git / modules / ...
- person drevicko; 22.02.2017
git init && git submodule add <repository> && git rm <name>
оставляет за собой запись .git/config
, каталог .git/modules/<name>
и его содержимое. Возможно, вы не инициализировали подмодуль перед его удалением?
- person fvgs; 22.02.2017
the_submodule
? Путь к подмодулю?
- person Jarrod Smith; 03.07.2017
Unlink of file '...' failed
- person Adam Burley; 01.03.2018
git rm -f path/to/submodule
, я думаю, что stackoverflow.com/a/36593218/2808203 - лучшее решение.
- person Darrell Ulm; 17.06.2020
.git/modules/
- person xealits; 13.11.2020
Простые шаги
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?.
for dir in directory/*; do git rm --cached $dir; done
.
- person Pablo Olmos de Aguilera C.; 10.10.2011
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
git submodule | grep '^+' | cut -d' ' -f2
- person errordeveloper; 12.10.2011
submodulename
в двойные кавычки "submodulename"
.., ссылаясь на файл .git/config
- person muon; 20.07.2017
В дополнение к рекомендациям мне также пришлось rm -Rf .git/modules/path/to/submodule
, чтобы иметь возможность добавить новый подмодуль с тем же именем (в моем случае я заменял вилку оригинальной)
Чтобы удалить добавленный подмодуль, используйте:
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
git rm
по-прежнему оставляет материал в .git/modules/
. (2.5.4)
- person Rudolf Adamkovič; 02.01.2016
git rm
, этого не произойдет; Быстрый тест с 2.5.4 на моем Mac обновляет файл .gitmodules, как описано в документации здесь: git-scm.com/docs/git-rm#_submodules ... но если вы нашли какую-то комбинацию платформы / версии, где этого не происходит, вам, вероятно, следует сообщить об ошибке Это.
- person Doug; 02.01.2016
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, возможно, кто-нибудь напишет для вас сценарий оболочки.
Подводя итог, вот что вам следует сделать:
Установите 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 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
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
.
Я обнаружил, что deinit
мне подходит:
git submodule deinit <submodule-name>
git rm <submodule-name>
Из git docs:
deinit
Отмените регистрацию данных подмодулей, т.е. удалите весь раздел
submodule.$name
из .git / config вместе с их рабочим деревом.
git
s, которые знают о deinit
, как другой ответ удаляет каталог .git/modules/submodule
слишком рано, что, кажется, приводит к тому, что новые git
время от времени выходят из строя. Также (см. Мой комментарий) удаление .git/modules/submodule
может быть неправильным путем, поэтому это опасный шаг, лучше всего его предпринять позже, только когда git
пожалуется (или если вы на 299% уверены, что это то, что вы хотите, это правильный путь и действительно нужен) .
- person Tino; 25.11.2019
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)
git rm --cached $path
, а затем rm -rf $path
вместо git rm -r $path
?
- person bfontaine; 29.11.2014
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}"
Вот что я сделал:
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
fatal: no submodule mapping found in .gitmodules for path 'submodule_name'
на шаге 3. Однако оба шага были необходимы. (git v2.8.2)
- person U007D; 25.08.2016
git submodule deinit <path to submodule>
.gitmodules
git rm <path to submodule>
git add .gitmodules
git submodule deinit <submodule_name>
и git rm <path_to_submodule>
. Последняя команда автоматически удаляет запись внутри .gitmodules
. Git 2.17
- person Dmytro Ovdiienko; 05.05.2020
-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"
.
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 без старой ссылки на подмодуль.
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.
Я только что нашел скрытый файл .submodule (забыл точное имя), у него есть список ... вы можете стереть их индивидуально таким образом. У меня был только один, поэтому я удалил его. Просто, но это может испортить Git, так как я не знаю, прикреплено ли что-нибудь к подмодулю. Пока что вроде нормально, если не считать обычной проблемы с обновлением libetpan, но это (надеюсь) не связано.
Заметил, что никто не опубликовал ручное стирание, поэтому добавил
С git 2.17 и выше это просто:
git submodule deinit -f {module_name}
git add {module_name}
git commit
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"
2.20.1
и Ubuntu 18.04 2.17.1
."$submodule"
просто чтобы подчеркнуть, где поставить имя, и что вы должны быть осторожны с пробелами и т.п."$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
.git/config
git rm
.gitmodules
git submodule add
.git/modules/NAME/
git submodule init
, поэтому обновляет .git/config
git submodule update
, поэтому нерекурсивно проверяет модуль.gitmodules
git submodule update --init --recursive -- module
Это не может быть полностью симметричным, так как сохранять его строго симметричным не имеет особого смысла. Больше двух команд просто не нужно. Также «извлечение данных» подразумевается, потому что оно вам нужно, но удаление кэшированной информации не выполняется, потому что это вообще не нужно и может стереть ценные данные.
Это действительно озадачивает новичков, но в основном это хорошо: 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 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/
наличия двух разных (и, возможно, несовместимых) исходных репозиториев. И самое лучшее: вы также храните оба кешированных локально.
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.
С git v2.7.4 простые 3 шага работали нормально.
git submodule deinit -f -- a/submodule
git rm -f a/submodule
git commit
Если вы только что добавили подмодуль, и, например, вы просто добавили не тот подмодуль или добавили его не в то место, просто выполните git stash
, а затем удалите папку. Предполагается, что добавление подмодуля - единственное, что вы сделали в недавнем репо.
Подводя итог, вот что вам следует сделать:
Установите переменную 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
См. Также: Альтернативные рекомендации
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
В последнем git требуется всего 4 операции для удаления подмодуля git.
.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
git rm <submodule path> && git commit
. This can be undone using git revert
.
.gitmodules
file. $GIT_DIR/modules/<name>/
.Источник: git help submodules
Это сработало для меня. Вышеупомянутые ответы показали это в терминале, и больше ничего не происходило
'fatal: not removing 'demolibapp' recursively without -r'
Чтобы удалить подмодуль git
, необходимо выполнить ниже 4 шага.
.gitmodules
файле. Запись может быть такой, как указано ниже[submodule "path_to_submodule"]
path = path_to_submodule
url = url_path_to_submodule
git add .gitmodules
git rm --cached <path_to_submodule>
.git commit -m "Removed submodule xxx"
и нажмите.Дополнительные 2 шага, упомянутые ниже, необходимы для полной очистки подмодуля в локальной клонированной копии.
.git/config
файле. Запись может быть такой, как указано ниже[submodule "path_to_submodule"]
url = url_path_to_submodule
rm -rf .git/modules/path_to_submodule
Эти 5-й и 6-й шаги не создают никаких изменений, требующих фиксации.
git submodule deinit
git-scm.com/docs/git-submodule#Documentation/
- person Black; 31.01.2020
git rm modulename
иrm -rf .git/modules/modulename
- person imz -- Ivan Zakharyaschev   schedule 15.06.2015.git/config
. В принятом ответе показан современный способ полного удаления подмодуля. Это также более лаконично объясняется в этом ответе: stackoverflow.com/a/36593218/1562138 - person fvgs   schedule 13.04.2016