Эта статья описывает функции базового уровня, которые вы можете использовать сразу после установки модуля GIT.PHP
В настоящий момент модуль находится на модерации и доступен для установке по прямой ссылке сайт.ру/bitrix/admin/update_system_partner.php?addmodule=coffeediz.git После прохождения модерации модуль будет доступен в Маркетплейсе 1С-Битрикс по ссылке marketplace.1c-bitrix.ru/solutions/coffeediz.git/ |
В рамках статьи не описывается специфика работы с системами контроля версий (и GIT в частности), предполагая что читатель знает что это такое и чем может быть полезно.
Модуль реализует поддержку библиотеки GIT.PHP v.0.2 в 1С-Битрикс. По состоянию на 25.04.2015 это только сама библиотека и набор её классов, без какого-либо специфичного функционала и компонентов.
Подключение модуля.
Для использования модуля на странице или в коде необходимо выполнить:
if (!CModule::IncludeModule("coffeediz.git"))
return;
Начало работы (инициация/подключение репозитория).
Для того чтобы начать работу с GIT необходимо создать объект репозитория. Для этого необходимо выполнить одно из действий:
-
Инициировать новый репозиторий (если он не существует)
-
Открыть имеющийся репозиторий (если он существует)
Важно! Для указания адреса репозитория необходимо указать путь к репозиторию от корня веб сервера (а не относительно корня сайта), например: /u00/app/bitrix/Apache/htdocs/site/ru/ Получить путь к корню сайта (в котором выполняется php скрипт) от корня сервера можно с помощью $_SERVER['DOCUMENT_ROOT']. При этом при указании путей в явном виде можно работать с репозиториями в других сайтов на многосайтовой конфигурации 1С-Битрикс. |
Инициация репозитория
$repo = Git::create('/home/a/a92661qd/coursera/public_html/');
Аналог команды git init
Открытие репозитория
$repo = Git::open('/home/a/a92661qd/coursera/public_html/');
Статус репозитория (git status
)
$repo->status();
Результат этой команды можно как выводить на печать (echo $repo->status();
), так и передавать в переменную для обработки ($status = $repo->status();
)
Фиксация изменений
Активные пользовали GIT знают, что изменения проходят несколько стадий:
Незафиксированные изменения (файлы изменились, но GIT об этом не знает) -> проиндексированные изменения (GIT записывает во временное хранилище состояние файлов) -> фиксация изменений (коммит, т.е. создание точки в постоянном хранилище) -> обмен с удалённым репозиторием (Push/Pull).
Инденксация (git add
)
string GitRepo->add ([ mixed $files = "*" ])
$repo->add($files);
$files может принимать на вход как строку, так и массив. Примеры передаваемых значений:
-
$files = '1.php'; //файл
-
$files = 'auth/'; // папка
-
$files = array("2.php", "quests/"); // массив значений (1 файл и 1 папка)
-
$files = array(
0 => ".htaccess",
1 => ".section.php",
2 => "personal/", ); // массив значений с ключами (2 файла и 1 папка, ключи игнорируются, берутся только значения) -
$files = '.'; //регулярное выражение для индексации всех новых или изменившихся (и не проиндексированных) файлов и папок
Фиксация/коммит изменений (git commit -av -m
)
string GitRepo->commit ([ string $message = "" ])
$repo->commit($message);
$message принимает на вход строку. Знак переноса «\n» не работает.
Пример: $message = "Initial commit";
Отправка изменений в удалённый репозиторий (git push
)
string GitRepo->push ( string $remote, string $branch )
$repo->push('origin', 'master');
Поддерживается сложный синтаксис для обоих параметров:
-
$repo->push('origin', 'master:example'); // отправка изменений из ветки master в ветку example
-
$repo->push('https://login:password@github.com/lexnekr/git', 'example'); // отправка изменений в произвольный репозиторий github.com/lexnekr/git по HTTPS, используя логин и пароль (login:password)
Получение изменений из удалённого репозитория (git pull
)
string GitRepo->pull ( string remote, string $branch )
$repo->pull('origin', 'master');
Поддерживается сложный синтаксис для обоих параметров (аналогично Push):
-
$repo->pull('origin', 'master:example'); // получение изменений из ветки master в ветку example
-
$repo->pull('https://login:password@github.com/lexnekr/git', 'example'); // получение изменений из произвольного репозитория github.com/lexnekr/git по HTTPS, используя логин и пароль (login:password)
В случае необходимости merge (объединения изменений) и возможности автоматического разрешения коллизий, это будет произведено и не будет выдано сообщений об ошибках! В этом случае будет создан новый коммит.
Важно! Имейте в виду, что при получении изменений командой
Если вы указываете ветку ОТКУДА берёте изменений. А получены они будут в текущую ветку. Чтобы этого избежать используйте сложный синтаксис для явного указания обеих веток. |
Произвольная команда GIT
К сожалению, модуль имеет классы не для всех команд, предусмотренных в GIT. Однако он снабжён универсальным классом:
string GitRepo->run ( string $command )
Пример (получение статуса, аналог git status, $repo->status();):
$repo->run('status');
Несколько необходимых для начала работы конструкций, для которых не было реализовано отдельных классов:
Имя владельца репозитория (git config user.name
)
$repo->run('config user.name "ALEKSEY ZADOINIY"');
Email владельца репозитория (git config user.email
)
$repo->run('config user.email a@coffeedoz.ru');
Важно!
С высокой вероятностью на вашем хостинге/сервере будет недоступна команда « |
Привязка удалённого репозитория (git remote add
)
$repo->run('remote add origin git@github.com:lexnekr/git.git');
Важно! Если вы не можете настроить обмен с удалённым репозиторием по SSH (т.к. не можете обменяться ключами, например), то вы можете привязать репозиторий по https протоколу. В этом случае вам так же придётся передавать логин и пароль. Я не рекомендую хранить их в явном виде в конфиге, однако вы можете это сделать следующим образом:
|
История изменений (git log
)
Полная история: $repo->log();
Возможные параметры:
-
$format (задаёт параметры форматирования, используется для формирования своей маски ответа, например, если ответ предстоит парсить с помощью php)
-
$limit
-
$offset
-
$searchString
Примеры скриптов:
1 – создание нового репозитория в имеющемся сайте и его отправка в github
if (!CModule::IncludeModule("coffeediz.git"))
return; //подключаем модуль
$repo = Git::create('/home/a/a92661qd/coursera/public_html/'); // создаём репозиторий
$repo->run('config user.name "ALEKSEY ZADOINIY"'); //добавляем имя владельца репозитория
$repo->run('config user.email a@coffeedoz.ru'); // добавляем email владельца репозитория
$repo->run('remote add origin https://login:password@github.com/lexnekr/gittest'); //добавляем адрес удалённого репозитория (с логином и паролем для доступа по HTTPS, что НЕ РЕКОМЕНДУЕТСЯ)
$files = '.';
$repo->add($files); //индексируем все новые и изменённые файлы и папки
$message = "1st commit";
$repo->commit($message); //создаём коммит с текстовым комментарием
$repo->push('origin', 'master'); //отправляем в удалённый репозиторий в master ветку
2 – Скрипт создания и отправки бекапа
подходит для постановки на Cron, но требует дополнительных првоерок и ограничений прав, чтобы не был использован для DDOS.
if (!CModule::IncludeModule("coffeediz.git"))
return; //подключаем модуль
$repo = Git::open('/home/a/a92661qd/coursera/public_html/'); //открываем имеющийся репозиторий
$files = '.';
$repo->add($files); //индексируем все новые и изменённые файлы и папки
$message = date('Y-m-d');
$repo->commit($message); //создаём коммит с комментарием в виде текущей даты
$repo->push('origin', 'master:backup'); //отправляем в удалённый репозиторий (состояние ветки master в ветку backup)
3 – Парсинг лога в массив
Черновой скрипт, который планируется использовать для построения дерева истории
if (!CModule::IncludeModule("coffeediz.git"))
return; //подключаем модуль
$repo = Git::open('/home/a/a92661qd/coursera/public_html/'); //открываем репозиторий
$log = $repo->log($format=',"%h":{"HASH":"%h","PARENTS":"%p","AUTHOR_NAME":"%cn","SUBJECT":"%s","NOTES":"%N","DATE":"%ai","DECOR":"%d"}'); // читаем лог ВСЕХ веток в близкий JSON формат
$log = '{'.substr($log, 1).'}'; // Приводим к 100% JSON формату (добавляем фигурные кавчки и убираем 1й лишний символ "запятую")
$log = json_decode($log, true); // JSON --> Array
foreach ($reversed_log as $hash => &$commit) { // идём по циклу по коммитам
$reversed_log[$hash]['PARENTS'] = explode(" ", $reversed_log[$hash]['PARENTS']); // превращаем строку со списком SHA родителей в массив (разделитель между SHA - пробел)
if(empty($reversed_log[$hash]['PARENTS'][0])){ //если 1й элемент массива родителей пуст
$reversed_log[$hash]['PARENTS'] = array(); // заменяем пустой элемент массива с родителями на пустой массив (для корректной операции Array --> JSON в будущем). Причина - на предыдущем этапе пустая строка (если нет родителей) превратилась в массив с 1 пустым элементом.
}
}