Inhoud

Website ontwikkeling met Git

Dit document demonstreert het gebruik van Git voor het beheer van bestands-gebaseerde websites.

1. Introductie

Git is een versie-beheersysteem ontwikkeld door Linus Torvalds t.b.v. software ontwikkeling. Het Git versie-beheersysteem is echter veel breder inzetbaar als versie-beheersysteem voor een collectie bestanden.

Diverse moderne website management systemen (CMS) zijn bestands-gebaseerd.1) Het Git versie-beheersysteem is zeer geschikt voor het beheer van dergelijke website management systemen.

In deze demonstratie passen we Git zonder CMS direct op HTML bestanden toe. Om de HTML bestanden eenvoudig aan te maken gebruiken we de Markdown opmaaktaal. 2)

2. Inleiding demonstratie Git HTML/Markdown

2.1 "Internet" en "Ontwikkel" server

In deze demonstratie gebruiken we een “Internet” server en een “Ontwikkel” server. Op de Internet server staat de publiek toegankelijke website. De Ontwikkel server is een Linux PC, waarop we de website ontwikkelen.

2.2 Git en bestandstypen

Hoewel met Git in principe alle typen bestanden beheerd kunnen worden, is Git toch vooral geschikt voor het beheren van tekst bestanden. 3) Voor het beheren van (grote) binaire bestanden zijn er twee alternatieven:

Git-annex is een toevoeging aan Git, waarbij de bestanden als symbolische links worden beheerd. De data van de bestanden wordt buiten de Git repository bewaard. Daardoor zijn er geen limieten aan de bestandsgrootte. 4) Git-annex brengt een extra set aan commando's met zich mee. Dat maakt het beheer ingewikkelder.

Rsync is geen versie-beheersysteem. Rsync kan echter wel de backup/replicatie functie van een versie-beheersysteem vervullen. Rsync is een programma om collecties bestanden te synchroniseren. Het lijkt op “scp” (secure remote copy), maar werkt veel efficienter. In tegenstelling tot “scp” -dat altijd alle bestanden copieert- copieert “rsync” alleen gewijzigde bestanden naar de bestemming.

Rsync voert geen administratie (zoals Git). Wanneer het gewenst is om periodiek oude bestanden definitief te verwijderen, kan dat echter ook een voordeel zijn! Een versie-beheersysteem is dan contraproductief. Bestanden uit de historie van een Git repository verwijderen is niet eenvoudig. 5) In git-annex gaat dit makkelijker, omdat de data van de bestanden zich buiten de Git repository bevindt. 6)

In deze demonstratie gebruiken we “rsync” om de foto's van de website met de “Internet server” te synchroniseren.

3. demonstratie Git/rsync HTML/Markdown

3.1 Demo website "Muziekinstrumenten" [Ontwikkel server]

Op de “Ontwikkel” server hebben we de volgende demo wesite staan:

$ ls -lR WWW fotos
fotos:
totaal 796
-rw-r--r-- 1 demo demo  43249 dec 13 21:14 266px-JayCEastonSaxFamily_cropped.jpg
-rw-r--r-- 1 demo demo  12521 dec 13 20:24 Buffet_piano.jpg
-rw-r--r-- 1 demo demo  71501 dec 13 21:12 Classical_Guitar_two_views2.png
-rw-r--r-- 1 demo demo  17853 dec 14 14:10 Home-orange.png
-rw-r--r-- 1 demo demo 211311 dec 14 14:48 muziekinstrumenten-header.png
-rw-r--r-- 1 demo demo 430598 dec 14 14:43 muziekinstrumenten.png

WWW:
totaal 16
lrwxrwxrwx 1 demo demo    9 dec 13 20:17 fotos -> ../fotos/
drwxr-xr-x 2 demo demo 4096 dec 16 14:56 img
-rw-r--r-- 1 demo demo  781 dec 16 14:57 index.html
-rw-r--r-- 1 demo demo  183 dec 16 14:57 index.md
drwxr-xr-x 2 demo demo 4096 dec 14 14:40 muz-inst

WWW/img:
totaal 4
-rw-r--r-- 1 demo demo 1698 dec 14 14:12 Home.png

WWW/muz-inst:
totaal 24
-rw-r--r-- 1 demo demo  895 dec 14 14:37 gitaar.html
-rw-r--r-- 1 demo demo  302 dec 14 14:33 gitaar.md
-rw-r--r-- 1 demo demo 1101 dec 14 14:37 piano.html
-rw-r--r-- 1 demo demo  529 dec 14 14:32 piano.md
-rw-r--r-- 1 demo demo 1251 dec 14 14:37 saxofoon.html
-rw-r--r-- 1 demo demo  676 dec 14 14:33 saxofoon.md

Toelichting:

De directory “WWW” zal in de demo de “root” directory van de Git repository 7) worden. Omdat de foto-collectie buiten de Git-repository moet blijven, staat de directory “fotos” niet in de directory “WWW”, maar een niveau hoger in de directory hierarchie. De toegang naar de directory “fotos” verloopt via de symlink “WWW/fotos”.

3.2 Richt lokale Git repository in [Ontwikkel server]

