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

Я хотел бы изменить имя каталога подмодуля Git в моем суперпроекте Git.

предположим, у меня есть следующая запись в моем :

[submodule ".emacs.d/vimpulse"]  
path = .emacs.d/vimpulse  
url = git://gitorious.org/vimpulse/vimpulse.git

что мне нужно ввести, чтобы переместить

10 ответов


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

С git 1.8.5,git mv old/submod new/submod работает, как ожидалось и вся сантехника для вас. Возможно, вы захотите использовать git 1.9.3 или новее, поскольку он включает исправления для перемещения подмодулей.


это похоже на то, как вы удаляете подмодуль (см. Как удалить подмодуль?):

  1. редактировать .gitmodules и измените путь подмодуля соответствующим образом и поместите его в индекс с git add .gitmodules.
  2. при необходимости создайте родительский каталог нового расположения подмодуля (mkdir -p new/parent).
  3. переместить все содержимое из старого в новый каталог (mv -vi old/parent/submodule new/parent/submodule).
  4. убедитесь, что Git отслеживает этот каталог (git add new/parent).
  5. Удалите старый каталог с помощью git rm --cached old/parent/submodule.
  6. переместить каталог .git/modules/old/parent/submodule со всем его содержанием .git/modules/new/parent/submodule.
  7. редактировать .git/modules/new/parent/config файл, убедитесь, что элемент worktree указывает на новые местоположения, поэтому в этом примере он должен быть worktree = ../../../../../new/parent/module. Как правило, должно быть еще два .. затем каталоги в прямом пути в этом месте.
  8. редактировать файл new/parent/module/.git, убедитесь, что путь в нем указывает на правильное новое место внутри основного проекта .git папка, поэтому в этом примере gitdir: ../../../.git/modules/new/parent/submodule.

    git status вывод выглядит так для меня после этого:

    # On branch master
    # Changes to be committed:
    #   (use "git reset HEAD <file>..." to unstage)
    #
    #       modified:   .gitmodules
    #       renamed:    old/parent/submodule -> new/parent/submodule
    #
    
  9. наконец, сохраните изменения.


самый современный ответ, взятый из комментария Валлорика выше:

  1. обновление до Git 2.0 (или, по крайней мере, до 1.9.3)
  2. git mv old/submod new/submod
  3. далее .gitmodules и каталог подмодулей уже расположены для фиксации (вы можете проверить это с помощью git status.)
  4. зафиксировать изменения с git commitи вы хорошо идти!

готово!


в моем случае я хотел переместить подмодуль из одного каталога в подкаталог, например "AFNetworking" -> "ext/AFNetworking". Вот шаги, которым я следовал:--11-->

  1. правка .gitmodules изменение имени подмодуля и пути к "ext / AFNetworking"
  2. переместить каталог git подмодуля из ".git / модули / AFNetworking "to".git / модули / ext / AFNetworking"
  3. переместить библиотеку из "AFNetworking"в" ext/AFNetworking"
  4. изменить ".git / modules / ext / AFNetworking / config " и исправить [core] worktree линии. Мой изменился с ../../../AFNetworking to ../../../../ext/AFNetworking
  5. Edit " ext / AFNetworking/.ГИТ" и исправить gitdir. Мой изменился с ../.git/modules/AFNetworking to ../../git/modules/ext/AFNetworking
  6. git add .gitmodules
  7. git rm --cached AFNetworking
  8. git submodule add -f <url> ext/AFNetworking

наконец, я увидел в статусе git:

matt$ git status
# On branch ios-master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   modified:   .gitmodules
#   renamed:    AFNetworking -> ext/AFNetworking

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


[Обновления: 2014-11-26] А Яр красиво приведены ниже прежде чем что-либо делать, убедитесь, что вы знаете URL-адрес подмодуля. если неизвестно, открытого .git/.gitmodules и изучить ключsubmodule.<name>.url.

то, что сработало для меня, было удалить старый подмодуль используя git submodule deinit <submodule> следовал по git rm <submodule-folder>. Затем снова добавьте подмодуль с новым именем папки и зафиксируйте. Проверка состояния git перед фиксацией показывает старый подмодуль, переименованный в новое имя and .gitmodule изменен.

$ git submodule deinit foo
$ git rm foo
$ git submodule add https://bar.com/foo.git new-foo
$ git status
renamed:    foo -> new-foo
modified:   .gitmodules
$ git commit -am "rename foo submodule to new-foo"

