Как извлечь из вложенных репозиториев GIT, находящихся внутри GIT superrepo

#git #git-submodules

#git #git-подмодули

Вопрос:

У меня есть проект, состоящий из огромного количества данных. Из-за его размера я не могу использовать удаленное репозиторий GIT и отправлять / извлекать данные через Интернет. Вместо этого я ношу с собой переносной жесткий диск, который содержит текущее состояние проекта (т. Е. workdir). Репозиторий GIT этого workdir находится на другом жестком диске внутри моего настольного компьютера (я использовал --separate-git-dir для достижения этого). Время от времени я стискиваю зубы, подключаю свой внешний жесткий диск к рабочему столу и делаю еще один гигантский коммит GIT, чтобы отслеживать историю данных проекта.

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

 portable HDD                             desktop HDD
|                                        |
|-.git <- text file (gitlink) to here -> |-ProjectGit
|                                        | |-objects
|-project1                               | |-refs
| |-.git <- actual git dir               | |-HEAD
| |-some files                           . . ...
|
|-project2
| |-.git <- actual git dir
| |-some files
|
|-loads
|-and
|-loads
|-of
|-files
  

Когда я пытаюсь выполнить a git add --all . внутри основного superrepo, GIT по понятным причинам сердится из-за наличия вложенных .git папок и кричит на меня, что я должен использовать подмодули.
И я бы с удовольствием сделал именно это, за исключением того, что подмодули находятся либо (а) в .git/modules папке superrepo, либо (б) можно принудительно включить устаревший режим и сохранить подмодуль внутри workdir. В случае (а) у меня не будет .git папок на моем внешнем жестком диске, и я не смогу зафиксировать изменения в вложенных репозиториях во время работы; и в случае (б) в .git папке superrepo не будет копии коммитов вложенных репозиториев, и, следовательно, если переносной жесткий диск будет поврежден, данные будут потеряны.

Я хочу каким-то образом извлекать все коммиты, находящиеся во вложенных вложенных репозиториях, на жесткий диск рабочего стола каждый раз, когда я делаю коммит superrepo. Единственный способ, который я смог придумать на данный момент, — это каким-то образом использовать git-хуки и прикрепить к ним скрипт, который автоматически перенесет все изменения в несколько небольших репозиториев, находящихся на жестком диске рабочего стола вместе с git-каталогом superrepo.

Ответ №1:

В итоге я просто использовал опцию «старые подмодули»:

  1. Переместите папки вложенных репозиториев на жесткий диск рабочего стола, где-нибудь рядом с каталогом git superrepo; запишите их исходные пути
  2. Убедитесь, что рабочий каталог superrepo чист
  3. Добавьте вложенные репозитории обратно в superrepo, используя git submodule add --name NAME RESERVE_HDD_PATH PORTABLE_HDD_PATH , где NAME — некоторое допустимое имя каталога, RESERVE_HDD_PATH — путь к вложенному каталогу на жестком диске рабочего стола, PORTABLE_HDD_PATH — исходный путь к вложенному каталогу, который вы записали на шаге 1, относительно корня superrepo
  4. Удалите .git файлы, которые были созданы в workdir, и скопируйте исходные вложенные репозитории обратно с жесткого диска рабочего стола вместо этих файлов
  5. Удалите modules папку из каталога git superrepo (это лишнее)
  6. Добавьте вложенные репозитории, которые сейчас находятся на переносном жестком диске в качестве удаленных, к соответствующим вложенным репозиториям, которые находятся на жестком диске рабочего стола.

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

 #!/bin/bash

while read filename
do
  echo "Pulling into $filename..."
  cd "$filename"
  git pull hdd master
  cd ..
done < submodules-list
  

где submodules-list — текстовый файл, содержащий список ваших вложенных репозиториев.
Думаю, я мог бы автоматизировать это еще больше, используя git-хуки, но я доволен тем, как обстоят дела сейчас.