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

3133

Как удалить субмодуль Git?

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

  • 89
    Простой ответ stackoverflow.com/a/21211232/94687 теперь правильный, и должен быть помечен так. Теперь это просто git rm modulename и rm -rf .git/modules/modulename
  • 8
    Это на самом деле не правда. Этот ответ не касается удаления записи субмодуля из .git/config . Принятый ответ показывает современный способ полного удаления субмодуля. Это также объясняется более кратко в этом ответе: stackoverflow.com/a/36593218/1562138
Показать ещё 3 комментария
Теги:
git-submodules

22 ответа

1978
Лучший ответ

Начиная с версии 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 удаляет ее из индекса:
    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 - в коммите ead8dbe, 13 февраля 2018 г.)

git ${wt_prefix:+-C "$wt_prefix"} submodule--helper deinit \
  ${GIT_QUIET:+--quiet} \
  ${prefix:+--prefix "$prefix"} \
  ${force:+--force} \
  ${deinit_all:+--all} "$@"
  • 14
    Можете ли вы привести пример использования submodule deinit ?
  • 3
    @yourfriendzak - вот один пример того, как кто-то успешно его использует: stackoverflow.com/a/16161950/6309 . Но имейте в виду, что, вопреки тому, чему я изначально верил, 1.8.3 еще не выпущен! В Unix вы можете скомпилировать его из исходников.
Показать ещё 34 комментария
3384

На странице Git Submodule Tutorial:

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

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

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

  • 387
    "И, кстати, есть ли причина, по которой я не могу просто сделать git submodule rm?" ?
  • 44
    @abernier Краткий ответ может быть «потому что такой команды не существует». Я предполагаю, что они пытаются сделать удаление файлов субмодулей против конфигурации субмодуля явным, чтобы избежать случайной потери данных. Возможно, один человек подумает, что git submodule rm просто удаляет регистрацию подмодуля, и будет удивлен, если команда также удалит локальный репозиторий. Любые локальные изменения будут безвозвратно потеряны. И, возможно, другой человек подумает, что будут удалены только файлы.
Показать ещё 26 комментариев
399

Просто заметьте. Поскольку 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
  • 3
    Я на git версии 2.4.9 (Apple Git-60), и все, что мне нужно было сделать, это rm the_submodule. Я нажал на это, а затем снова добавил папку с именем подмодуля, и она работала без проблем.
  • 0
    Я использую git версии 2.5.4 для OSX, и вам нужно выполнить вторую команду, только если вы хотите повторно добавить субмодуль из другого места. Если вы не сделаете второй шаг, то увидите следующее: каталог git для 'submodule' находится локально с удаленными (и):
Показать ещё 10 комментариев
340

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

Подмодуль, клонированный с использованием 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
  • 16
    Почему в этом ответе так мало голосов? Все эти популярные ответы что-то упускают, это единственный, который действительно удаляет все следы подмодуля, самым простым способом. И обратите внимание: порядок команд имеет значение.
  • 0
    Откуда вы получаете -rf ? Я получаю сообщение об ошибке при попытке запустить его (вторая команда; Windows-машина)
Показать ещё 6 комментариев
187

