Git kan vier verschillende netwerk protocollen gebruiken om data uit te wisselen: 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).
Het simpelste is het Lokale protocol, waarbij de remote repository in een andere directory op de schijf van dezelfde host staat. Deze opzet wordt vaak gebruikt als iedereen in het team toegang heeft op een gedeeld bestandssyteem zoals een NFS mount, of in het minder waarschijnlijke 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 lokale bestands-gebaseerde 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 /srv/git/project.git
Of je kunt dit doen:
$ git clone file:///srv/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 of direct de bestanden te kopieren.
Als je file://
specificeert, dan start Git de processen die het normaal gesproken gebruikt om data uit te wisselen over een netwerk, wat over het algemeen een veel 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 ch10-git-internals.asc 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 /srv/git/project.git
Daarna kan je op gelijke wijze pushen naar, en pullen van die remote via je nieuwe reomte genaamd local_projc
zoals je over een netwerk zou doen.
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. We zullen de manier om een kopie van een kale repositiory te exporteren voor dit doel bespreken in ch04-git-on-the-server.asc.
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 fetchen.
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.
Git kan op twee verschillende manieren via HTTP communiceren. Voor Git versie 1.6.6 was er maar een manier waarop dit kon 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.
Het slimme HTTP protocol werkt ongeveer gelijk aan het SSH of Git protocol, maar verloopt via standaard HTTPS 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 normaalgesproken wel zou moeten), 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://github.com/schacon/simplegit) is dezelfde URL die je kunt gebruiken om te clonen en, als je toegang hebt, om te pushen.
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 ch08-customizing-git.asc).
Vanaf dat moment, kan iedereen die de webserver waarop je de repository hebt gezet kan bereiken ook je repository klonen.
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 ch10-git-internals.asc 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.
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 HTTPS protocol zo gebruikelijk is dat de firewalls van bedrijven vaak zo zijn opgezet dat ze verkeer via deze poorten toestaan.
Git via HTTPS 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 inhoud 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 macOS en Credential Manager op Windows om dit redelijk gladjes te laten verlopen. Lees ch07-git-tools.asc om te zien hoe veilige HTTP wachtwoord caching op jouw systeem op te zetten.
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
Als je in beide bovenstaande gevallen de optionele gebruikersnaam niet opgeeft, neemt Git de gebruikernaam over waarmee je op dat moment ingelogd bent.
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 HTTPS, Git en lokale protocol worden de gegevens zo compact mogelijk gemaakt voordat het getransporteerd wordt.
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.
Tot slot 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 een 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 klonen of het is het voor niemand.
Dit betekent dat er over het algemeen niet wordt gepusht 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 kan pushen.
Laten we zeggen dat dit zelden voorkomt.
Het Git protocol is vaak het snelste netwerk overdrachtsprotocol beschikbaar. 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.
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
of systemd
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.