?
Предыдущая заметка рассказывала про то, как избежать рутины при хостинге своего статичного блога. В ней всё хорошо и у вас не будет проблем, пока вы не захотите расширить функциональность своего «Jekyll» сайта. А это потребуется даже для обычных тегов и категорий; «Jekyll» — очень простой движок. После прикручивания дополнительной функциональности и деплоя сайта на гитхаб. Вы обнаружите, что сайт не работает.
Проблемы с github pages
Первые же ссылки в гугл поиске выдают ссылки объсяняющие, что github pages не работают с jekyll плагинами. Я подозреваю, что это сделано в целях безопасности.
Ссылки, которые помогут нам разобраться с решением проблемы.
- Using Jekyll with Pages
- Jekyll + Plugins + Github + You via charlie park
- Jekyll (with plugins!) hosted on GitHub Pages via Eddie Hedges
- GitHub Pages and Jekyll plugins via Alexandre Rademaker
Решение Чарли Пака
Первое решение предлагает разделить блог на две части, то есть поддерживать два разных репозитория — один для исходников блога, второй для результата генерации джекилла. Это жутко неудобно, да и раздражать будет. Другие рещения на порядок лучше и поэтому это решение я не буду приводить здесь.
Решение Эдди Хеджеса
Это решение не такое понятное сразу. Оно предлагает сделать объект коммита, который будет содержать историю только одной папки _site:
echo 'description of what we are doing' | git commit-tree dev^{tree}:_site
Эта комманда выведет id этого коммита, и дальше по этому id обновим выбранную для github pages ветку
git update-ref refs/heads/master COMMIT_ID
После этого надо убедиться, что ветка master имеет только нужные нам файлы:
$ git checkout master
Как видно, это то, что нам нужно. Так как мы не определили родителя коммита, то вынуждены сделать форсированный пуш на сервер:
$ git push -f origin master
Но можно, не делать форсированный пуш, если указать родителя коммита в самой первое команде:
$ echo 'description of what we are doing' | git commit-tree dev^{tree}:_site -p $(cat .git/refs/heads/master)
После этого всё можно оптимизировать до одной строки
$ git update-ref refs/heads/master $(echo 'Add commit message here!' | git commit-tree dev^{tree}:_site -p $(cat .git/refs/heads/master))
Решение Александра Рэйдмэйкера
На мой взгляд самое лаконичное решение.
$git checkout source // делайте всё, что вам угодно $ git status / git add / git commit $ jekyll $ checkout master $ cp -r _site/* . && rm -rf _site/ && touch .nojekyll $ git status > git add > git commit $ git push -all origin
Этот способ привлекателен тем, что у вас только один репозиторий, а для разных версий сайта вы используете, также как и раньше — разные ветки.
Самое важное в этой строке:
$ cp -r _site/* . && rm -rf _site/ && touch .nojekyll
Эта комманда составная и состоит из следующих более простых комманд, разделенных знаком &&
$ cp -r _site/* . // скопировали всё из подпапки в папку родительского уровня $ rm -rf _site/ // удаляет содержимое папки *_site* $ touch .nojekyll // создаёт файл, который сообщает гитхабу не запускать джекилл на своём сервере с помощью посткоммит хука.
Александр предлагает создать две ветки: source для исходников блога, и master для результатов работы Джекилла.
Поиск решения
В моём случае, я осознанно использую другую конфигурацию. master — ветка для исходников блога, так как эта ветка по умолчанию главная, а с ней чаще всего и приходится работать, поэтому она и остаётся главной. Для блога я использую зарезервиронную гитхабом ветку gh-pages. Для подобной конфигурации, я и приведу окончательное решение.
Убедитесь, что вы в master ветке
$ git branch gh-pages * master
Если маркер стоит напротив другой ветки, то перейдите в master
$ git checkout master
В решении Рэйдмэйкера, мне казалось странным запускать джекилл каждый раз, когда надо что-то закоммитить, можно же запустить его один раз в режиме --auto — и он будет постоянно сам перегенерировать контент, обнаруживая изменения. Во-вторых, после комманды
$ cp -r _site/* . && rm -rf _site/ && touch .nojekyll
В папке подготовленной для отправления на сервер, как готовый сайт, оставалось много лишнего материала относящегося к генератору сайта, что с одной стороны приемлемо, но сдругой стороны не красиво.
$ git status // посмотрите, что надо закоммитить $ git add // добавьте это в коммит $ git commit // закоммитьте $ git checkout gh-pages && git merge master // синхронизируем с главной веткой, $ shopt -s extglob // включаем расширенный шелл $ rm !(_site) -r // удаляем все папки, кроме _site $ mv _site/* ./ // перемещаем сгенерированный сайт в корень папки. $ rm _site // удаляем папку для генерации $ git add . $ git commit -m 'converted to flat site' $ git checkout master // перемещаемся в мастер ветку $ git push --all // пушим все изменения вместе со всеми ветками на сервер
Окончательное решение
Теперь, рассмотрим, что можно оптимизировать до одной строчки.
$ git status // посмотрите, что надо закоммитить $ git add // добавьте это в коммит $ git commit // закоммитьте
Эти строчки, всегда придётся делать руками — их не трогаем.
А всё остальное как мы видим можно сократить.
Первый шаг:
$ git checkout gh-pages && git merge master $ shopt -s extglob && rm !(_site) -r $ mv _site/* ./ && rm _site $ git commit -am 'converted to flat site' $ git checkout master && git push --all
git commit -am 'smth' === git add . && git commit -m 'smth'
Второй шаг:
$ git checkout gh-pages && git merge master $ shopt -s extglob && rm !(_site) -r && mv _site/* ./ && rm _site -r $ git commit -am 'converted to flat site' && git checkout master && git push --all
Окончательный шаг:
$ git checkout gh-pages && git merge master && shopt -s extglob && rm !(_site) -r && mv _site/* ./ && rm _site -r && git commit -am 'converted to flat site' && git checkout master && git push --all