PHP Composer, Git submodules и Assembla

// Декабрь 6th, 2012 // Веб-разработка, Системы контроля версий (VCS)

Некоторое время назад я решил навести порядок в списках своих библиотек, подключить всё через Composer, настроить человеческую автозагрузки по PSR-0, и вообще как следует прибраться в коде. Однако не всё шло гладко. В этом посте я расскажу об особенностях работы с Composer внутри Git репозитария с библиотеками, подключаемыми как git submodules.

Проблема с Git Submodules и Composer

В общем, проблема такая. Имеется некоторое количество библиотек в папки vendor. Они туда ставятся Composer’ом и обновляются при помощи

php composer.phar update

После этого делаем commit & push. Но вот незадача, когда на другой машине я делаю git pull с этой же ветки, то получаю пустую папку, вместо библиотеки. Может быть это проблема git, может assembla, по идее сабмодули должны по другому отображаться (см. рисунок).

Очень долго копался в проблеме, экспериментально выяснил, что git submodules коммититься совершенно не хотят. Т.е. после каждого обновления кода надо обновлять и папку vendor с библиотеками, что в моём случае неприемлимо. А вдруг оборвётся связь с репозитарием одной из библиотек, а вдруг они там что-то нашаманят, ветку может уберут или ещё что? В общем зависить от всех сторонних репозитариев при деплое на продакшен своего кода не хочется. Поэтому я начал поиск решения.

Решение

Решение нашлось, не скажу, что быстро, но нашлось. Итак. Во-первых нам надо создать скриптик stash_git.sh. Образец был взят с хабра, спасибо хабраюзеру karser. Код немного модифицировал, чтобы скрипт удалял вообще все .git* файлы и папки. Вот исходник:

#!/bin/bash
backup_git="stash_git.tar"
stash() {
    echo "Stashing....."
    tar -czf $backup_git $git_list
    rm -rf $git_list
}
apply() {
    echo "Applying....."
    tar -xf $backup_git && rm $backup_git
}
if [ "$1" = "apply" ]
then
    if [ -f $backup_git ]
    then
        apply
    else
        echo "Nothing to apply"
    fi
else
    git_list=`find vendor/ -name ".git*"`
    if [ "$git_list" ]
    then
        stash
    else
        echo "Nothing to stash."
        exit 0
    fi
fi
exit 1;

Этот скриптик можно запускать либо для удаления в архив(tar) всех git файлов и папок:

./stash_git.sh

либо для возвращения их обратно

./stash_git.sh apply

Порядок действий для починки репозитария

У меня в репозитарии после пуша сабмодулей творилась вообще анархия. Зайдя в assembla я видел вместо папок некие одноименные файлы, которые не открывались, при git pull они принимались кака пустые папки. Нет кода — куча багов. В результате родился такой вот солюшен:

  1. Переключаемся в дев ветку, говорим коллегам, чтобы пока не пулились.
  2. Удаляем все библиотеки внутри папки vendor.
  3. git add . & git add -u .
  4.  git commit -m «Удалили vendor»
  5. git push origin branch_name
  6. Убеждаемся через веб-морду или консоль в origin, что папки реально удалены.
  7. php composer.phar self-update
  8. php composer.phar update
  9. ./stash_git.sh (проверьте, чтобы был установлен исполняемый бит на нём)
  10. rm -rf ./git_stash.tar (он нам нафиг не нужен, т.к. composer при следующем update всё равно всё пересоздаст там)
  11. git add .
  12. git add -u .
  13. git commit -m «Обновили vendor»
  14. git push origin branch_name

Всё, смотрим детали коммита и видим там, что теперь папки библиотек записались полноценно.

Итого

В качестве плюса такого решения вижу отсутствие зависимости от сторонних репозитариев во время деплоя и разработки, т.е. они реально нужны только при обновлении библиотек. В качестве минусов — немного более затруднённый процесс обновления, однако при любых глюках с Composer самый частый совет на форумах — «удалите библиотеки в vendor и попробуйте снова» :-) Если у вас есть более изящное решение — велкам в комменты, буду рад услышать.

Ссылки

Использование Сomposer в Git репозитории

Share

Спасибо!


Если вам помогла статья, или вы хотите поддержать мои исследования и блог - вот лучший способ сделать это:


7 Responses to “PHP Composer, Git submodules и Assembla”

  1. hackPNZ:

    У меня была ситуация, когда либа, подключенная с гитхаба имела внутри себя submodule. Понятное дело, что при composer install папочка субмодуля совершенно пустая. Для себя решил это так в composer.json:

    «scripts»: {
    «post-install-cmd»: [
    «cd && git submodule update —init —recursive»
    ]
    }

  2. hackPNZ:

    Дополню немного. cd делаешь в директорию субмодуля, ключ «—recursive» нужен, если есть вложенные субмодули.

  3. janson:

    О, спасибо!
    Как раз столкнулся с такой проблемой. Не понимал — в чём собственно дело и как бороться.
    Ваш пост помог. :)

  4. Alex Grand:

    Добавлять папку vendor под версионирование нельзя! Есть файл composer.lock и composer.json, это все что можно от композера добавлять.
    Composer.lock файл содержит сылки на все зависимости в «развернутом» виде, то-есть с привязкой к коммиту, и т.д.
    Поэтому достаточно просто выполнить composer install, и будет установлены все зависимости с теми же версиями, что и в папке vendor.

    Если же вы делаете правки в vendor, то это мягко говоря не очень, переопределяйте поведение, иначе у Вас может поломаться все.

    • google.com Андрей Токарчук:

      Правки в vendors — ад и Израиль. Конечно не делаем. По поводу выноса vendors из репозитария, composer.lock и composer install — это идеологически верно и первоначальный вариант был именно такой… до той поры, пока не начались сетевые проблемы и деплой продакшена не начал отваливаться по таймауту из-за этого.

Комментировать