Подмодуль Git на удаленном голом
Я настроил свою среду, чтобы я мог нажать на удаленный открытый репозиторий, я использовал эти команды для настройки удаленного репозитория:
$ mkdir ~/website.git && cd ~/website.git
$ git init --bare
и
$ cat > hooks/post-receive
#!/bin/sh
GIT_WORK_TREE=/var/www/website git checkout -f
$ chmod +x hooks/post-receive
И в моей локальной среде:
$ git remote add web ssh://website.com/home/website.git
$ git push web +master:refs/heads/master
Теперь я могу развернуть этот пульт с помощью git push web
и все отлично работает.
Проблема: Субмодули
У меня есть несколько подмодулей в моем проекте, которые не были инициализированы/обновлены в удаленном репозитории... Я не могу запустить git submodule update
на голом, потому что он голый, и я не может запустить его в папке /var/www/website
, потому что это просто копия файлов, а не репозиторий git.
Ответы
Ответ 1
Одним из возможных способов может быть:
- настроить
/var/www/website
как репозиторий (не голый) - иметь ваш
post-receive
крюк вашего голого репо:
Другими словами:
Извлечение из чистого репо вместо попытки извлечения из чистого репо: непогашенное репо должно быть в состоянии выполнить шаг git submodule update
.
Пример сценария может выглядеть так
#!/bin/sh
# Get the latest code
cd /path/to/bare/repo
# Set git variables
GIT_WORK_TREE=/var/www/website
GIT_DIR=/var/www/website/.git
# Go to website and pull
cd /var/www/website
git pull /path/to/bare/repo
git submodule update --init --recursive
# Run additional build stuff here
Ответ 2
Я понял другое решение, которое выглядит довольно чистым для меня. Просто дайте git всю информацию, необходимую для выполнения субмодуля:
$ cd /path/to/your/git_work_tree
$ git --git-dir=/path/to/your/bare_repo.git --work-tree=. submodule init
$ git --git-dir=/path/to/your/bare_repo.git --work-tree=. submodule update
Ответ 3
Я наткнулся на эту тему два дня назад, пока я боролся с той же проблемой. После того, как вы наконец пришли к хорошему, аккуратным решениям, я написал статью об этом здесь:
Git нажмите с подмодулями: руководство по эксплуатации
Я понял, что если я перейду к push
к голой репо, только чтобы использовать post-receive
to pull
в не-гоповое репо, я мог бы просто просто сохранить его и push
напрямую в не-голый репозиторий. Это явный случай, когда "лучшая практика" только при нажатии на голый репо только увеличивает сложность.
В случае ссылки rot, я вставлю свое решение здесь, пропуская бит, где я сталкиваюсь со всеми теми же проблемами, которые, я уверен, вы сделали.
Во-первых, создайте универсальный крюк post-receive
, который мне не нужно будет изменять на основе каждого репозитория:
[[email protected]]$ cat > /usr/local/share/git-core/templates/hooks/post-receive.sample
#!/bin/sh
#
# An example hook script to update the working tree, including its
# submodules, after receiving a push.
#
# This hook requires core.worktree to be explicitly set, and
# receive.denyCurrentBranch to be set to false.
#
# To enable this hook, rename this file to "post-receive".
# Read standard input or hook will fail
while read oldrev newrev refname
do
:
done
# Unset GIT_DIR or the universe will implode
unset GIT_DIR
# Change directory to the working tree; exit on failure
cd `git config --get core.worktree` || exit
# Force checkout
git checkout --force
# Force update submodules
git submodule update --init --recursive --force
[[email protected]]$ chmod +x /usr/local/share/git-core/templates/hooks/post-receive.sample
Теперь давайте продолжим и нарушим все правила.
Собирались инициализировать не-голый репозиторий Git, прямо в нашем каталоге веб-сайта; убедитесь, что он может получать от git push
; явно установить свое рабочее дерево в родительский каталог; и разрешить наш крюк, который мы только что создали.
[[email protected]]$ cd /var/www/vhosts/aaronadams.ca/sites/staging.aaronadams.ca
[[email protected]]$ git init && git config --bool receive.denyCurrentBranch false && git config --path core.worktree ../ && mv .git/hooks/post-receive.sample .git/hooks/post-receive
Initialized empty Git repository in /var/www/vhosts/aaronadams.ca/sites/staging.aaronadams.ca/.git/
Наконец, на нашей локальной машине измените наш пульт, чтобы отразить местоположение нашего нового репозитория, и нажмите.
[[email protected]]$ git remote set-url staging [email protected]:sites/staging.aaronadams.ca
[[email protected]]$ git push staging master
remote: Submodule 'codeigniter' (git://github.com/EllisLab/CodeIgniter.git) registered for path 'codeigniter'
remote: Cloning into 'codeigniter'...
remote: Submodule path 'codeigniter': checked out 'fd24adf31255822d6aa9a5d2dce9010ad2ee4cf0'
To [email protected]:sites/staging.aaronadams.ca
* [new branch] master -> master
Святое дерьмо, это сработало!
Этот метод не только совместим с подмодулями, но также требуется только одна команда для настройки нового удаленного репозитория (который, в порядке, состоит из четырех команд). Он также сохраняет хранилище и рабочее дерево в одном и том же месте; и без абсолютных путей, необходимых в нашей конфигурации или файлах с крючками, теперь это полностью переносимое.
Я надеюсь, что этот ответ поможет кому-то, так как все остальные сообщения Stack Exchange помогли мне в течение последних двух дней!