Я предлагаю некоторый workflow обновления зависимостей в Git репозитории с помощью Сomposer. Проект основан на Symfony и все зависимости хранятся в папке vendors. Я уверен, что версия зависимостей всегда должна соответствовать версии кода на момент его написания, и обновлять зависимости нужно централизованно, т.к с проектом работают много людей.
Однако, Сomposer подразумевает использование Git submodules, то есть все скачанные зависимости представляют собой Git репозитории, об обновлении которых каждый пользователь должен заботиться самостоятельно.
Преобразовать Git submodules в обычный код помогла команда
find vendors/ -name ".git" -type -d | xarg rm -rf
Однако, при следующем обновлении Сomposer выдает ошибку: Source directory has uncommitted changes.
Сomposer знает, что обновляемый модуль это Git репозиторий, и для проверки изменений использует git status.
protected function enforceCleanDirectory($path)
{
$command = sprintf('cd %s && git status --porcelain --untracked-files=no', escapeshellarg($path));
if (0 !== $this->process->execute($command, $output)) {
throw new RuntimeException('Failed to execute ' . $command . "nn" . $this->process->getErrorOutput());
}
if (trim($output)) {
throw new RuntimeException('Source directory ' . $path . ' has uncommitted changes');
}
}
Поскольку я удалил все .git папки, мы получаем ответ от репозитория основного проекта, изменения в котором произвел как минимум сам Composer в файле Composer/installed.json.
Я написал простой скрипт, который выполняет 2 команды:
- создать резервную копию .git папок в архив stash_git.tar и удалить их
$ ./stash_git.sh
- распаковать и удалить архив
$ ./stash_git.sh apply
Текст скрипта:
#!/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/ -type d -name ".git"`
if [ "$git_list" ]
then
stash
else
echo "Nothing to stash."
exit 0
fi
fi
exit 1;
Не забудьте пометить скрипт исполняемым
$ chmod +x ./stash_git.sh
Итак, наш workflow:
$ git pull
$ php composer.phar self-update
$ php composer.phar install
$ php composer.phar update
$ ./stash_git.sh
Stashing.....
$ git add .
$ git commit -am "vendors update"
$ git push
При следующем обновлении
$ ./stash_git.sh apply
Applying.....
Не забудьте stash_git.tar внести в .gitignore
Автор: karser