Git --distributed-even-if-your-workflow-isnt
Chapters ▾ 2nd Edition

4.1 Git op de server - De protocollen

Je zou nu de alledaagse taken waarvoor je Git zult gebruiken moeten kunnen uitvoeren. Echter, om enige vorm van samenwerking te hebben in Git is een remote Git repository nodig. Technisch gezien kun je wijzigingen pushen en pullen van individuele repositories, maar dat wordt afgeraden omdat je vrij gemakkelijk het werk waar anderen mee bezig zijn in de war kunt schoppen als je niet oppast. Daarnaast wil je dat je medewerkers de repository kunnen bereiken, zelfs als jouw computer van het netwerk is; het hebben van een betrouwbare gezamenlijke repository is vaak handig. De voorkeursmethode om met iemand samen te werken is daarom een tussenliggende repository in te richten waar alle partijen toegang tot hebben en om daar naartoe te pushen en vandaan te pullen.

De protocollen

Git kan vier veel voorkomende netwerk protocollen gebruiken om data te transporteren: Lokaal, HTTP, Beveiligde Shell (Secure Shell, SSH) en Git. Hier bespreken we wat deze zijn, en in welke omstandigheden je ze zou willen gebruiken (of juist niet).

Lokaal protocol

Het simpelste is het Lokale protocol, waarbij de remote repository in een andere directory op de schijf staat. Deze opzet wordt vaak gebruikt als iedereen in het team toegang heeft op een gedeeld bestandssyteem zoals een NFS mount, of in het weinig voorkomende geval dat iedereen op dezelfde computer werkt. Het laatste zou niet ideaal zijn, want dan zouden alle repositories op dezelfde computer staan, wat de kans op een catastrofaal verlies van gegevens veel groter maakt.

Als je een gedeeld bestandssyteem hebt, dan kun je clonen, pushen en pullen van een op een lokaal bestand aanwezige repository. Om een dergelijk repository te clonen, of om er een als een remote aan een bestaand project toe te voegen, moet je het pad naar het repository als URL gebruiken. Bijvoorbeeld, om een lokaal repository te clonen, kun je zoiets als het volgende uitvoeren:

$ git clone /opt/git/project.git

Of je kunt dit doen:

$ git clone file:///opt/git/project.git

Git werkt iets anders als je expliciet file:// aan het begin van de URL zet. Als je alleen het pad specificeert, probeert Git hardlinks te gebruiken naar de bestanden die het nodig heeft. Als ze niet op hetzelfde bestandssysteem staan zal Git de objecten die het nodig heeft kopiëren, gebruikmakend van het standaard kopieer mechanisme van het besturingssysteem. Als je file:// specificeert, dan start Git de processen die het normaal gesproken gebruikt om data te transporteren over een netwerk, wat over het algemeen een minder efficiënte methode is om gegevens over te dragen. De belangrijkste reden om file:// wel te specificeren is als je een schone kopie van de repository wilt met de systeemvreemde referenties of objecten eruit gelaten; over het algemeen na een import uit een ander versiebeheer systeem of iets dergelijks (zie Chapter 10 voor onderhoudstaken). We zullen het normale pad hier gebruiken, omdat het bijna altijd sneller is om het zo te doen.

Om een lokale repository aan een bestaand Git project toe te voegen, kun je iets als het volgende uitvoeren:

$ git remote add local_proj /opt/git/project.git

Daarna kan je op gelijke wijze pushen naar, en pullen van die remote als je over een netwerk zou doen.

De voordelen

De voordelen van bestands-gebaseerde repositories zijn dat ze eenvoudig zijn en ze maken gebruik van bestaande bestandspermissies en netwerk toegang. Als je al een gedeeld bestandssysteem hebt waar het hele team al toegang toe heeft, dan is een repository opzetten heel gemakkelijk. Je stopt de kale repository ergens waar iedereen gedeelde toegang tot heeft, en stelt de lees- en schrijfrechten in zoals je dat bij iedere andere gedeelde directory zou doen. In de volgende paragraaf “Git op een server krijgen” bespreken we hoe je een kopie van een kale repository kunt exporteren voor dit doeleinde.

