Как сделать существующий каталог в репозитории git подмодулем git

я очень смущен git-подмодулями.

в основном моя проблема в том, что я не могу заставить git понять это ~/main-project/submodule - Это субмодуль.


у меня есть хороший опыт работы с подмодулями git:
в моем хранилище dotfiles я создал .gitmodules файл в ~/dotfiles-repo и я добавил туда пути и URL-адреса. С тех пор, если я внесу изменения в файлы внутри подмодулей и запустите git status, Я бы получил что-то вроде: .vim/bundle/auto-complete (new commits) # in red

я создал на ~/main-project но:

  • если я внесу изменения в ~/main-project/submodule и даже нажмите изменения, я не получаю аналогичного ответа, как <submodule> (new commits) # in red при работе git status на ~/main-project. я просто сделать изменения, которые были сделаны в этих каталогах
  • когда я нажму ссылки папок в github для этих каталогов он не направляет меня в сами репозитории, но я остаюсь в том же хранилище.

    1. может быть, я упускаю весь смысл. Каковы основные особенности подмодулей?
    2. почему git понимает подмодули в РЕПО dotfiles а не в моем другом РЕПО?
    3. это потому, что я уже сказал git добавить файлы внутри ~/main-project/submodule в индекс?

я читал этот вопрос что привело меня к ответ Но я не уверен, что мне нужно git-subtree. Я не хочу делать то, что может сделать изменения, которые трудно вернуть.

Edit:это предложенное дубликат-решение тоже не сработало, я получил ошибку, что Updates were rejected because the remote contains work that you do not have locally. Кажется, что @GabLeRoux практически сказал мне <repo-A> к url <repo-B>.

3 ответов


решение довольно простое. Он был извлечен из здесь.

  1. git rm submodule-dir
    Это удалит все файлы, которые git отслеживал после в submodule-dir
  2. rm -rf submoduledir
    Это приведет к удалению всех других файлов, которые могли быть оставлены в submodule-dir потому что git игнорировал их.
  3. теперь мы должны совершить, чтобы удалить файлы из индекса:
    git commit
    После фиксации мы очистили файлы этот мерзавец последовал за ним и не последовал в submodul-dir. Теперь пришло время сделать:
  4. git submodule add <remote-path-to-submodule>
    Это будет повторно добавить подмодуль, но как истинный подмодуль.
  5. в этот момент может быть хорошей идеей проверить .gitmodules и посмотреть, были ли успешно добавлены подмодули. В моем случае у меня уже был .gitmodules файл, поэтому мне пришлось его изменить.

редактировать

С П2.12.0-rc0, и после этот коммит, мы получено git submodule absorbgitdirs и это именно то, что мне было нужно в то время, когда я разместил этот вопрос.

это docs укажите, что эта команда делает:

если каталог git подмодуля находится внутри подмодуля, перейти в каталог Git из подмодуля в superprojects $GIT_DIR/modules путь, а затем подключите каталог git и его рабочий каталог, установив core.worktree и добавления ля. git-файл, указывающий на встроенный каталог git этот каталог git superprojects.

поэтому вместо того, чтобы начинать все сначала, как предлагалось в предыдущих ответах @DomQ и мной, можно просто добавить выполнить следующее:

  1. не удаляя из индекса подмодуль, добавьте url подмодуля в .gitmodules и .git/config С
    git submodule add <url> <path>
  2. переместить подмодуль

в принципе нет лучшего способа, чем притворяться, чтобы начать все сначала:

  1. убедитесь, что все совершается везде
  2. переместить суб-репозиторий в сторону
  3. git submodule add суб-репозиторий ПДУ
  4. cd mysubmodule
  5. git fetch ../wherever/you/stashed/the/sub-repository/in/step-1
  6. git merge FETCH_HEAD

чтобы объяснить, почему это так, мне кажется, чем глубже понимание того, что подмодули are нужно, чем то, что можно почерпнуть из git-submodule(1) ручная страница (или даже соответствующая глава из книги Git). Я нашел еще несколько подробных объяснений на этот блог, но так как этот пост немного длинный, я беру на себя смелость обобщить их здесь.

на низком уровне подмодуль git состоит из следующих элементов,

  • A фиксация объекта в верхней части дерево подмодулей,
  • (в последних версиях Git) подкаталог в .git/modules для размещения объектов Git для подмодуля,
  • запись .gitmodules файл конфигурации.

объект commit содержится (или, точнее, ссылается на SHA1) в Родительском объекте дерева. Это необычно, как вещи обычно происходит наоборот, но это объясняет, почему вы видите, что каталог появляется в главном репозитории git status после выполнили фиксацию в подмодуле. Вы также можете сделать эксперименты С git ls-tree чтобы наблюдать этот объект фиксации более подробно.

поддиректории в .git/modules означает .git подкаталог в подмодуле; и на самом деле, есть .git в подмодуле, который указывает на первый, используя gitdir: линии. Это поведение по умолчанию начиная с версии 1.7.8 Git. Не знаю, почему бы и нет. Работа, если вы просто продолжали иметь отдельный .git каталог, за исключением случаев, отмеченных в примечаниях к выпуску, вы, вероятно, столкнетесь с проблемами при переключении между ветвью, которая имеет подмодуль, и другой, которая этого не делает.

на .gitmodules файл предоставляет URL, который git submodule update --remote и друзья должны тянуть из; что, очевидно, отличается от набора пультов главного репозитория. Обратите внимание также, что .gitmodules копируется в .git/config на git submodule sync command и другие команды, которые вызовите его за кулисами.

в то время как это довольно легко сделать необходимые изменения вручную для .gitmodules + .git/config, а также .git/modules + mysubmodule/.git (а на самом деле, есть даже git submodule absorbgitdirs для последнего), на самом деле нет фарфора для создания только объекта фиксации в дереве. Следовательно, предлагаемое решение путем перемещения + переделки изменений, представленных выше.


чтобы ответить на ваши вопросы по порядку:

  1. на цель подмодулей в соответствии с GitHub. Особенность мудрый, он был разработан, чтобы концептуализировать дочерний репозиторий (который почти можно рассматривать как любой другой файл), то есть версию, контролируемую родительским репозиторием, где родитель отслеживает текущий идентификатор фиксации подмодуля (дочернего репозитория), а не его содержимое.
  2. Это скорее всего потому, что вы уже добавили файлы к индексу репозитория. В этом случае, решение git rm --cached submodule-name/. Затем создайте промежуточную фиксацию с последующим добавлением папки как хранилище: git add submodule-name (обратите внимание, что есть нет Слэша after submodule-name в случае подмодулей).
  3. да :)

на ответ вы упомянули, что можете исправить историю ваших коммитов как хорошо:

  1. преимущества:

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

  1. недостатки:

Если история фиксации изменена, все остальные участники также должны будут повторно клонировать проект, так как они получат конфликты слияния или хуже; повторно ввести проблему фиксации обратно в проект.