SourceTree

  1. Inleiding
  2. Installatie
  3. Local git repository
  4. Klonen
  5. Locaties
    1. local naar remote
    2. remote naar local
  6. Merge Conflicts
  7. Harde reset met geforceerde push
  8. Branche met Pull Request
  9. Soft en mixed resets
  10. Slot

up | down

Inleiding

In de eerdere posts over Git en GitHub hebben we voor de Git-commando’s gebruik gemaakt van de Git Bash command line interface.

De Git for Windows Git Bash (Bourne Again SHell) command line interface (CLI) emuleert Linux en in die CLI kunnen Git commando’s ingegeven worden. Veel die-hard IT’ers van de oude stempel zweren bij een CLI met een knipperende prompt waarbij in een tekstmodus alle (Git) commando’s zonder poespas ingegeven kunnen worden:

Veel andere gebruikers hebben desalniettemin toch de behoefte aan een GUI (Graphical User Interface). Redenen voor een GUI zijn de gebruikersvriendelijkheid en het niet hoeven te weten wat de te gebruiken (Git) commando’s zijn.

Je krijgt bij de installatie van Git weliswaar Git GUI, maar Git GUI is vrij rudimentair en de makers van GIT GUI willen dat waarschijnlijk ook zo houden.

Veel partijen zijn daarop ingesprongen en er zijn op dat vlak inmiddels heel wat Git GUI tools voor handen (GitHub Desktop, gitKraken, SourceTree, Tower etc.). Zie daarvoor dit schrijven van devart over de meest populaire GIT GUI tools.

Alle GIT GUI tools bieden een (uitgebreide) GUI waarmee je het één en ander voor elkaar krijgt m.b.t. je lokale Git repository en je remote repository. We zullen in deze post Atlassian’s SourceTree bekijken.

up | down

Installatie

We gaan naar de site van SourceTree en we zien dat meerdere besturingssystemen ondersteund worden. SourceTree is er op het moment van dit schrijven in twee smaken (Windows en Mac OS X) en we gebruiken in deze post de Windows-versie.

Met betrekking tot de installatie:

  • Git repositories kunnen door o.a. Atlassian’s Bitbucket gehost worden. Bij de installatie wordt gevraagd om een Bitbucket account en of je er anders één wilt aanmaken als je nog geen Bitbucket account hebt. De vragen m.b.t. Bitbucket laten we voor wat het is omdat we in deze post GitHub gebruiken.
  • Verder verschijnen ook vragen m.b.t. Mercurial, maar ook met deze vragen doen we niks omdat we geen gebruik maken van het versiebeheersysteem van Mercurial.
  • SourceTree gebruikt uiteindelijk de reeds aanwezige user accounts van je remote repositories en zal daarvoor waarschijnlijk kijken in de Windows Credential Manager (referentiebeheer).

Het kan voorkomen dat SourceTree na een Windows installatie niet getoond wordt in het Windows Start Menu waarbij een snelkoppeling naar SourceTree ook niet op je bureaublad is gezet.

Niet echt handig, want hoe moet je SourceTree na de installatie dan opstarten?

Maak, als SourceTree niks toont, als volgt een snelkoppeling naar SourceTree.exe voor het doen opstarten van SourceTree waarbij de .exe in deze folder staat:

C:\Users\%username%\AppData\Local\SourceTree

up | down

Local git repository

Vanuit SourceTree kun je een local Git repository3 openen dat al aanwezig is op je PC. Ga hiervoor in SourceTree naar tabblad Add en geef de folder op in welke de local Git repository3 zich bevindt:

SourceTree maakt een bladwijzer (bookmark) aan na het openen van de local Git repository3:

Bovenstaand is het equivalent van de “Git Bash Here” in Windows Verkenner waarmee een Git Bash CLI wordt geopend voor de desbetreffende folder:

up | down

Klonen

Een kloon trekken uit de repository kan ook. Zoek daarvoor eerst de url op van je remote repository. In GitHub vind je de url terug onder de Code-button:

Ga in SourceTree naar tabblad Clone en geef de url op van de remote repository en waar het één en ander mag komen op de lokale PC (in dit voorbeeld hebben we folder C:\Blog\GitMRA2 opgegeven).

SourceTree haalt alles over en het maakt een bookmark aan voor de desbetreffende repository. De bookmarks kunnen verwijderd worden, maar let op wat wat je precies verwijderd wilt hebben. Gaat het alleen om de bookmark of wil je ook de hele lokale repository weg hebben?

Bovenstaand is het equivalent van de:

git clone https://github.com/mrasoftGithub.git .

up | down

Locaties

