Восстановить подмодули git из .gitmodules
У меня есть папка, которая была git repo. Он содержит некоторые файлы и файл .gitmodules. Теперь, когда я делаю git init
, а затем git submodule init
, последний вывод команды ничего. Как я могу помочь git увидеть подмодули, определенные в файле .gitmodules, без запуска git submodule add
вручную снова?
Обновление:
это мой файл .gitmodules:
[submodule "vim-pathogen"]
path = vim-pathogen
url = git://github.com/tpope/vim-pathogen.git
[submodule "bundle/python-mode"]
path = bundle/python-mode
url = git://github.com/klen/python-mode.git
[submodule "bundle/vim-fugitive"]
path = bundle/vim-fugitive
url = git://github.com/tpope/vim-fugitive.git
[submodule "bundle/ctrlp.vim"]
path = bundle/ctrlp.vim
url = git://github.com/kien/ctrlp.vim.git
[submodule "bundle/vim-tomorrow-theme"]
path = bundle/vim-tomorrow-theme
url = git://github.com/chriskempson/vim-tomorrow-theme.git
и вот список этого каталога:
drwxr-xr-x 4 evgeniuz 100 4096 июня 29 12:06 .
drwx------ 60 evgeniuz 100 4096 июня 29 11:43 ..
drwxr-xr-x 2 evgeniuz 100 4096 июня 29 10:03 autoload
drwxr-xr-x 7 evgeniuz 100 4096 июня 29 12:13 .git
-rw-r--r-- 1 evgeniuz 100 542 июня 29 11:45 .gitmodules
-rw-r--r-- 1 evgeniuz 100 243 июня 29 11:18 .vimrc
так, безусловно, он находится на верхнем уровне. каталог git не изменяется, выполняется только git init
Ответы
Ответ 1
git submodule init
рассматривает только те подмодули, которые уже есть в индексе (т.е. "подготовлены") для инициализации. Я написал бы короткий сценарий, который анализирует .gitmodules
, и для каждой пары url
.gitmodules
и path
выполняется:
git submodule add <url> <path>
Например, вы можете использовать следующий скрипт:
#!/bin/sh
set -e
git config -f .gitmodules --get-regexp '^submodule\..*\.path$' |
while read path_key path
do
url_key=$(echo $path_key | sed 's/\.path/.url/')
url=$(git config -f .gitmodules --get "$url_key")
git submodule add $url $path
done
Это основано на том, как git-submodule.sh
скрипт git-submodule.sh
анализирует файл .gitmodules
.
Ответ 2
Развернувшись на @Mark Longair, я написал bash script для автоматизации шагов 2 и 3 следующего процесса:
- Клонировать "шаблонный" репо, чтобы начать новый проект.
- Удалить папку .git и повторно инициализировать в качестве нового репо
- Повторно инициализировать подмодули, запрашивая ввод перед удалением папок.
#!/bin/bash
set -e
rm -rf .git
git init
git config -f .gitmodules --get-regexp '^submodule\..*\.path$' > tempfile
while read -u 3 path_key path
do
url_key=$(echo $path_key | sed 's/\.path/.url/')
url=$(git config -f .gitmodules --get "$url_key")
read -p "Are you sure you want to delete $path and re-initialize as a new submodule? " yn
case $yn in
[Yy]* ) rm -rf $path; git submodule add $url $path; echo "$path has been initialized";;
[Nn]* ) exit;;
* ) echo "Please answer yes or no.";;
esac
done 3<tempfile
rm tempfile
Примечание: подмодули будут проверяться на кончике главной ветки, а не на том же фиксации, что и на реплике с шаблоном, поэтому вам нужно будет сделать это вручную.
Выполнение вывода из git config в цикл чтения вызывало проблемы с приглашением ввода, поэтому оно выводит его в файл temp. Любые улучшения в моем первом bash script были бы очень желанными:)
Большое спасибо Mark, fooobar.com/questions/933/..., bash: вложенное интерактивное чтение в цикле, которое также использует чтение и tnettenba @chat.freenode.net, чтобы помочь мне прийти к этому решению!
Ответ 3
У меня была аналогичная проблема. git submodule init
терпел неудачу.
Когда я это сделал:
git submodule add <url> <path>
Я получил:
The following path is ignored by one of your .gitignore files: ...
Я думаю, что причиной могут быть .gitignore (d) пути.
Ответ 4
Расширение превосходного ответа @Mark Longair для добавления субмодуля с уважением к ответвлению и названию репо.
#!/bin/sh
set -e
git config -f .gitmodules --get-regexp '^submodule\..*\.path$' |
while read path_key path
do
name=$(echo $path_key | sed 's/\submodule\.\(.*\)\.path/\1/')
url_key=$(echo $path_key | sed 's/\.path/.url/')
branch_key=$(echo $path_key | sed 's/\.path/.branch/')
url=$(git config -f .gitmodules --get "$url_key")
branch=$(git config -f .gitmodules --get "$branch_key" || echo "master")
git submodule add -b $branch --name $name $url $path || continue
done
Ответ 5
Я знаю, что это было давно, но я хочу поделиться этой версией, которая вызывает git config
только один раз, не требует сценария и также обрабатывает ветки:
git config -f .gitmodules --get-regexp '^submodule\.' | perl -lane'
$conf{$F[0]} = $F[1]}{
@mods = map {s,\.path$,,; $_} grep {/\.path$/} keys(%conf);
sub expand{$i = shift; map {$conf{$i . $_}} qw(.path .url .branch)}
for $i (@mods){
($path, $url, $branch) = expand($i);
print(qq{rm -rf $path});
print(qq{git submodule add -b $branch $url $path});
}
'
Единственным побочным эффектом является вывод команд, при этом ничего не выполняется, поэтому вы можете провести аудит перед их выполнением.
Это работает с простым копированием и вставкой в консоли, но это должно быть тривиально, чтобы вставить в сценарий оболочки.
пример вывода:
rm -rf third-party/dht
git submodule add -b post-0.25-transmission https://github.com/transmission/dht third-party/dht
rm -rf third-party/libutp
git submodule add -b post-3.3-transmission https://github.com/transmission/libutp third-party/libutp
rm -rf third-party/libb64
git submodule add -b post-1.2.1-transmission https://github.com/transmission/libb64 third-party/libb64
rm -rf third-party/libnatpmp
git submodule add -b post-20151025-transmission https://github.com/transmission/libnatpmp third-party/libnatpmp
rm -rf third-party/miniupnpc
git submodule add -b post-2.0.20170509-transmission https://github.com/transmission/miniupnpc third-party/miniupnpc
rm -rf third-party/libevent
git submodule add -b post-2.0.22-transmission https://github.com/transmission/libevent third-party/libevent