Вопрос

Как удалить подмодуль 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:

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

  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

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

Просто примечание.Начиная с 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

Простые шаги

  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?.

Помимо рекомендаций мне пришлось еще 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

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

  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

Если субмодуль был случайно добавлено, потому что вы добавили, зафиксировали и отправили папку, которая уже была репозиторием 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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top