Простые шаги

  • Удалить записи конфигурации:
    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?.

  • 1
    У меня было много подмодулей (и больше беспорядка), поэтому мне пришлось пропустить их через цикл for. Так как большинство из них, находящихся в определенном каталоге и в ls, содержат конечные слэши. Я сделал что-то вроде for dir in directory/*; do git rm --cached $dir; done
  • 0
    Чтобы получить этот список, который можно использовать в скрипте для рекурсивного удаления - 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
Показать ещё 3 комментария
81

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

  • 1
    У меня тоже были проблемы с этим. Если вы попытаетесь переустановить субмодуль по тому же пути, он сохранит информацию о ветках в кэше в указанном вами месте, что приведет к путанице.
  • 0
    Спасибо, мне это тоже нужно. @ Антон, я согласен, и я отредактировал ответ с наибольшим количеством голосов, чтобы добавить эту информацию.
Показать ещё 1 комментарий
50

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

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
  • 0
    +1 действительно. Это единственный правильный ответ начиная с git 1.8.3. Должен быть принят как правильный.
  • 0
    +1 Правильный и чистый способ удаления в более новых версиях git.
Показать ещё 3 комментария
47

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

git rm --cached path/to/submodule

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

  • 0
    Никакого сценария оболочки не требуется, в другом ответе есть команды для удаления всех следов подмодуля: stackoverflow.com/a/36593218/4973698
40

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

  • Установите 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

  • 0
    так что все остальные, кто извлекает мои изменения, должны запустить rm -rf $ path_to_submodule rm -rf .git / modules / $ path_to_submodule для удаления кеша субмодуля?
  • 0
    Я рекомендую обновить git submodule update . И если пути к подмодулям не были обновлены правильно (git выдает ошибку), удалите их: rm -rf .git/modules/<submodule> && rm -rf <submodule> && git submodule update
39

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

[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

36

Если субмодуль был случайно добавлен, потому что вы добавили, зафиксировали и нажали папку, которая уже была хранилищем Git (содержащая .git), у вас не будет файла .gitmodules для редактирования или что-либо в .git/config, В этом случае все, что вам нужно:

git rm --cached subfolder
git add subfolder
git commit -m "Enter message here"
git push

FWIW, я также удалил папку .git, прежде чем делать git add.

  • 0
    именно мой случай
21

После экспериментов со всеми различными ответами на этом сайте я закончил это решение:

#!/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)
  • 0
    Почему вы используете git rm --cached $path затем rm -rf $path вместо git rm -r $path ?
18

Я нашел, что deinit работает хорошо для меня:

git submodule deinit <submodule-name>    
git rm <submodule-name>

От git docs:

Deinit

Отмените регистрацию данных подмодулей, т.е. удалите все submodule.$nameраздел из .git/config вместе со своим деревом работ.

  • 0
    Согласитесь, нашли такое же решение. Это лучший способ сегодня в 2018 году)
  • 0
    он не удалил .git / modules / ... Вы должны удалить их, смотрите ответ @fvgs
17

То, что я делаю в декабре 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}"
13

Недавно я обнаружил проект git, который включает много полезных команд, связанных с git: https://github.com/visionmedia/git-extras

Установите его и введите:

git-delete-submodule submodule

Тогда все готово. Каталог подмодулей будет удален из вашего репозитория и все еще будет существовать в вашей файловой системе. Затем вы можете зафиксировать изменение следующим образом: git commit -am "Remove the submodule".

12

Вот что я сделал:

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
  • 0
    Спасибо за это. Для меня я должен был изменить порядок первых трех шагов в 3), 1), 2). Выполнение 1) сначала дало fatal: no submodule mapping found in .gitmodules for path 'submodule_name' в шаге 3 fatal: no submodule mapping found in .gitmodules for path 'submodule_name' . Оба шага были необходимы. (git v2.8.2)
10

Мне пришлось занять John Douthat еще один шаг и cd в каталог подмодулей, а затем удалить репозиторий Git:

cd submodule
rm -fr .git

Затем я мог зафиксировать файлы как часть родительского репозитория Git без старой ссылки на подмодуль.

  • 0
    Мне пришлось сделать это тоже, чтобы обойти ошибку «роковая: не репозиторий git:» при попытке выполнить шаг git rm --cache .
8

Вот 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.

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

Я просто нашел скрытый файл .submodule(забыли точное имя), у него есть список... вы можете стереть их индивидуально таким образом. У меня только один, поэтому я удалил его. Простой, но это может испортить Git, так как я не знаю, связано ли что-либо с подмодулем. Кажется, пока что, кроме обычной проблемы с выпуском libetpan, но это (надеюсь) не связано.

Заметили, что никто не опубликовал ручное удаление, поэтому добавил

  • 0
    Это .gitmodules
4

Если вы только что добавили подмодуль, и, например, вы просто добавили неправильный субмодуль или вы добавили его в неправильное место, просто выполните git stash, затем удалите папку. Это предполагает, что добавление подмодуля - единственное, что вы сделали в недавнем репо.

0

Сделайте следующее

cd Yoursubmodule
rm -force .git

Ещё вопросы

Сообщество Overcoder
Наверх
Меню