3.2.1 Maak een nieuwe Git repository in "WWW"

$ cd WWW

$ git init
Initialized empty Git repository in /home/demo/WWW/.git/

3.2.2 Maak identiteit van de gebruiker bekend aan Git:

$ git config --global user.email "demo@ontwikkel.dom"

$ git config --global user.name "Demo user"

De globale Git instellingen worden opgeslagen in “$HOME/.gitconfig”:

$ more $HOME/.gitconfig
[user]
    email = demo@ontwikkel.dom
    name = Demo user

3.2.3 Administreer alle bestanden in "WWW" in Git

Het commando “git add” voegt bestanden of gehele directories met bestanden toe aan de Git “index”.

$ cd WWW

$ git add .

$ git status
On branch master

Initial commit

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

    new file:   fotos
    new file:   img/Home.png
    new file:   index.html
    new file:   index.md
    new file:   muz-inst/gitaar.html
    new file:   muz-inst/gitaar.md
    new file:   muz-inst/piano.html
    new file:   muz-inst/piano.md
    new file:   muz-inst/saxofoon.html
    new file:   muz-inst/saxofoon.md
$

3.2.4 Git commit

Het commando “git commit” maakt een foto van de wijzigingen vastgelegd in de Git index.

$ git commit

De “vi” editor opent om de “commit” mededeling vast te leggen:

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
#
 Initial commit

 Changes to be committed:
        new file:   fotos
        new file:   img/Home.png
        new file:   index.html
        new file:   index.md
        new file:   muz-inst/gitaar.html
        new file:   muz-inst/gitaar.md
        new file:   muz-inst/piano.html
        new file:   muz-inst/piano.md
        new file:   muz-inst/saxofoon.html
        new file:   muz-inst/saxofoon.md
#

".git/COMMIT_EDITMSG" [Modified] line 18 of 19

Bij verlaten van de “vi” editor wordt de “commit” geschreven in de Git repository:

$ git commit
[master (root-commit) 6d9095b]  Initial commit
 10 files changed, 134 insertions(+)
 create mode 120000 fotos
 create mode 100644 img/Home.png
 create mode 100644 index.html
 create mode 100644 index.md
 create mode 100644 muz-inst/gitaar.html
 create mode 100644 muz-inst/gitaar.md
 create mode 100644 muz-inst/piano.html
 create mode 100644 muz-inst/piano.md
 create mode 100644 muz-inst/saxofoon.html
 create mode 100644 muz-inst/saxofoon.md

3.2.5 Toon de Git status

$ git status
On branch master
nothing to commit, working tree clean

3.2.6 Toon het Git logboek:

$ git log
commit 6d9095b8f1ad860ad8f8239560cf1c6a52e64dcc
Author: Demo user <demo@ontwikkel.dom>
Date:   Mon Dec 17 20:38:56 2018 +0100

     Initial commit

     Changes to be committed:
            new file:   fotos
            new file:   img/Home.png
            new file:   index.html
            new file:   index.md
            new file:   muz-inst/gitaar.html
            new file:   muz-inst/gitaar.md
            new file:   muz-inst/piano.html
            new file:   muz-inst/piano.md
            new file:   muz-inst/saxofoon.html
            new file:   muz-inst/saxofoon.md

3.3 Richt remote Git repository in [Internet server]

3.3.1 Login op de Internet server

$ ssh demo@internet_server.dom

3.3.2 Maak een nieuwe Git repository in "WWW" [Internet server]

$ cd WWW

$ git init
Initialized empty Git repository in /home/demo/WWW/.git/

3.3.3 Maak identiteit van de gebruiker bekend aan Git: [Internet server]

$ git config --global user.email "demo@ontwikkel.dom"

$ git config --global user.name "Demo user"

3.3.4 Sta op afstand updaten van de actuele branch toe [Internet server]

Vanuit de Ontwikkel server willen we de nieuwe data telkens naar de Internet server sturen (git push). Standaard laat Git dit echter niet toe!

Geef deze Git repository vrij voor het op afstand updaten van de actuele branch:

$ cd WWW

$ git config receive.denyCurrentBranch ignore

3.3.5 Actualiseer de werk directory na push [Internet server]

Een “git push” operatie update weliswaar de remote Git repository, maar de bestanden in de werk directory blijven ongewijzigd.

Dit probleem is echter op te lossen met een Git “hook” script. Git “hooks” scripts zijn scripts in de directory “.git/hooks”, die bij bepaalde gebeurtenissen worden uitgevoerd. 8)

Met een “post-receive” script in “.git/hooks” kunnen we automatisch na iedere “git push” de werk directory actualiseren:

$ cd .git/hooks

Maak hier een nieuw script aan met de naam “post-receive”:

#!/bin/sh
# post-receive script

cd ..
env -i git reset --hard HEAD

Maak het “post-receive” script uitvoerbaar:

$ chmod +x post-receive

De remote Git repository is nu klaar om data via een “git push” te ontvangen.

3.4 De eerste "git push" naar de "Internet server" [Ontwikkel server]

3.4.1 Administreer de remote Git repository [Ontwikkel server]

$ cd WWW

