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

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

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

38 ответов

Решение

Начиная с версии 1.8.3 (22 апреля 2013 г.):

Не было никакого Фарфорового способа сказать "Я больше не заинтересован в этом подмодуле", как только вы выразите свою заинтересованность в подмодуле с помощью " 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 Это упоминается в ответе udondan и обобщается Eonil в комментариях:

Это оставляет .git/modules/<path-to-submodule>/ без изменений.
Поэтому, если вы однажды удалите подмодуль этим методом и снова добавите их, это будет невозможно, поскольку хранилище уже повреждено.


git rm: Смотрите коммит 95c16418:

В настоящее время использую git rm msgstr "в подмодуле удаляет рабочее дерево подмодуля из суперпроекта и 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 (Q2 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 Submodule Tutorial:

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

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

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

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

Подмодуль, клонированный с использованием git 1.7.8 или новее, оставит не более четырех своих следов в вашем локальном репо. Процесс удаления этих четырех следов задается тремя командами ниже:

# Remove the submodule entry from .git/config
git submodule deinit -f path/to/submodule

# Remove the submodule directory from the superproject's .git/modules directory
rm -rf .git/modules/path/to/submodule

# Remove the entry in .gitmodules and remove the submodule directory located at path/to/submodule
git rm -f path/to/submodule

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

Простые шаги

  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?",

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

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

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

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

git rm --cached path/to/submodule

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

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

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

Из Git Docs:

Deinit

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

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

[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 config, и тогда вы можете сделать: 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

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

Это легко:

  1. Удалить раздел из .gitmodules
  2. Вызов: git add .gitmodules
  3. Вызов: git submodule deinit <path to submodule>
  4. Вызов: git rm <path to submodule>
  5. Зафиксировать и нажать

Вам придется вручную удалить файлы модуля в вашем проекте.

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

#!/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}"

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

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

git-delete-submodule submodule

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

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

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.) Удалите ссылку (без косой черты):

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 2.28.0. Однострочный ответ,

      git rm path-to-submodule

Однако, несмотря на то, что подмодуль удален из системы управления версиями,.git/modules/path-to-submodule по-прежнему содержит репозиторий подмодуля, а .git/config содержит его URL-адрес, поэтому вам все равно придется удалить их вручную:

      git config --remove-section submodule.path-to-submodule
rm -rf .git/modules/path-to-submodule

Иногда приходится использовать -fфлаг:

      $ git rm -f img2vec

Например, потому что вы можете получить такую ​​ошибку:

      $ git rm img2vec/
error: the following file has changes staged in the index:
    img2vec
(use --cached to keep the file, or -f to force removal)

Для удобства читателя здесь делается попытка подвести итог и дать пошаговое руководство о том, как это сделать, если что-то работает не так, как ожидалось. Ниже приводится проверенный и безопасный способ дляgit версия 2.17и выше, чтобы избавиться от подмодуля:

submodule="path/to/sub"              # no trailing slash!
git submodule deinit -- "$submodule"
git rm -- "$submodule"
  • Если это не сработает, см. Ниже.
  • Без вариантов. Ничего опасного. И даже не думайте делать больше!
  • Протестировано с Debian Buster 2.20.1 и Ubuntu 18.04 2.17.1.
  • "$submodule" просто чтобы подчеркнуть, где поставить имя, и что вы должны быть осторожны с пробелами и т.п.
  • Если в Windows проигнорируйте первую строку и замените "$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
    • (1) обновления .git/config
  • git rm
    • (2) удаляет файлы модуля
    • (3) тем самым рекурсивно удаляет подмодули подмодуля
    • (4) обновления .gitmodules
  • git submodule add
    • загружает данные в .git/modules/NAME/
    • (1) делает git submodule init, поэтому обновления .git/config
    • (2) делает git submodule update, поэтому нерекурсивно проверяет модуль
    • (4) обновления .gitmodules
  • git submodule update --init --recursive -- module
    • при необходимости извлекает дополнительные данные
    • (3) рекурсивно проверяет подмодули подмодуля

Это не может быть полностью симметричным, так как сохранять его строго симметричным не имеет особого смысла. Больше двух команд просто не нужно. Также "извлечение данных" подразумевается, потому что оно вам нужно, но удаление кэшированной информации не выполняется, потому что это вообще не нужно и может стереть ценные данные.

Это действительно озадачивает новичков, но в целом это хорошо: git просто делает то, что очевидно, и делает это правильно, и даже не пытается делать больше. git это инструмент, который должен выполнять надежную работу, а не просто еще один "Eierlegende Wollmilchsau" ("Eierlegende Wollmilchsau" переводится для меня как "злая версия швейцарского армейского ножа").

Так что я понимаю жалобы людей, которые говорят: "Почему не работает? git очевидная вещь для меня ". Это потому, что" очевидное "здесь зависит от точки зрения. Надежность в каждой ситуации гораздо важнее. Следовательно, то, что для вас очевидно, часто не подходит во всех возможных технических ситуациях. помните, что: AFAICS gitследует техническим путем, а не социальным. (Отсюда и хитрое название: git)

Если это не удается