трюк, кажется, понимание того, что .git каталог для подмодулей теперь хранится в главном репозитории в разделе .git/modules, и каждый подмодуль имеет .git файл, который указывает на это. Это процедура, которая вам нужна сейчас:

  • переместите подмодуль в его новый дом.
  • редактировать .git файл в рабочем каталоге подмодуля и измените путь, который он содержит, чтобы он указывал на правильный каталог в главном репозитории .git/modules справочник.
  • введите.git/modules каталог и найдите каталог, соответствующий вашему подмодулю.
  • редактировать обновление worktree путь, чтобы он указывал на новое местоположение рабочего каталога подмодуля.
  • редактировать .gitmodules файл в корне главного репозитория, обновляющий путь к рабочему каталогу подмодуля.
  • git add -u
  • git add <parent-of-new-submodule-directory> (важно, чтобы добавить родитель, а не сам каталог подмодулей.)

несколько замечаний:

  • на [submodule "submodule-name"] строки .gitmodules и .git/config должны соответствовать друг другу, но не соответствуют ничему другому.
  • рабочий каталог подмодуля и .git каталог должен правильно указывать друг на друга.
  • на .gitmodules и .git/config файлы должны быть синхронизированы.

вы можете просто добавить новый и удалить старый субмодуль субмодуль с помощью стандартных команд. (должен предотвратить любые случайные ошибки внутри .git)

пример настройки:

mkdir foo; cd foo; git init; 
echo "readme" > README.md; git add README.md; git commit -m "First"
## add submodule
git submodule add git://github.com/jquery/jquery.git
git commit -m "Added jquery"
## </setup example>

Examle переместить "jquery" в "поставщик / jquery/jquery":

oldPath="jquery"
newPath="vendor/jquery/jquery"
orginUrl=`git config --local --get submodule.${oldPath}.url`

## add new submodule
mkdir -p `dirname "${newPath}"`
git submodule add -- "${orginUrl}" "${newPath}"

## remove old submodule
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 old src
rm -rf ".git/modules/${oldPath}" ## cleanup gitdir (housekeeping)

## commit
git add .gitmodules
git commit -m "Renamed ${oldPath} to ${newPath}"

Бонусный метод для больших подмодулей:

Если субмодуль большой и вы предпочитаете не ждать клона, вы можете создать новый подмодуль использует старый как origin, а затем переключает origin.

пример (используйте тот же пример настройки)

oldPath="jquery"
newPath="vendor/jquery/jquery"
baseDir=`pwd`
orginUrl=`git config --local --get submodule.${oldPath}.url`

# add new submodule using old submodule as origin
mkdir -p `dirname "${newPath}"`
git submodule add -- "file://${baseDir}/${oldPath}" "${newPath}"

## change origin back to original
git config -f .gitmodules submodule."${newPath}".url "${orginUrl}"
git submodule sync -- "${newPath}"

## remove old submodule
...

строка в кавычках после "[submodule " не имеет значения. Вы можете изменить его на "foobar", если хотите. Он используется для поиска соответствующей записи в ".git / config".

поэтому, если вы внесете изменения перед запуском "git submodule init", он будет работать нормально. Если вы внесете изменения (или получите изменения через слияние), вам нужно будет либо вручную отредактировать .git / config или снова запустите "git submodule init". Если вы сделаете последнее, вы останетесь с безвредной" застрявшей " записью с старое имя .git / config.


данное решение не сработало для меня, однако аналогичная версия...

это с клонированным репозиторием, поэтому репозитории Git подмодуля содержатся в верхних репозиториях .git dir. Все катионы из верхнего репозитория:

  1. правка .gitmodules и измените параметр "path =" для рассматриваемого подмодуля. (Нет необходимости менять метку или добавлять этот файл в индекс.)

  2. правка .git / модули / имя / конфигурация и измените параметр "worktree =" для рассматриваемого подмодуля

  3. run:

    mv submodule newpath/submodule
    git add -u
    git add newpath/submodule
    

интересно, имеет ли значение, являются ли репозитории атомарными или относительными подмодулями, в моем случае это было относительным (submodule/.git-это ссылка на topproject/.git / модули / подмодуль)


просто использовать shell-скрипт git-submodule-move.


Я только вчера прошел через это испытание и ответ отлично работал. Вот мои шаги, для ясности:--8-->

  1. убедитесь,что подмодуль зарегистрирован и отправлен на сервер. Вы также должны знать, какая ветка его на.
  2. вам нужен URL вашего подмодуля! использовать more .gitmodules потому что после удаления подмодуля он не будет вокруг
  3. теперь вы можете использовать deinit, rm и затем submodule add

пример

команды

    git submodule deinit Classes/lib/mustIReally
    git rm foo
    git submodule add http://developer.audiob.us/download/SDK.git lib/AudioBus

    # do your normal commit and push
    git commit -a 

Примечание: git mv этого не делает. Совсем.