$ git remote add web ssh://demo@internet_server.dom/~/WWW

Dit commando legt de toegang tot de remote Git repository vast onder de naam “web”. Met “git remote -v” kunnen we de “remotes” opvragen:

$ git remote -v
web ssh://demo@internet_server.dom/~/WWW (fetch)
web ssh://demo@internet_server.dom/~/WWW (push)

3.4.2 De eerste "git push" [Ontwikkel server]

Bij de eerste “git push” vraagt Git om de remote branch aan de lokale branch te koppelen via de optie “–set-upstream”:

$ git push --set-upstream web master

demo@internet_server.dom's password:
Counting objects: 14, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (12/12), done.
Writing objects: 100% (14/14), 4.54 KiB | 0 bytes/s, done.
Total 14 (delta 4), reused 0 (delta 0)
remote: HEAD is now at 6d9095b  Initial commit
To ssh://internet_server.dom/~/WWW
 * [new branch]      master -> master
Branch master set up to track remote branch master from web.

De Internet server heeft nu alle actuele website bestanden m.u.v. de foto's.

3.5 Synchroniseren foto's [Ontwikkel server]

3.5.1 Synchroniseren met "rsync"

Vanuit de $HOME directory synchroniseren we de directory “fotos/” met de Internet server:

$ cd

$ rsync -a --delete fotos/ demo@internet_server.dom:fotos

Zie verder: $ man rsync

3.5.2 rsync script

Met het rync commando in een script gaat de synchronisatie makkelijker en is minder gevoeliger voor fouten in de commandoregel.

Maak een script “rsync-fotos”:

rsync-fotos:

#! /bin/sh

rsync -a --delete fotos/ demo@internet_server.dom:fotos

Maak het script uitvoerbaar:

$ chmod +x rsync-fotos

Voor het synchroniseren van de foto's hoeven we alleen maar het script uit te voeren:

$ ./rsync-fotos

3.6 Wijzigen aan de website [Ontwikkel server]

3.6.1 Wijzigen bestanden

We brengen een wijziging aan in de “piano” pagina:

$ cd WWW

$ cd muz-inst

$ vi piano.md

Als voorbeeld voegen we een link toe naar de Wikipedia pagina over de piano:

piano.md:

[Wikipedia: piano](https://nl.wikipedia.org/wiki/Piano_(instrument))

We genereren een nieuwe HTML pagina:

$ pandoc -s -o piano.html piano.md

3.6.2 Wijzigen administreren in Git

Nog in de “WWW/muz-inst” directory:

$ git add piano.*

De wijzigingen zijn nu toegevoegd in de Git Index.

Met “git status” kunnen we zien wat in Git is gewijzigd:

$ git status
On branch master
Your branch is up-to-date with 'web/master'.
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    modified:   piano.html
    modified:   piano.md

3.6.3 Git commit

Ga naar de Git “root” directory“:

$ cd $HOME/WWW

Voer de Git commit door:

$ git commit

De “vi” editor opent om de “commit” mededeling vast te leggen:

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# Your branch is up-to-date with 'web/master'.
#
# Changes to be committed:

Link naar Wikipedia toegevoegd
==============================
modified:   muz-inst/piano.html
modified:   muz-inst/piano.md

3.6.4 Publiceer wijzigigen op de Internet server

Push de “master” branch naar de remote Git repository “web”:

$ git push web master
demo@internet_server.dom's password:

Counting objects: 5, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (5/5), 603 bytes | 0 bytes/s, done.
Total 5 (delta 4), reused 0 (delta 0)
remote: HEAD is now at decba9e Link naar Wikipedia toegevoegd
To ssh://internet_server.dom/~/WWW
   6d9095b..decba9e  master -> master

De wijzigingen zijn nu doorgevoerd op de Internet server.

3.6.5 Synchroniseren foto's

Indien er wijzigingen zijn in de foto-collectie, synchroniseer de foto-collectie dan met de Internet server:

$ ./rsync-fotos

Appendix A - Documentatie

Appendix B - Markdown-HTML script

#!/bin/bash
#
# pandoc-html.scr
# W20181214

# Usage: pandoc-html.scr afile.md [bfile.md ..]

# For all arguments do
for i in "$@"
do
  if ! test -f "${i%.*}.md"
  then
      echo "$0: Cannot open ${i%.*}.md" >&2
      exit 1
  fi
  
  # Convert Markdown into html
  pandoc -s -o "${i%.*}.html" "${i%.*}.md"

done

Copyright © 2018 Tux4u.be - Author: Marjan Waldorp; git-webdev.md 2018-12-30

1)
bijv. Grav, GetSimpelCMS, Dokuwiki
3)
Z.g. “platte” tekst bestanden, bijv. HTML, Markdown, C-broncode
4)
Git heeft geen harde limieten. Zeer grote bestanden (>50M) en heel veel bestanden (>25k) zouden echter tot vertraging leiden.
5)
git filter-branch
6)
git annex drop
7)
repository (Engels): repositorium (Latijn) = opbergplaats
9)
rsync: Met een / achter de bron-directory copieert rsync de bestanden in de directory, maar niet de bron-directory zelf.