Приведенные выше команды могут не работать по следующим причинам:

  • Твой gitслишком стар. Тогда используйте более новуюgit. (См. Ниже, как это сделать.)
  • У вас есть незафиксированные данные, и вы можете их потерять. Тогда лучше сначала зафиксируйте их.
  • Ваш подмодуль не чист в git cleanсмысл. Затем сначала очистите свой подмодуль с помощью этой команды. (Смотри ниже.)
  • Вы делали что-то в прошлом, что не поддерживается git. Тогда вы переходите на темную сторону, и все становится уродливо и сложно. (Возможно, это исправит использование другой машины.)
  • Возможно, есть другие способы потерпеть неудачу, о которых я не знаю (я просто git продвинутый пользователь.)

Возможные исправления приведены ниже.

Используйте более новую git

Если ваша машина слишком старая, нет submodule deinit в вашем git. Если вы не хотите (или можете) обновлять свой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 жалуется на несохраненный материал, зафиксируйте его и отправьте в безопасное место.
  • Если 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'

Видишь ли, нет -f необходимо на submodule deinit. Если все чисто, в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/наличие двух разных (и, возможно, несовместимых) исходных репозиториев. И самое лучшее: вы также храните оба кешированных локально.

  • Это верно не только для вас. Это также верно для всех остальных, использующих ваш репозиторий.
  • И вы не потеряете историю. Если вы забыли установить самую последнюю версию старого подмодуля, вы можете ввести локальную копию и сделать это позже. Обратите внимание, что довольно часто кто-то забывает подтолкнуть некоторые субмодули (потому что это PITA для новичков, пока они не привыкнут кgit).

Однако, если вы удалили кэшированный каталог, обе разные проверки будут сталкиваться друг с другом, потому что вы не будете использовать --nameварианты, правда? Поэтому каждый раз, когда вы выполняете оформление заказа, вам, возможно, придется удалять.git/modules/<module>/каталог снова и снова. Это чрезвычайно громоздко и затрудняет использование чего-то вродеgit bisect.

Так что есть очень техническая причина оставить этот каталог модуля в качестве заполнителя. Люди, которые рекомендуют что-то удалить ниже.git/modules/ либо не знаю, либо забываю сказать вам, что это делает такие мощные функции, как git bisect почти невозможно использовать, если это пересекает такую ​​несовместимость субмодулей.

Еще одна причина показана выше. Посмотрите наls. Что ты там видишь?

Ну 2 вариант модуля two/ не под .git/modules/two/, это под .git/modules/someunusedname/! Такие вещи какgit rm $module; rm -f .git/module/$moduleсовершенно не правы! Вы должны либо проконсультироватьсяmodule/.git или .gitmodules найти нужную вещь удалить!

Так что не только большинство других ответов попадают в эту опасную ловушку, даже очень популярную.gitВ расширениях была эта ошибка (теперь она там исправлена)! Так что лучше держи руки.git/ каталог, если не совсем то, что вы делаете!

А с философской точки зрения стирать историю всегда неправильно! Кроме квантовой механики, как обычно, но это совсем другое.

К вашему сведению, вы, наверное, догадались: hilbix - это моя учетная запись GitHub.

Я должен был сделать шаги Джона Даута на один шаг вперед и cd в каталог подмодуля, а затем удалите Git-репозиторий:

cd submodule
rm -fr .git

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

С git v2.7.4 простые 3 шага работали нормально.

      git submodule deinit -f -- a/submodule    
git rm -f a/submodule
git commit

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

Лучший способ удалить подмодуль из git:

      $ git submodule deinit -f <submodule-name>
$ rm -rf .git/modules/<submodule-name>
$ git config -f .gitmodules --remove-section submodule.<submodule-name>
$ git config -f .git/config --remove-section submodule.<submodule-name>
$ git rm --cached <submodule-name>
$ git commit -m 'rm submodule: <submodule-name>'

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

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

Я следовал инструкциям из этого же руководства. Как удалить субмодуль?

      $ git submodule deinit -f <submodule-name>
$ rm -rf .git/modules/<submodule-name>
$ git config -f .gitmodules --remove-section submodule.<submodule-name>
$ git config -f .git/config --remove-section submodule.<submodule-name>
$ git rm --cached <submodule-name>
$ git commit -m 'rm submodule: <submodule-name>'

Но продолжал говорить:

      fatal: no submodule mapping found in .gitmodules for path

Итак, что я сделал, так это включил путь в .gitignore следующим образом (без звездочки в конце пути):

      <path>

Затем я изменил любой файл и сделал простой толчок :

      $ git add .
$ git commit -m "Ignoring sharedlibs folder <path> on .gitignore"
$ git push -u origin master

С git 2.17 и выше это просто:

git submodule deinit -f {module_name}
git add {module_name}
git commit
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

Это сработало для меня. Вышеупомянутые ответы показали это в терминале, и больше ничего не происходило.

      'fatal: not removing 'demolibapp' recursively without -r'
  1. demolibapp - это имя моего подмодуля, который я хочу удалить
  2. Подмодуль git deinit demolibapp
  3. git rm --cached demolibapp -r
  4. rm -rf .git / модули / demolibapp
  5. git add --all
  6. git commit -m "удаление лишних подмодулей"
  7. git push
  8. rm -rf demolibapp

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

См. Также: Альтернативные направляющие линии

Другие вопросы по тегам