De Git software versiebeheersysteem kent vier locaties en het is de bedoeling dat alle relevante bestanden alle locaties doorlopen om te eindigen in een remote repository in de cloud of om weer terug te komen als een “untracked” bestand in de lokale folder op de PC:

  1. Allereerst is er een folder lokaal op de PC met daarin je broncode
    (de desbetreffende folder is je working directory1)
  2. Vervolgens hebben we een staging area2
    (Git hanteerde voorheen de term ‘index’)
  3. Daarna volgt de local Git repository3
    (die zich nog steeds lokaal op de PC bevindt) en
  4. Ten slotte hebben we de remote (Github) repository4 in de cloud
    (we gebruiken in dit voorbeeld de hosting service van GitHub)

In de Git Bash CLI komen de locaties en bijbehorende fases tot uiting in:
a) een working directory1 (fase unstaged)
b) een staging area2 (fase staged)
c) een local Git repository3 (fase committed) en in
d) een remote (Github) repository4 (fase pushed)

up | down

local naar remote

De bestanden in een versiebeheersysteem doorlopen een aantal fasen en SourceTree ziet in welke fase de bestanden in de working directory1 zich bevinden (de File Status).

Het één en ander komt tot uiting in de GUI en we kunnen met de desbetreffende buttons bestanden unstagen1, stagen2, committen3 en met een commit zelfs direct pushen4 naar de remote repository.

In onderstaande printscreen is bestand index.html “staged”.

Uiteindelijk doen we na een commit de push naar de remote repository:

en SourceTree gaat aan de slag:

waarna de remote repository is bijgewerkt:

De Git Bash CLI equivalenten:

# Toevoegen van bestanden aan 
# de staging area zodat ze
# gevolgd worden door Git
git add index.html

# opnemen in de local git repository
# als je parameter -a gebruikt dan
# hoef je niet eerst git add te doen
git commit -m "<toelichting>"

# de inhoud overzetten
# van de lokale Git repository
# naar branche master in de remote repository
git push origin master 

up | down

remote naar local

Het laten doen üpdaten van de local Git repository3 vanuit de remote (GitHub) repository4 gebeurt met een pull commando. In SourceTree hebben we de Pull menukeuze:

en SourceTree gaat aan de slag om je local Git repository3 geüpdated te krijgen:

De Git Bash CLI equivalent:

# update de local git repository
# met de remote github remote repository
git pull origin master

up | down

Merge Conflicts

In deze post hadden we het gehad over merge conflicts. Merge conflicts kunnen ook vanuit de SourceTree GUI opgelost worden en we zullen het één en ander toelichten aan de hand van gebruiker wappie. Dezelfde gebruiker die ook in de post voorkwam over merge conflicts.

Gebruiker wappie is afgereisd naar de Verenigde Staten voor het volgen van een aantal conspiracy seminars en de uitgangssituatie voor wappie is de index.html met daarin de complottheorie over het niet plaatsvinden van de maandlanding.

In die tussentijd is de onzin van wappie weggehaald uit de remote repository en in de remote repository is nu een index.html actief zonder de tekst over de maandlanding, maar met een aanvulling over de Bootes void. Dit komt dan ook tot uiting in de onderstaande popup zodra wappie weer thuis is en een pull gaat doen uit de remote repository.

En we zien na de push de conflicterende onderdelen van index.html:

We doen wat in de popup wordt voorgesteld. Bij file status selecteren we het bestand dat conflicten geeft (index.html) waarna we kiezen voor één van de opties onder ‘Resolve Conflicts‘. Wappie gaat overstag en kiest met de nodige tegenzin voor ‘Resolve Using ‘Theirs’.

Bevestigd moet dan worden dat het gaat om een specifieke commit:

En de opvatting over de maanlanding is verwijderd en vervangen door de opmerkingen over de Bootes void. Wappie legt zich er niet bij neer en voegt zijn nieuwste inzicht toe namelijk dat de aarde bestuurd wordt door Vogons uit het Alpha Draconis-sterrenstelsel en dat wij dat niet door hebben omdat ze zich vermomd hebben als hoogwaardigheidsbekleders.

En wederom staat na de push in de remote repository een index.html met de allernieuwste onzin…

De Git Bash CLI equivalent:

# update de local git repository
# met de remote github remote repository
git pull origin master

up | down

Harde reset met geforceerde push

In deze post hadden we een situatie beschreven waarin iemand een laatste bijdrage had gedaan. Van die bijdrage vonden we dat die verwijderd mag worden uit de repository en niet meer zichtbaar hoefde te blijven omdat de bijdrage niks toevoegde aan de repository. Dit alles kan ook vanuit de SourceTree GUI.

We zullen het één en ander toelichten aan de hand van wappie’s bijdrage over de Vogons uit het Alpha Draconis-sterrenstelsel. De stelling is op zijn zachtst uitgedrukt tamelijk ongeloofwaardig en de bijdrage willen we verwijderd hebben uit de repository.