Dit is ook een prettige optie om snel werk uit een repository van iemand anders te pakken. Als jij en een collega aan hetzelfde project werken, en hij wil dat je iets bekijkt, dan is het uitvoeren van een commando zoals git pull /home/john/project vaak makkelijker dan wanneer hij naar een remote server moet pushen, en jij er van moet pullen.

De nadelen

Eén van de nadelen van deze methode is dat gedeelde toegang over het algemeen moeilijker op te zetten en te bereiken is vanaf meerdere lokaties dan simpele netwerk toegang. Als je wilt pushen van je laptop als je thuis bent, dan moet je de remote schijf aankoppelen, wat moeilijk en langzaam kan zijn in vergelijking met met netwerk gebaseerde toegang.

Het is ook belangrijk om te vermelden dat het niet altijd de snelste optie is als je een gedeeld koppelpunt (mount) of iets dergelijks gebruikt. Een lokale repository is alleen snel als je snelle toegang tot de data hebt. Een repository op NFS is vaak langzamer dan een repository via SSH op dezelfde server omdat dit laatste Git in staat stelt op lokale schijven te werken op elk van de betrokken systemen.

Het HTTP protocol

Git kan op twtee verschillende manieren via HTTP communiceren. Voor Git versie 1.6.6 was er maar een manier waarop dit kan en dat was erg basaal en over het algemeen kon je alleen lezen. In versie 1.6.6 en later, is een slimmere protocol geïntroduceerd waardoor Git in staat is gesteld om de gegevens uitwisseling iets slimmer aan te pakken, op een manier die lijkt op de SSH aanpak. In de laatste paar jaar is dit nieuwe HTTP protocol erg populair geworden omdat het eenvoudiger is voor de gebruiker en slimmer in de manier waarop het communiceert. Aan deze nieuwere versie wordt vaak gerefereerd als het “slimme” HTTP protocol en het oude als het “domme” HTTP. We zullen eerst het nieuwere “slimme” HTTP protocol behandelen.

Slimme HTTP

Het “slimme” HTTP protocol werkt ongeveer gelijk aan het SSH of Git protocol, maar verloopt via standaard HTTP/S poorten en kan verscheidene HTTP authenticatie mechanismen gebruiken, wat betekent dat het vaak eenvoudiger is voor de gebruiker dan iets als SSH, omdat je zaken als basale gebruikersnaam/wachtwoord authenticatie kunt gebruiken in plaats van SSH sleutels in te richten.

Het is waarschijnlijk de meest populaire manier om Git te gebruiken geworden, omdat het zowel ingericht kan worden om anoniem gebruik te faciliteren zoals bij het git:// protocol, maar ook met authenticatie en encryptie zoals bij het SSH protocol. In plaats van verschillende URLs op te zetten voor deze dingen, kan je nu een enkele URL voor beide gebruiken. Als je probeert te pushen en de repository heeft authenticatie nodig (wat gewoonlijk het geval is), kan de server om gebruikernaam en wachtwoord vragen. Hetzelfde geldt voor lees-toegang.

Sterker nog, voor services als GitHub is de URL die je gebruikt om de repository online te bekijken (bijvoorbeeld, "https://githum.com/schacon/simplegit[]") is dezelfde URL die je kunt gebruiken om te clonen en, als je toegang hebt, om te pushen.

Domme HTTP

Als de server niet werkt met een Git HTTP slimme service, zal de Git client terug proberen te vallen op het simpelere “domme” HTTP protocol. Het domme protocol verwacht dat de kale Git repository moet worden verspreid als gewone bestanden van de web server. Het mooie van het domme HTTP protocol is de eenvoud van het inrichten. Alles wat je hoeft te doen is een kale Git repository onder je HTTP document-root neer te zetten en een speciale post-update hook in te richten, en je bent klaar (Zie “Git Hooks”). Vanaf dat moment, kan iedereen die de webserver waarop je de repository hebt gezet kan bereiken ook je repository clonen. Om lees-toegang tot je repository toe te staan over HTTP, kan je iets als dit doen:

