Как переименовать репозиторий git, который содержит подмодули в своих подкаталогах

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

Предположим, что

  • Все ваши проекты расположены в /tmp.
  • У вас есть proj_master и proj_mod.
  • Вы клонируете porj_master как proj_ALL, затем клонируете prom_mod в качестве подмодуля в нем.
  • Переименуйте proj_ALL в proj_onebillion. Затем происходит черная магия.

Следующие шаги приведут к воспроизведению упомянутой проблемы. Версия git, которую я использую:

$ git --version
git version 1.7.9.5

  • Инициализировать proj_master.

    $ cd /tmp
    $ mkdir proj_master; cd proj_master
    $ git init .
    $ touch README
    $ git add .; git commit -m "hello proj_master"
    
  • Инициализировать proj_mod.

    $ cd /tmp
    $ mkdir proj_mod; cd proj_mod
    $ git init .
    $ touch README
    $ git add .; git commit -m "hello proj_mod"
    
  • Клонировать proj_master как proj_ALL и клонировать proj_mod как подмодуль.

    $ cd /tmp
    $ git clone proj_master proj_ALL
    $ cd proj_ALL
    $ git submodule add /tmp/proj_mod ./mod
    $ git add .; git commit -m "hello proj_ALL"
    $ git status   % Everything is OK.
    
  • Переименуйте proj_ALL в proj_onebillion. Встречайте фатальную ошибку.

    $ cd /tmp
    $ mv proj_ALL proj_onebillion
    $ cd proj_onebillion
    $ git status
    fatal: Not a git repository: /tmp/proj_ALL/.git/modules/mod
    

Одно замечание - это файл .git в каталоге подмодулей.

$ cat /tmp/proj_ALL/mod/.git 
gitdir: /tmp/proj_ALL/.git/modules/mod

Да, абсолютный путь. Впервые я понимаю, что git знает что-то, что выходит за пределы папки репо верхнего уровня.

Что это. Я повторяю, что еще раз я переименую папку проекта верхнего уровня, а не папку подмодуля. Я проверяю вопрос schmuck, который пытался переименовать папку подмодуля, поэтому кажется, что это не очень полезно для моей проблемы.

Если я пропущу что-то, что должно было быть прочитано раньше, я приношу свои извинения. Все ребята приветствуются.

Ответ 1

У вас есть несколько вариантов, они в конечном итоге становятся тем же:

снова клонировать

Вместо того, чтобы переименовывать папку - просто снова клонировать

$ cd /project/original
$ cd ..
$ mkdir moved
$ git init
$ git pull ../original master
$ git submodule init
$ git submodule update

Сравните original/.git/config с moved/.git/config и устраните любые существенные различия (недостающие ветки нуждаются в создании - отсутствующие пульты просто нужно добавить в файл конфигурации).

исправить пути

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

  • Исправьте ссылки на субмодули .git.

т.е. эти файлы:

$ cd /project/moved
$ find -name .git -type f

Все, что вам нужно сделать, это отредактировать их, чтобы указать нужный каталог

  • Исправьте ваши файлы подкатегорий .git.

т.е. эти файлы:

$ cd /project/moved
$ find .git/modules/ -name config

Здесь обновите параметр worktree:

[core]
    ...
    worktree = /original/path/submodule

Для

[core]
    ...
    worktree = /moved/path/submodule

И что это.

Заметка о версиях

1.7.8 ввел использование .git файла для подмодулей и использовал абсолютные пути, это было зафиксировано в 1.7.10 - поэтому проблема применима только к репозиториям git, созданным с помощью git версии 1.7.8 и 1.7.9.

Ответ 2

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

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

find . -name .git -print0 -type f | xargs -0 sed -i 's|<OLD PATH>|<NEW PATH>|g'

Во-вторых, файлы конфигурации для подмодулей git имеют строку, в которой сохраняется рабочий каталог, также абсолютный. Чтобы обновить все ссылки сразу, запустите следующую команду из корня основного проекта:

find . -name config -print0 -type f | xargs -0 sed -i 's|<OLD PATH>|<NEW PATH>|g'

Сделанные предположения заключаются в том, что ваша ОС - это некоторая форма * nix, и что у вас установлен пакет sed.

Ответ 3

Вам также необходимо проверить каждый подмодуль gitdir.

Он должен находиться в папке .git подмодуля.

Ответ 4

Вам нужно на самом деле изменить два файла

.git/modules/<path-to-submodule>/config
<path-to-submodule>/.git