We halen met een pull alles over naar de lokale PC en bij History selecteren we de commit tot en met welke we de repository gereset willen hebben. Met de rechter muisknop krijgen we onderstaande popup en we kiezen voor ‘Reset current branch to this commit‘:

We kiezen bij de Reset voor using mode: “Hard – discard all working copy changes“. Bestanden uit de local Git repository3 en de staging area2 worden met deze using mode verwijderd, maar het werkt met terugwerkende kracht ook de bestanden bij in de working directory1 waardoor alle wijzingen na die voorlaatste commit verloren gaan.

Bevestig dat je inderdaad een harde reset wilt doen:

Na de harde reset lukt een “gewone” push naar de remote repository niet meer. Bij een “gewone” push constateert GitHub dat een commit aanwezig is die Git niet meer heeft. Dit omdat we de commit uit Git hebben verwijderd met de harde reset. De commit komt echter nog wel voor in de historie van GitHub en GitHub zal de push-actie verwerpen omdat alles niet meer synchroon zal zijn als de push-actie wordt uitgevoerd.

Met een “geforceerde” push staan we toe dat alles in GitHub overschreven mag worden met datgene uit Git. Ook als dingen verloren mochten gaan in GitHub. In dit voorbeeld komt het erop neer dat we de commit van gebruiker wappie in de remote (Github) repository4 gaan verliezen. Dat is in dit geval geen probleem. Het is precies datgene wat we willen.

We moeten wel bij SourceTree opgeven dat een geforceerde push is toegestaan want die is by default niet toegestaan. De instelling vinden we bij Options > Git > Enable Force Push:

En we kunnen bij de push optie “Force Push” aanvinken. Bevestig dat je inderdaad een geforceerde push wilt doen:

Het resultaat; zoals de remote repository eruit ziet voor de geforceerde push:

En na de geforceerde push; de situatie in de remote repository is weer tot en met de voorlaatste commit:

De Git Bash CLI equivalenten:

# update de git local repository
# met de remote repository
git pull origin master

# hard reset
# om een commit te herstellen tot en met
# een bepaalde Commit ID
# de bestanden in de working directory en
# de staging area horen expliciet 
# bij die commit, alle wijzigingen 
# nadien zijn weg!
git reset --hard <Commit ID>

# een geforceerde push om
# de remote repository bij te werken
# commit history en 
# versies in de remote repository
# na de eerder opgegeven Commit ID 
# gaan verloren! 
git push origin <hoofdbranche> --force

up | down

Branche met Pull Request

Branching is ook mogelijk vanuit de SourceTree GUI en in deze post zijn we ingegaan op branches (branching). De bedoeling van branching is dat een hoofdbranche (master of main) alleen maar broncode bevat dat zo ‘zuiver’ en stabiel mogelijk is.

Voor installaties naar bijvoorbeeld productiemachines wordt dan de broncode uit de hoofdbranche gebruikt door bijvoorbeeld een Azure DevOps pipeline.

Een “best practice” is dat je eerst je aanpassingen doet in een sub branche waarbij je het één en ander test en evalueert. Je neemt na goedbevinding de aanpassingen op in de hoofdbranche via een pull request.

We zullen het één ander illustreren aan de hand van bestand index.html waaraan we een opmerking toevoegen over de Eridanus super void.

In SourceTree beginnen we met de creatie van sub branche eridanus die gebaseerd is op de hoofdbranche master:

We voegen in sub branche eridanus in bestand index.html de opmerking toe over de Eridanus super void.

We committen sub branche eridanus en we pushen die meteen naar de remote repository:

In de remote repository kunnen we voor sub branche eridanus een pull request creëren:

Sub branche eridanus gaan we samenvoegen met hoofdbranche master:

We bevestigen de samenvoeging:

En we verwijderen in zowel Github als in Git sub branche eridanus. De verwijdering van de branche in Git doen we met SourceTree:

En als laatste stap doen we een pull zodat de lokale repository weer synchroon loopt met de remote repository:

De Git Bash CLI equivalenten:

# Welke branches hebben we en 
# in welke branche zitten we nu? 
# (aangegeven met een *)
git branch
 
# aanmaken branche 
# met de naam 'eridanus'
git branch eridanus
 
# ga naar een andere branche
# bijvoorbeeld naar branche 'eridanus'
git switch eridanus
 
# update de github remote repository
# zet branche 'eridanus' over naar
# de remote repository
git push origin eridanus
 
# verwijder branche hubble
# uit de local git repository
git branch -D eridanus
 
# update de git local repository
# met de remote repository
git pull origin master

up | down

Soft en mixed Resets

In deze post hadden we het gehad over die gevallen waarin alles is doorgezet naar de local Git repository3, maar nog niet naar de remote (Github) repository4.

Je hebt dan voor het doen “terugdraaien” van dingen nog de mogelijkheid tot een reset vanuit de Sourcetree GUI waarbij een aantal varianten mogelijk zijn.