$ cd /var/www/htdocs/
$ git clone --bare /path/to/git_project gitproject.git
$ cd gitproject.git
$ mv hooks/post-update.sample hooks/post-update
$ chmod a+x hooks/post-update

Dat is alles. De post-update hook dat standaard bij Git geleverd wordt activeert het juiste commando (git update-server-info) om HTTP fetching en cloning correct te laten werken. Dit commando wordt gedraaid als je naar deze repository pusht (misschien met SSH); en andere mensen kunnen clonen met zoiets als

$ git clone https://example.com/gitproject.git

In dit specifieke geval gebruiken we het /var/www/htdocs pad dat gebruikelijk is voor Apache setups, maar je kunt elke statische web server gebruiken; zet gewoon de kale repository in het pad. De Git data wordt verspreid als gewone statische bestanden (zie Chapter 10 voor details hoe precies het wordt verspreid).

Over het algemeen zou je kunnen kiezen om een lees/schrijf slimme HTTP server te draaien of om de bestanden beschikbaar te stellen als alleen lezen op de domme manier. Het is zeldzaam om een combinatie van beide services te draaien.

De voordelen

Ze zullen ons voornamelijk richten op de voordelen van de slimme versie van het HTTP protocol.

De eenvoud van het hebben van een enkele URL voor alle typen van toegang en de server alleen te laten vragen om authenticatie wanneer het noodzakelijk is maakt het heel erg eenvoudig voor de eindgebruiker. Het kunnen authenticeren met gebruikersnaam en wachtwoord is ook een groot voordeel ten opzichte van SSH, omdat de gebruikers geen SSH sleutels lokaal hoeven te genereren en hun publieke sleutels niet naar de server hoeven te uploaden voordat ze in staat zijn met deze te communiceren. Voor minder kundige gebruikers, of gebruikers op systemen waar SSH minder gebruikelijk is, is dit een groot voordeel in bruikbaarheid. Het is ook een erg snel en efficiënt protocol, vergelijkbaar met SSH.

Je kunt ook je repositories met alleen leesrechten verspreiden middels HTTPS, wat inhoudt dat je de inhoud versleuteld verstuurt; of je kunt zelfs zover gaan dat je de clients speciaal getekende SSL certificaten laat gebruiken.

Een ander aardigheid is dat het HTTP/S protocol zo gebruikelijk is dat de firewalls van bedrijven vaak zo zijn opgezet dat ze verkeer via deze poorten toestaan.

De nadelen

Git via HTTP/S kan op sommige servers iets moeilijker op te zetten zijn in vergelijking tot SSH. Anders dan dat, is er weinig dat andere protocollen in het voordeel laat zijn als we het hebben over het ``slimme"` HTTP protocol om Git te bedienen.

Als je HTTP gebruikt voor geauthenticeerde pushen, is het invullen van credentials (gebruikersnaam en wachtwoord) soms ingewikkelder dan het gebruik sleutels via SSH. Er zijn echter een aantal credential caching tools die je kunt gebruiken, waaronder Keychain toegang op OSX en Credential Manager op Windows om dit redelijk gladjes te laten verlopen. Lees “Het opslaan van inloggegevens” om te zien hoe veilige HTTP wachtwoord caching op jouw systeem op te zetten.

Het SSH Protocol

Een gebruikelijk transport protocol voor Git in het geval van zelf-hosting is SSH. Dit is omdat SSH toegang tot servers in de meeste gevallen al ingericht is, en als dat niet het geval is, is het eenvoudig te doen. SSH is ook een authenticerend netwerk protocol, en omdat het alom aanwezig is, is het over het algemeen eenvoudig om in te richten en te gebruiken.

Om een Git repository via SSH te clonen, kan je een ssh:// URL specificeren op deze manier:

$ git clone ssh://user@server/project.git

Of je kunt het kortere scp-achtige syntax voor het SSH protocol gebruiken:

$ git clone user@server:project.git

Je kunt de gebruiker ook niet opgeven, en Git neemt dan de gebruiker waarmee je op dat moment ingelogd bent.

De voordelen

Er zijn vele voordelen om SSH te gebruiken. Ten eerste is SSH relatief eenvoudig op te zetten: SSH daemons komen veel voor, veel systeembeheerders hebben er ervaring mee, en veel operating systemen zijn er mee uitgerust of hebben applicaties om ze te beheren. Daarnaast is toegang via SSH veilig: alle data transporten zijn versleuteld en geauthenticeerd. En als laatste is SSH efficiënt, net zoals bij het HTTP/S, Git en lokale protocol worden de gegevens zo compact mogelijk gemaakt voordat het getransporteerd wordt.

De nadelen

Het negatieve aspect van SSH is dat je er geen anonieme toegang naar je repository over kunt geven. Mensen moeten via SSH toegang hebben om er gebruik van te kunnen maken zelfs als het alleen lezen is, dit maakt dat SSH toegang niet echt bevordelijk is voor open source projecten. Als je het alleen binnen je bedrijfsnetwerk gebruikt, is SSH wellicht het enige protocol waar je mee in aanraking komt. Als je anonieme alleen-lezen toegang wilt toestaan tot je projecten, dan moet je SSH voor jezelf instellen om over te pushen, maar iets anders voor anderen om te fetchen.

Het Git Protocol

Vervolgens is er het Git protocol. Dit is een speciale daemon dat met Git mee wordt geleverd, het luistert naar een toegewezen poort (9418) en biedt een service die vergelijkbaar is met het SSH protocol, maar zonder enige vorm van authenticatie. Om een repository via het Git protocol te laten verspreiden, moet je eerst het git-daemon-export-ok bestand maken; de daemon zal een repository zonder dat bestand niet verspreiden, maar anders dan dat is er geen beveiliging. De Git repository is beschikbaar voor iedereen om te clonen of het is het niet. Dit betekent dat er over het algemeen niet wordt gepushed met dit protocol. Je kunt push-toegang beschikbaar maken, maar gegeven het ontbreken van authenticatie kan iedereen op het internet die de vingers kan leggen op het URL van je project naar jouw project pushen als je deze toestaat. Laten we zeggen dat dit zelden voorkomt.

De voordelen

Het Git protocol is vaak het snelste netwerk overdrachtsprotocol dat bestaat. Als je veel verkeer voor een publiek project moet bedienen of een erg groot project dat geen authenticatie behoeft voor lees-toegang, is het waarschijnlijk dat je een Git daemon wilt opzetten om je project te bedienen. Het gebruikt dezelfde data-transfer mechanisme als het SSH protocol, maar zonder de encryptie en authenticatie-overhead.

De nadelen

Het nadeel van het Git protocol is het ontbreken van authenticatie. Het is over het algemeen niet wenselijk om alleen middels het Git protocol toegang te geven tot je project. Over het algemeen zal je dit koppelen met SSH of HTTPS toegang voor de enkele ontwikkelaars die push (schrijf)rechten hebben en voor alle anderen het git:// protocol voor leestoegang. Daarbij is het waarschijnlijk het moeilijkste protocol om in te richten. Het moet zijn eigen daemon draaien, wat betekent dat de xinetd configuratie (of iets verglijkbaars) wat niet het eenvoudigste is om te doen. Ook moet de firewall toegang tot poort 9418 worden opengezet, wat geen standaard poort is die in de firewalls van bedrijven wordt toegestaan. In de firewall van grote bedrijven is deze obscure poort doorgaans geblokkeerd.