We hebben, om het één en ander te demonstreren aan index.html een schrijven toegevoegd over de KBC Void (groen gemarkeerd door SourceTree):

Alles is gecommit, maar we willen alles gereset hebben tot en met de voorlaatste commit. Verder staat de laatste versie nog niet in de remote repository zodat onze acties beperkt kunnen blijven tot de local repository.

We selecteren bij de History de voorlaatste commit waarbij we met de rechter muisknop onderstaande popup krijgen te zien. We kiezen voor ‘Reset current branch to this commit‘:

Bij een reset hebben we de keuze uit een aantal Using modes:

Using mode: “Hard – discard all working copy changes“ hadden we hier reeds besproken. Bestanden uit de local Git repository3 en de staging area2 worden met deze using mode verwijderd,

maar het werkt met terugwerkende kracht ook de bestanden bij in de working directory1 waardoor de nieuwste wijzigingen verloren gaan. In dit voorbeeld komt het erop neer dat met een harde commit het schrijven m.b.t de KBC void verloren gaat.

Bij de twee andere using modes krijgen we een situatie waarin het schrijven over de KBC Void nog wel aanwezig is:

Using mode: “Soft- keep all local changes” zet alle, bij die commit horende bestanden in de staging area2 (staged files). Deze using mode is handig als je bijvoorbeeld een bestand bent vergeten die je ook wil opnemen in de commit. De desbetreffende bestanden kun je dan alsnog toevoegen aan de staged files alvorens je opnieuw gaat committen:

Using mode: “Mixed – keep working copy but reset index” is de default en het maakt alle, bij die commit horende bestanden weer “unstaged” (unstaged files):

De Git Bash CLI equivalenten:

# mixed reset (default)
# om een commit te herstellen tot en met
# een bepaalde Commit ID
# het gewijzigde bestand is 
# nadien "untracked"
# en alleen nog maar aanwezig in
# de working directory
git reset --mixed <Commit ID>
 
# soft reset
# om een commit te herstellen tot en met
# een bepaalde Commit ID
# nadien zijn de gewijzigde bestanden 
# nog aanwezig in de
# staging area en de working directory
git reset --soft <Commit ID>

up | down

Slot

Met de Git Bash CLI kunnen Git commando’s ingegeven worden waarmee je het één en ander voor elkaar krijgt m.b.t. je lokale Git repository en je remote repository. Veel gebruikers hebben toch liever een GUI (Graphical User Interface) omdat die wat gebruikersvriendelijker is en je niet hoeft te weten wat de te gebruiken (Git) commando’s zijn.

In deze post hebben we Atlassian’s SourceTree nader bekeken. SourceTree biedt een (uitgebreide) GUI waarmee je ook het één en ander voor elkaar krijgt m.b.t. je lokale Git repository en je remote repository. Andere populaire GIT GUI tools zijn GitHub Desktop, gitKraken, Tower en nog veel meer en zie daarvoor dit schrijven van devart over de tien meest populaire GIT GUI tools.

We hebben in de eerdere posts over Git en GitHub gebruik gemaakt van de Git Bash CLI, maar we kunnen met SourceTree hetzelfde bewerkstelligen. We hebben laten zien hoe met SourceTree:

  • een local Git repository3 geopend kan worden
  • een remote (GitHub) repository4 gekloond kan worden
  • de locaties van de Git software versie systeem gevisualiseerd worden
  • merge conflicts opgelost kunnen worden
  • een harde reset met een geforceerde push naar de remote (GitHub) repository4 gedaan kan worden
  • aan branching gedaan kan worden
  • dingen gereset kunnen worden als alles nog niet is gepushed naar de remote (GitHub) repository4

We hebben bij bovenstaande acties de Git Bash CLI equivalenten meegegeven waarmee je hetzelfde voor elkaar krijgt.

Of je nu gebruik maakt van een GIT GUI tool zoals SourceTree of van de wat ascetischere Git Bash CLI, je zult in beide gevallen toch de concepten moeten begrijpen van Git’s versiebeheersysteem wil je enigszins door hebben van wat je aan het doen bent. Ik hoop dat mijn posts over Git en GitHub hier iets aan kunnen bijdragen.

Mogelijk dat je steeds meer gebruik gaat maken van de Git Bash CLI naarmate je meer en meer bedreven raakt in het één en ander, maar een GIT GUI laat naar mijn idee toch beter zien wat er precies gebeurt en ook niet onbelangrijk, het laat beter zien wat er precies misgaat en wat gedaan kan worden om het te verhelpen.

Hopelijk ben je met deze posting weer wat wijzer geworden en ik hoop je weer terug te zien in één van mijn volgende blog posts. Klik op de Home-button om te zien wat ik nog meer geschreven heb…

up

Laat een reactie achter

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *